🐛 Improve resposivnes

This commit is contained in:
Meierschlumpf
2023-01-04 19:06:19 +01:00
parent afe3e2fc39
commit d439ba1842
6 changed files with 244 additions and 176 deletions

View File

@@ -17,81 +17,6 @@
} }
], ],
"apps": [ "apps": [
{
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a33a",
"name": "Documentation",
"url": "https://homarr.dev",
"behaviour": {
"onClickUrl": "https://homarr.dev",
"externalUrl": "https://homarr.dev",
"isOpeningNewTab": true
},
"network": {
"enabledStatusChecker": false,
"okStatus": [
200
]
},
"appearance": {
"iconUrl": "/imgs/logo/logo.png"
},
"integration": {
"type": null,
"properties": []
},
"area": {
"type": "wrapper",
"properties": {
"id": "default"
}
},
"shape": {
"location": {
"x": 0,
"y": 11
},
"size": {
"width": 4,
"height": 3
}
}
},
{
"id": "e41a11f5-9c6e-41bc-ac0e-4c4c47582faa",
"name": "Your app",
"url": "https://homarr.dev",
"appearance": {
"iconUrl": "/imgs/logo/logo.png"
},
"network": {
"enabledStatusChecker": false,
"okStatus": []
},
"behaviour": {
"isOpeningNewTab": true,
"externalUrl": ""
},
"area": {
"type": "wrapper",
"properties": {
"id": "default"
}
},
"shape": {
"location": {
"x": 8,
"y": 10
},
"size": {
"width": 4,
"height": 2
}
},
"integration": {
"type": null,
"properties": []
}
},
{ {
"id": "5df743d9-5cb1-457c-85d2-64ff86855652", "id": "5df743d9-5cb1-457c-85d2-64ff86855652",
"name": "Your app", "name": "Your app",
@@ -128,6 +53,42 @@
"properties": [] "properties": []
} }
}, },
{
"id": "76217a87-7151-42d0-b0cf-1b72aef63f83",
"name": "Small app",
"url": "https://homarr.dev",
"appearance": {
"iconUrl": "/imgs/logo/logo.png"
},
"network": {
"enabledStatusChecker": false,
"okStatus": []
},
"behaviour": {
"isOpeningNewTab": true,
"externalUrl": "https://homarr.dev"
},
"area": {
"type": "category",
"properties": {
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a33f"
}
},
"shape": {
"location": {
"x": 4,
"y": 0
},
"size": {
"width": 1,
"height": 1
}
},
"integration": {
"type": null,
"properties": []
}
},
{ {
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a330", "id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a330",
"name": "Contribute", "name": "Contribute",
@@ -158,7 +119,7 @@
}, },
"shape": { "shape": {
"location": { "location": {
"x": 4, "x": 7,
"y": 0 "y": 0
}, },
"size": { "size": {
@@ -167,42 +128,6 @@
} }
} }
}, },
{
"id": "76217a87-7151-42d0-b0cf-1b72aef63f83",
"name": "Small app",
"url": "https://homarr.dev",
"appearance": {
"iconUrl": "/imgs/logo/logo.png"
},
"network": {
"enabledStatusChecker": false,
"okStatus": []
},
"behaviour": {
"isOpeningNewTab": true,
"externalUrl": "https://homarr.dev"
},
"area": {
"type": "category",
"properties": {
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a33f"
}
},
"shape": {
"location": {
"x": 5,
"y": 0
},
"size": {
"width": 1,
"height": 1
}
},
"integration": {
"type": null,
"properties": []
}
},
{ {
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a337", "id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a337",
"name": "Discord", "name": "Discord",
@@ -242,6 +167,45 @@
} }
} }
}, },
{
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a33a",
"name": "Documentation",
"url": "https://homarr.dev",
"behaviour": {
"onClickUrl": "https://homarr.dev",
"externalUrl": "https://homarr.dev",
"isOpeningNewTab": true
},
"network": {
"enabledStatusChecker": false,
"okStatus": [
200
]
},
"appearance": {
"iconUrl": "/imgs/logo/logo.png"
},
"integration": {
"type": null,
"properties": []
},
"area": {
"type": "wrapper",
"properties": {
"id": "default"
}
},
"shape": {
"location": {
"x": 0,
"y": 11
},
"size": {
"width": 4,
"height": 3
}
}
},
{ {
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a990", "id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a990",
"name": "Donate", "name": "Donate",
@@ -272,7 +236,7 @@
}, },
"shape": { "shape": {
"location": { "location": {
"x": 7, "x": 5,
"y": 0 "y": 0
}, },
"size": { "size": {
@@ -280,54 +244,45 @@
"height": 1 "height": 1
} }
} }
},
{
"id": "e41a11f5-9c6e-41bc-ac0e-4c4c47582faa",
"name": "Your app",
"url": "https://homarr.dev",
"appearance": {
"iconUrl": "/imgs/logo/logo.png"
},
"network": {
"enabledStatusChecker": false,
"okStatus": []
},
"behaviour": {
"isOpeningNewTab": true,
"externalUrl": ""
},
"area": {
"type": "wrapper",
"properties": {
"id": "default"
}
},
"shape": {
"location": {
"x": 8,
"y": 10
},
"size": {
"width": 4,
"height": 2
}
},
"integration": {
"type": null,
"properties": []
}
} }
], ],
"widgets": [ "widgets": [
{
"id": "weather",
"properties": {
"displayInFahrenheit": false,
"location": "Paris"
},
"area": {
"type": "category",
"properties": {
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a33f"
}
},
"shape": {
"location": {
"x": 0,
"y": 0
},
"size": {
"width": 2,
"height": 2
}
}
},
{
"id": "date",
"properties": {
"display24HourFormat": true
},
"area": {
"type": "category",
"properties": {
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a33f"
}
},
"shape": {
"location": {
"x": 2,
"y": 0
},
"size": {
"width": 2,
"height": 2
}
}
},
{ {
"id": "calendar", "id": "calendar",
"properties": { "properties": {
@@ -349,6 +304,51 @@
"height": 5 "height": 5
} }
} }
},
{
"id": "weather",
"properties": {
"displayInFahrenheit": false,
"location": "Paris"
},
"area": {
"type": "category",
"properties": {
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a33f"
}
},
"shape": {
"location": {
"x": 0,
"y": 0
},
"size": {
"width": 4,
"height": 1
}
}
},
{
"id": "date",
"properties": {
"display24HourFormat": true
},
"area": {
"type": "category",
"properties": {
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a33f"
}
},
"shape": {
"location": {
"x": 8,
"y": 0
},
"size": {
"width": 4,
"height": 1
}
}
} }
], ],
"settings": { "settings": {

View File

@@ -12,7 +12,7 @@ export const initializeGridstack = (
items: AppType[], items: AppType[],
widgets: IWidget<string, any>[], widgets: IWidget<string, any>[],
isEditMode: boolean, isEditMode: boolean,
isLargerThanSm: boolean, wrapperColumnCount: 3 | 6 | 12,
events: { events: {
onChange: (changedNode: GridStackNode) => void; onChange: (changedNode: GridStackNode) => void;
onAdd: (addedNode: GridStackNode) => void; onAdd: (addedNode: GridStackNode) => void;
@@ -20,7 +20,7 @@ export const initializeGridstack = (
) => { ) => {
if (!wrapperRef.current) return; if (!wrapperRef.current) return;
// calculates the currently available count of columns // calculates the currently available count of columns
const columnCount = areaType === 'sidebar' ? 4 : isLargerThanSm || typeof isLargerThanSm === 'undefined' ? 12 : 6; const columnCount = areaType === 'sidebar' ? 4 : wrapperColumnCount;
const minRow = areaType !== 'sidebar' ? 1 : Math.floor(wrapperRef.current.offsetHeight / 64); const minRow = areaType !== 'sidebar' ? 1 : Math.floor(wrapperRef.current.offsetHeight / 64);
// initialize gridstack // initialize gridstack
const newGrid = gridRef; const newGrid = gridRef;

View File

@@ -28,11 +28,18 @@ interface UseGristackReturnType {
}; };
} }
const useWrapperColumnCount = () => {
const isLargerThanSm = useScreenLargerThan('sm');
const isLargerThanXl = useScreenLargerThan('xl');
return typeof isLargerThanXl === 'undefined' || isLargerThanXl ? 12 : isLargerThanSm ? 6 : 3;
};
export const useGridstack = ( export const useGridstack = (
areaType: 'wrapper' | 'category' | 'sidebar', areaType: 'wrapper' | 'category' | 'sidebar',
areaId: string areaId: string
): UseGristackReturnType => { ): UseGristackReturnType => {
const isLargerThanSm = useScreenLargerThan('sm'); const wrapperColumnCount = useWrapperColumnCount();
const isEditMode = useEditModeStore((x) => x.enabled); const isEditMode = useEditModeStore((x) => x.enabled);
const { config, configVersion, name: configName } = useConfigContext(); const { config, configVersion, name: configName } = useConfigContext();
const updateConfig = useConfigStore((x) => x.updateConfig); const updateConfig = useConfigStore((x) => x.updateConfig);
@@ -82,59 +89,104 @@ export const useGridstack = (
useEffect(() => { useEffect(() => {
if (areaType === 'sidebar') return; if (areaType === 'sidebar') return;
gridRef.current?.column( gridRef.current?.column(
isLargerThanSm || typeof isLargerThanSm === 'undefined' ? 12 : 6, wrapperColumnCount,
(column, prevColumn, newNodes, nodes) => { (column, prevColumn, newNodes, nodes) => {
let nextRow = 0; let nextRow = 0;
let available = 6; let available = column;
if (column === prevColumn) { if (column === prevColumn) {
newNodes.concat(nodes); newNodes.concat(nodes);
return; return;
} }
nodes.reverse().forEach((node) => { const getGridstackAttribute = (node: GridStackNode, path: 'x' | 'y' | 'w' | 'h'): number => parseInt(node.el!.getAttribute(`data-gridstack-${path}`)!, 10);
const getGridstackAttributes = (node: GridStackNode) => ({
width: getGridstackAttribute(node, 'w'),
height: getGridstackAttribute(node, 'h'),
x: getGridstackAttribute(node, 'x'),
y: getGridstackAttribute(node, 'y'),
});
const sortNodes = (a: GridStackNode, b: GridStackNode) => {
const aAttributes = getGridstackAttributes(a);
const bAttributes = getGridstackAttributes(b);
const differenceY = aAttributes.y - bAttributes.y;
return differenceY !== 0 ? differenceY : aAttributes.x - bAttributes.x;
};
const sorted = nodes.sort(sortNodes);
console.log(sorted);
sorted.forEach((node) => {
const newnode = node; const newnode = node;
const width = parseInt(newnode.el!.getAttribute('data-gridstack-w')!, 10); const width = parseInt(newnode.el!.getAttribute('data-gridstack-w')!, 10);
const height = parseInt(newnode.el!.getAttribute('data-gridstack-h')!, 10); const height = parseInt(newnode.el!.getAttribute('data-gridstack-h')!, 10);
const x = parseInt(newnode.el!.getAttribute('data-gridstack-x')!, 10); const x = parseInt(newnode.el!.getAttribute('data-gridstack-x')!, 10);
const y = parseInt(newnode.el!.getAttribute('data-gridstack-y')!, 10); const y = parseInt(newnode.el!.getAttribute('data-gridstack-y')!, 10);
const moveYDown = 1;
if (column === 6) { if (column === 3) {
newnode.x = available >= width ? 3 - available : 0;
newnode.y = available === 3 || available >= width ? nextRow : nextRow += moveYDown;
if (width > 3) {
newnode.w = 3;
nextRow += moveYDown;
available = 3;
} else if (available >= width) {
available -= width;
if (available === 0) {
nextRow += moveYDown;
available = 3;
}
} else if (available < width) {
newnode.y = newnode.y! + moveYDown;
available = 3 - width;
nextRow += moveYDown;
}
} else if (column === 6) {
newnode.x = available >= width ? 6 - available : 0; newnode.x = available >= width ? 6 - available : 0;
newnode.y = nextRow; newnode.y = nextRow;
if (width > 6) { if (width > 6) {
newnode.w = 6; newnode.w = 6;
nextRow += 2; nextRow += moveYDown;
available = 6; available = 6;
} else if (available >= width) { } else if (available >= width) {
available -= width; available -= width;
if (available === 0) { if (available === 0) {
nextRow += 2; nextRow += moveYDown;
available = 6; available = 6;
} }
} else if (available < width) { } else if (available < width) {
newnode.y = newnode.y! + 2; newnode.y = newnode.y! + moveYDown;
available = 6 - width; available = 6 - width;
nextRow += 2; nextRow += moveYDown;
} }
} else { } else {
newnode.x = y % 2 === 1 ? x + 6 : x; newnode.x = y % 2 === 1 ? x + 6 : x;
newnode.y = Math.floor(y / 2); newnode.y = Math.floor(y / 2);
} }
console.log(newnode);
newNodes.push(newnode); newNodes.push(newnode);
}); });
} }
); );
}, [isLargerThanSm]); }, [wrapperColumnCount]);
useEffect(() => { useEffect(() => {
if (width === 0) return; if (width === 0) return;
const widgetWidth = width / (isLargerThanSm ? 12 : 6); const widgetWidth = width / wrapperColumnCount;
// widget width is used to define sizes of gridstack items within global.scss // widget width is used to define sizes of gridstack items within global.scss
root.style.setProperty('--gridstack-widget-width', widgetWidth.toString()); root.style.setProperty('--gridstack-widget-width', widgetWidth.toString());
gridRef.current?.cellHeight(widgetWidth); gridRef.current?.cellHeight(widgetWidth);
}, [width, isLargerThanSm]); }, [width, wrapperColumnCount]);
const onChange = isEditMode const onChange = isEditMode
? (changedNode: GridStackNode) => { ? (changedNode: GridStackNode) => {
@@ -291,7 +343,7 @@ export const useGridstack = (
items, items,
widgets ?? [], widgets ?? [],
isEditMode, isEditMode,
isLargerThanSm, wrapperColumnCount,
{ {
onChange, onChange,
onAdd, onAdd,

View File

@@ -59,7 +59,7 @@
transition: none; transition: none;
} }
@media screen and (max-width: 768px) { @media screen and (max-width: 1400px) {
@for $i from 1 to 7 { @for $i from 1 to 7 {
.grid-stack>.grid-stack-item[gs-w="#{$i}"] { width: percentage(($i / 6)) !important } .grid-stack>.grid-stack-item[gs-w="#{$i}"] { width: percentage(($i / 6)) !important }
.grid-stack>.grid-stack-item[gs-min-w="#{$i}"] { min-width: percentage(($i / 6)) !important } .grid-stack>.grid-stack-item[gs-min-w="#{$i}"] { min-width: percentage(($i / 6)) !important }
@@ -74,3 +74,19 @@
min-width: percentage(1/6) !important; min-width: percentage(1/6) !important;
} }
} }
@media screen and (max-width: 768px) {
@for $i from 1 to 4 {
.grid-stack>.grid-stack-item[gs-w="#{$i}"] { width: percentage(($i / 3)) !important }
.grid-stack>.grid-stack-item[gs-min-w="#{$i}"] { min-width: percentage(($i / 3)) !important }
.grid-stack>.grid-stack-item[gs-max-w="#{$i}"] { max-width: percentage(($i / 3)) !important }
}
@for $i from 1 to 4 {
.grid-stack>.grid-stack-item[gs-x="#{$i}"] { left: percentage(($i / 3)) }
}
.grid-stack>.grid-stack-item {
min-width: percentage(1/3) !important;
}
}

View File

@@ -17,7 +17,7 @@ const definition = defineWidget({
}, },
gridstack: { gridstack: {
minWidth: 2, minWidth: 2,
minHeight: 2, minHeight: 1,
maxWidth: 12, maxWidth: 12,
maxHeight: 12, maxHeight: 12,
}, },

View File

@@ -20,7 +20,7 @@ const definition = defineWidget({
}, },
gridstack: { gridstack: {
minWidth: 2, minWidth: 2,
minHeight: 2, minHeight: 1,
maxWidth: 12, maxWidth: 12,
maxHeight: 12, maxHeight: 12,
}, },