diff --git a/src/components/CallView/CallView.vue b/src/components/CallView/CallView.vue index fc1e52809c7..2ae32ce37bc 100644 --- a/src/components/CallView/CallView.vue +++ b/src/components/CallView/CallView.vue @@ -47,7 +47,6 @@ :localMediaModel="localMediaModel" :localCallParticipantModel="localCallParticipantModel" :isStripe="false" - :showControls="false" :isSidebar="false" isBig fitVideo /> @@ -154,7 +153,6 @@ ref="localVideo" class="local-video" :class="{ 'local-video--sidebar': isSidebar }" - :showControls="false" :fitVideo="true" :isStripe="true" :token="token" diff --git a/src/components/CallView/Grid/StripeControls.spec.ts b/src/components/CallView/Grid/StripeControls.spec.ts new file mode 100644 index 00000000000..8a31f87d863 --- /dev/null +++ b/src/components/CallView/Grid/StripeControls.spec.ts @@ -0,0 +1,93 @@ +/** + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import { mount } from '@vue/test-utils' +import { describe, expect, test } from 'vitest' +import StripeControls from './StripeControls.vue' + +describe('StripeControls.vue', () => { + const SHOWN_SLOT = 'stripe-controls__slot--shown' + + /** + * @param props - the props to override + */ + function mountControls(props = {}) { + return mount(StripeControls, { + props: { + currentPage: 0, + numberOfPages: 1, + hasPreviousPage: false, + hasNextPage: false, + isOpen: true, + ...props, + }, + }) + } + + /** + * The slots shown while the controls are not hovered, in rendering order. + * + * @param wrapper - the mounted controls + */ + function shownSlots(wrapper: ReturnType) { + return wrapper.findAll('.stripe-controls__slot') + .map((slot) => slot.classes(SHOWN_SLOT)) + } + + describe('without pagination', () => { + test('holds the collapse control alone', () => { + const wrapper = mountControls() + + expect(wrapper.findAll('.stripe-controls__group')).toHaveLength(1) + expect(shownSlots(wrapper)).toEqual([]) + expect(wrapper.find('.stripe-controls__page').exists()).toBe(false) + }) + + test('holds the expand control alone when the stripe is collapsed', () => { + // A collapsed stripe shows no tile, so it is never paginated + const wrapper = mountControls({ isOpen: false, numberOfPages: 3, hasNextPage: true }) + + expect(wrapper.findAll('.stripe-controls__group')).toHaveLength(1) + expect(wrapper.find('.stripe-controls__page').exists()).toBe(false) + }) + }) + + describe('with pagination', () => { + const paginated = { numberOfPages: 3, hasPreviousPage: true, hasNextPage: true, currentPage: 1 } + + test('holds the paging controls next to the collapse control', () => { + expect(mountControls(paginated).findAll('.stripe-controls__group')).toHaveLength(2) + }) + + test('shows the arrows of the pages there are, and the page it is on once hovered', () => { + // Previous, page indicator and next + expect(shownSlots(mountControls(paginated))).toEqual([true, false, true]) + }) + + test('only shows the arrow of the page there is', () => { + expect(shownSlots(mountControls({ ...paginated, currentPage: 0, hasPreviousPage: false }))) + .toEqual([false, false, true]) + expect(shownSlots(mountControls({ ...paginated, currentPage: 2, hasNextPage: false }))) + .toEqual([true, false, false]) + }) + + test('indicates the current page', () => { + expect(mountControls(paginated).find('.stripe-controls__page').text()).toBe('2/3') + }) + + test('emits the page to move to and the collapse', async () => { + const wrapper = mountControls(paginated) + const buttons = wrapper.findAll('button') + + await buttons[0].trigger('click') + await buttons[1].trigger('click') + await buttons[2].trigger('click') + + expect(wrapper.emitted('previous')).toHaveLength(1) + expect(wrapper.emitted('next')).toHaveLength(1) + expect(wrapper.emitted('toggle')).toHaveLength(1) + }) + }) +}) diff --git a/src/components/CallView/Grid/StripeControls.vue b/src/components/CallView/Grid/StripeControls.vue new file mode 100644 index 00000000000..bedb241903b --- /dev/null +++ b/src/components/CallView/Grid/StripeControls.vue @@ -0,0 +1,190 @@ + + + + + + + diff --git a/src/components/CallView/Grid/VideosGrid.vue b/src/components/CallView/Grid/VideosGrid.vue index a24697e51c5..2046e4d993c 100644 --- a/src/components/CallView/Grid/VideosGrid.vue +++ b/src/components/CallView/Grid/VideosGrid.vue @@ -4,30 +4,32 @@ -->