fix: Column sizing may calculate incorrectly in grid mode (#1695)
This commit is contained in:
@@ -264,11 +264,11 @@ cameras:
|
||||
|
||||
Not all [engines](./engine.md) benefit from proxying:
|
||||
|
||||
| Engine | Purpose of proxying |
|
||||
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `frigate` | The Frigate integration already comes with a built-in proxy, so this functionality does not serve any purpose for `frigate`. |
|
||||
| `reolink`, `motioneEye` | May be used to fetch videos in cases where the browser may not be able to access the camera/NVR, or the camera/NVR may use a self-signed SSL certificate that your browser would otherwise reject due to [mixed content](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content). |
|
||||
| `generic` | `generic` cameras do not have media, so proxying currently would serve no purpose. |
|
||||
| Engine | Purpose of proxying |
|
||||
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `frigate` | The Frigate integration already comes with a built-in proxy, so this functionality does not serve any purpose for `frigate`. |
|
||||
| `reolink`, `motioneye` | May be used to fetch videos in cases where the browser may not be able to access the camera/NVR, or the camera/NVR may use a self-signed SSL certificate that your browser would otherwise reject due to [mixed content](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content). |
|
||||
| `generic` | `generic` cameras do not have media, so proxying currently would serve no purpose. |
|
||||
|
||||
Regardless of the parameters, the integration will never attempt to proxy
|
||||
content if the
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
const MEDIA_GRID_DEFAULT_MIN_CELL_WIDTH = 190;
|
||||
const MEDIA_GRID_DEFAULT_IDEAL_CELL_WIDTH = 600;
|
||||
const MEDIA_GRID_DEFAULT_SELECTED_WIDTH_FACTOR = 2.0;
|
||||
const MEDIA_GRID_HORIZONTAL_GUTTER_WIDTH = 1;
|
||||
|
||||
type GridID = string;
|
||||
type MediaGridChild = HTMLElement & FrigateCardMediaLoadedEventTarget;
|
||||
@@ -276,6 +277,7 @@ export class MediaGridController {
|
||||
initLayout: false,
|
||||
percentPosition: true,
|
||||
transitionDuration: '0.2s',
|
||||
gutter: MEDIA_GRID_HORIZONTAL_GUTTER_WIDTH,
|
||||
});
|
||||
this._masonry.addItems?.([...this._gridContents.values()]);
|
||||
this._throttledLayout();
|
||||
@@ -308,7 +310,12 @@ export class MediaGridController {
|
||||
}
|
||||
|
||||
protected _getColumnSize(): number {
|
||||
return Math.round(this._hostWidth / this._getColumns());
|
||||
const columns = this._getColumns();
|
||||
if (columns === 1) {
|
||||
return this._hostWidth;
|
||||
}
|
||||
|
||||
return Math.max(0, this._hostWidth / columns - MEDIA_GRID_HORIZONTAL_GUTTER_WIDTH);
|
||||
}
|
||||
|
||||
protected _getColumns(): number {
|
||||
|
||||
@@ -398,16 +398,16 @@ describe('MediaGridController', () => {
|
||||
expect(Masonry).toBeCalledWith(
|
||||
parent,
|
||||
expect.objectContaining({
|
||||
columnWidth: 246,
|
||||
columnWidth: 245,
|
||||
}),
|
||||
);
|
||||
expect(parent.style.getPropertyValue('--frigate-card-grid-column-size')).toBe(
|
||||
'246px',
|
||||
'245px',
|
||||
);
|
||||
});
|
||||
|
||||
it('should respect exact columns', () => {
|
||||
const parent = createParent({ children: createChildren(), width: 2000 });
|
||||
const parent = createParent({ children: createChildren(), width: 3000 });
|
||||
const controller = createController(parent);
|
||||
controller.setDisplayConfig({ mode: 'grid', grid_columns: 2 });
|
||||
|
||||
@@ -417,11 +417,11 @@ describe('MediaGridController', () => {
|
||||
expect(Masonry).toBeCalledWith(
|
||||
parent,
|
||||
expect.objectContaining({
|
||||
columnWidth: 1000,
|
||||
columnWidth: 1499,
|
||||
}),
|
||||
);
|
||||
expect(parent.style.getPropertyValue('--frigate-card-grid-column-size')).toBe(
|
||||
'1000px',
|
||||
'1499px',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -487,11 +487,11 @@ describe('MediaGridController', () => {
|
||||
expect(Masonry).toBeCalledWith(
|
||||
parent,
|
||||
expect.objectContaining({
|
||||
columnWidth: 246,
|
||||
columnWidth: 245,
|
||||
}),
|
||||
);
|
||||
expect(parent.style.getPropertyValue('--frigate-card-grid-column-size')).toBe(
|
||||
'246px',
|
||||
'245px',
|
||||
);
|
||||
|
||||
// Clear mock state.
|
||||
@@ -499,18 +499,18 @@ describe('MediaGridController', () => {
|
||||
vi.mocked(masonry.layout)?.mockClear();
|
||||
|
||||
// Resize the host.
|
||||
setElementWidth(parent, 2000);
|
||||
setElementWidth(parent, 3000);
|
||||
triggerResizeObserver('host');
|
||||
|
||||
// Masonry should be reconstructed, styles set and layout called.
|
||||
expect(Masonry).toBeCalledWith(
|
||||
parent,
|
||||
expect.objectContaining({
|
||||
columnWidth: 667,
|
||||
columnWidth: 599,
|
||||
}),
|
||||
);
|
||||
expect(parent.style.getPropertyValue('--frigate-card-grid-column-size')).toBe(
|
||||
'667px',
|
||||
'599px',
|
||||
);
|
||||
expect(masonry.layout).toBeCalled();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user