mirror of https://github.com/jitsi/jitsi-meet
ref(Filmstrip): Optimize resizes. (#4992)
* ref(Filmstrip): Optimize resizes. * fix(thumbnails): resize. * fix(thumbnails): Issue with height 0, width 0. * doc(Filmstrip): Improve JSDoc.pull/5009/head jitsi-meet_4191
parent
ca9ca04d0f
commit
31d9fb12c8
@ -0,0 +1,69 @@ |
||||
// @flow
|
||||
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../../base/app'; |
||||
import { MiddlewareRegistry } from '../../base/redux'; |
||||
|
||||
import { clientResized } from './actions'; |
||||
|
||||
/** |
||||
* Dimensions change handler. |
||||
*/ |
||||
let handler; |
||||
|
||||
/** |
||||
* Middleware that handles window dimension changes. |
||||
* |
||||
* @param {Store} store - The redux store. |
||||
* @returns {Function} |
||||
*/ |
||||
MiddlewareRegistry.register(store => next => action => { |
||||
const result = next(action); |
||||
|
||||
switch (action.type) { |
||||
case APP_WILL_UNMOUNT: { |
||||
_appWillUnmount(); |
||||
break; |
||||
} |
||||
case APP_WILL_MOUNT: |
||||
_appWillMount(store); |
||||
break; |
||||
|
||||
} |
||||
|
||||
return result; |
||||
}); |
||||
|
||||
/** |
||||
* Notifies this feature that the action {@link APP_WILL_MOUNT} is being |
||||
* dispatched within a specific redux {@code store}. |
||||
* |
||||
* @param {Store} store - The redux store in which the specified {@code action} |
||||
* is being dispatched. |
||||
* @private |
||||
* @returns {void} |
||||
*/ |
||||
function _appWillMount(store) { |
||||
handler = () => { |
||||
const { |
||||
innerHeight, |
||||
innerWidth |
||||
} = window; |
||||
|
||||
store.dispatch(clientResized(innerWidth, innerHeight)); |
||||
}; |
||||
|
||||
window.addEventListener('resize', handler); |
||||
} |
||||
|
||||
/** |
||||
* Notifies this feature that the action {@link APP_WILL_UNMOUNT} is being |
||||
* dispatched within a specific redux {@code store}. |
||||
* |
||||
* @private |
||||
* @returns {void} |
||||
*/ |
||||
function _appWillUnmount() { |
||||
window.removeEventListener('resize', handler); |
||||
|
||||
handler = undefined; |
||||
} |
@ -0,0 +1,54 @@ |
||||
// @flow
|
||||
|
||||
import { SET_HORIZONTAL_VIEW_DIMENSIONS, SET_TILE_VIEW_DIMENSIONS } from './actionTypes'; |
||||
import { calculateThumbnailSizeForHorizontalView, calculateThumbnailSizeForTileView } from './functions'; |
||||
|
||||
/** |
||||
* The size of the side margins for each tile as set in CSS. |
||||
*/ |
||||
const TILE_VIEW_SIDE_MARGINS = 10 * 2; |
||||
|
||||
/** |
||||
* Sets the dimensions of the tile view grid. |
||||
* |
||||
* @param {Object} dimensions - Whether the filmstrip is visible. |
||||
* @param {Object} windowSize - The size of the window. |
||||
* @returns {{ |
||||
* type: SET_TILE_VIEW_DIMENSIONS, |
||||
* dimensions: Object |
||||
* }} |
||||
*/ |
||||
export function setTileViewDimensions(dimensions: Object, windowSize: Object) { |
||||
const thumbnailSize = calculateThumbnailSizeForTileView({ |
||||
...dimensions, |
||||
...windowSize |
||||
}); |
||||
const filmstripWidth = dimensions.columns * (TILE_VIEW_SIDE_MARGINS + thumbnailSize.width); |
||||
|
||||
return { |
||||
type: SET_TILE_VIEW_DIMENSIONS, |
||||
dimensions: { |
||||
gridDimensions: dimensions, |
||||
thumbnailSize, |
||||
filmstripWidth |
||||
} |
||||
}; |
||||
} |
||||
|
||||
/** |
||||
* Sets the dimensions of the thumbnails in horizontal view. |
||||
* |
||||
* @param {number} clientHeight - The height of the window. |
||||
* @returns {{ |
||||
* type: SET_HORIZONTAL_VIEW_DIMENSIONS, |
||||
* dimensions: Object |
||||
* }} |
||||
*/ |
||||
export function setHorizontalViewDimensions(clientHeight: number = 0) { |
||||
return { |
||||
type: SET_HORIZONTAL_VIEW_DIMENSIONS, |
||||
dimensions: calculateThumbnailSizeForHorizontalView(clientHeight) |
||||
}; |
||||
} |
||||
|
||||
export * from './actions.native'; |
@ -0,0 +1,74 @@ |
||||
// @flow
|
||||
|
||||
import { getNearestReceiverVideoQualityLevel, setMaxReceiverVideoQuality } from '../base/conference'; |
||||
import { MiddlewareRegistry } from '../base/redux'; |
||||
import { CLIENT_RESIZED } from '../base/responsive-ui'; |
||||
import Filmstrip from '../../../modules/UI/videolayout/Filmstrip'; |
||||
import { |
||||
getCurrentLayout, |
||||
LAYOUTS, |
||||
shouldDisplayTileView |
||||
} from '../video-layout'; |
||||
|
||||
import { setHorizontalViewDimensions, setTileViewDimensions } from './actions'; |
||||
import { SET_HORIZONTAL_VIEW_DIMENSIONS, SET_TILE_VIEW_DIMENSIONS } from './actionTypes'; |
||||
|
||||
/** |
||||
* The middleware of the feature Filmstrip. |
||||
*/ |
||||
MiddlewareRegistry.register(store => next => action => { |
||||
const result = next(action); |
||||
|
||||
switch (action.type) { |
||||
case CLIENT_RESIZED: { |
||||
const state = store.getState(); |
||||
const layout = getCurrentLayout(state); |
||||
|
||||
switch (layout) { |
||||
case LAYOUTS.TILE_VIEW: { |
||||
const { gridDimensions } = state['features/filmstrip'].tileViewDimensions; |
||||
const { clientHeight, clientWidth } = state['features/base/responsive-ui']; |
||||
|
||||
store.dispatch(setTileViewDimensions(gridDimensions, { |
||||
clientHeight, |
||||
clientWidth |
||||
})); |
||||
break; |
||||
} |
||||
case LAYOUTS.HORIZONTAL_FILMSTRIP_VIEW: |
||||
store.dispatch(setHorizontalViewDimensions(state['features/base/responsive-ui'].clientHeight)); |
||||
break; |
||||
} |
||||
break; |
||||
} |
||||
case SET_TILE_VIEW_DIMENSIONS: { |
||||
const state = store.getState(); |
||||
|
||||
if (shouldDisplayTileView(state)) { |
||||
const { width, height } = state['features/filmstrip'].tileViewDimensions.thumbnailSize; |
||||
const qualityLevel = getNearestReceiverVideoQualityLevel(height); |
||||
|
||||
store.dispatch(setMaxReceiverVideoQuality(qualityLevel)); |
||||
|
||||
// Once the thumbnails are reactified this should be moved there too.
|
||||
Filmstrip.resizeThumbnailsForTileView(width, height, true); |
||||
} |
||||
break; |
||||
} |
||||
case SET_HORIZONTAL_VIEW_DIMENSIONS: { |
||||
const state = store.getState(); |
||||
|
||||
if (getCurrentLayout(state) === LAYOUTS.HORIZONTAL_FILMSTRIP_VIEW) { |
||||
const { horizontalViewDimensions = {} } = state['features/filmstrip']; |
||||
|
||||
// Once the thumbnails are reactified this should be moved there too.
|
||||
Filmstrip.resizeThumbnailsForHorizontalView(horizontalViewDimensions, true); |
||||
} |
||||
|
||||
break; |
||||
} |
||||
} |
||||
|
||||
return result; |
||||
}); |
||||
|
@ -0,0 +1,58 @@ |
||||
// @flow
|
||||
|
||||
import { StateListenerRegistry, equals } from '../base/redux'; |
||||
import Filmstrip from '../../../modules/UI/videolayout/Filmstrip'; |
||||
import { getCurrentLayout, getTileViewGridDimensions, shouldDisplayTileView, LAYOUTS } from '../video-layout'; |
||||
|
||||
import { setHorizontalViewDimensions, setTileViewDimensions } from './actions'; |
||||
|
||||
/** |
||||
* Listens for changes in the number of participants to calculate the dimensions of the tile view grid and the tiles. |
||||
*/ |
||||
StateListenerRegistry.register( |
||||
/* selector */ state => state['features/base/participants'].length, |
||||
/* listener */ (numberOfParticipants, store) => { |
||||
const state = store.getState(); |
||||
|
||||
if (shouldDisplayTileView(state)) { |
||||
const gridDimensions = getTileViewGridDimensions(state['features/base/participants'].length); |
||||
const oldGridDimensions = state['features/filmstrip'].tileViewDimensions.gridDimensions; |
||||
const { clientHeight, clientWidth } = state['features/base/responsive-ui']; |
||||
|
||||
if (!equals(gridDimensions, oldGridDimensions)) { |
||||
store.dispatch(setTileViewDimensions(gridDimensions, { |
||||
clientHeight, |
||||
clientWidth |
||||
})); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
/** |
||||
* Listens for changes in the selected layout to calculate the dimensions of the tile view grid and horizontal view. |
||||
*/ |
||||
StateListenerRegistry.register( |
||||
/* selector */ state => getCurrentLayout(state), |
||||
/* listener */ (layout, store) => { |
||||
const state = store.getState(); |
||||
|
||||
switch (layout) { |
||||
case LAYOUTS.TILE_VIEW: { |
||||
const { clientHeight, clientWidth } = state['features/base/responsive-ui']; |
||||
|
||||
store.dispatch(setTileViewDimensions( |
||||
getTileViewGridDimensions(state['features/base/participants'].length), { |
||||
clientHeight, |
||||
clientWidth |
||||
})); |
||||
break; |
||||
} |
||||
case LAYOUTS.HORIZONTAL_FILMSTRIP_VIEW: |
||||
store.dispatch(setHorizontalViewDimensions(state['features/base/responsive-ui'].clientHeight)); |
||||
break; |
||||
case LAYOUTS.VERTICAL_FILMSTRIP_VIEW: |
||||
// Once the thumbnails are reactified this should be moved there too.
|
||||
Filmstrip.resizeThumbnailsForVerticalView(); |
||||
break; |
||||
} |
||||
}); |
Loading…
Reference in new issue