Skip to content

Commit

Permalink
Fix overlap issue on load #133
Browse files Browse the repository at this point in the history
  • Loading branch information
OlegWock committed Nov 25, 2023
1 parent 0c8e0c6 commit bb78269
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 24 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
"to-string-loader": "^1.2.0",
"ts-loader": "^9.4.2",
"ts-node": "^10.9.1",
"typescript": "^5.0.4",
"typescript": "^5.3.2",
"url": "^0.11.0",
"walk-sync": "^3.0.0",
"webextension-polyfill": "^0.10.0",
Expand Down
47 changes: 44 additions & 3 deletions src/pages/newtab/start.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Suspense, lazy, useEffect, useMemo, useState } from 'react';
import { Modal } from '@components/Modal';
import { AnimatePresence, LazyMotion, MotionConfig, m } from 'framer-motion';
import { DirectionProvider } from '@radix-ui/react-direction';
import { useFolders } from '@utils/user-data/hooks';
import { getFolderDetails, setFolderDetails, useFolders } from '@utils/user-data/hooks';
import { FolderContent } from './components/FolderContent';
import { useHotkeys, useMirrorStateToRef, usePrevious } from '@utils/hooks';
import { storage, useBrowserStorageValue } from '@utils/storage/api';
Expand All @@ -22,7 +22,8 @@ import { useTranslation } from 'react-i18next';
import { IS_ANDROID, IS_IPAD, IS_TOUCH_DEVICE } from '@utils/device';
import { WidgetWindowsProvider, useWidgetWindows } from '@components/WidgetExpandArea';
import { loadAndMigrateStorage } from '@utils/storage/migrations';
import { Folder } from '@utils/user-data/types';
import { Folder, homeFolder } from '@utils/user-data/types';
import { findOverlapItems, findPositionForItemInGrid } from '@utils/grid';

const SettingsModal = lazy(() => import('./settings/Settings').then(m => ({ 'default': m.SettingsModal })));
const WhatsNew = lazy(() => import('@components/WhatsNew').then(m => ({ 'default': m.WhatsNew })));
Expand Down Expand Up @@ -128,7 +129,7 @@ const Start = () => {
useHotkeys('alt+8', () => switchToFolderByIndex(7));
useHotkeys('alt+9', () => switchToFolderByIndex(8));

console.log('Current language', {language, dir});
console.log('Current language', { language, dir });
return (
<DirectionProvider dir={dir}>
<MotionConfig transition={{ duration: 0.2, ease: 'easeInOut' }}>
Expand Down Expand Up @@ -245,6 +246,46 @@ getAllCustomIcons();

loadAndMigrateStorage()
.then(() => initTranslation())
.then(async (): Promise<void> => {
let folders = await storage.getOne('folders');
if (!folders) folders = [];
folders.unshift(homeFolder);
console.log('Checking for overlay');
for (const folder of folders) {
const { widgets } = await getFolderDetails(folder.id);
const reversedWidgets = [...widgets].reverse();
const overlapItems = findOverlapItems(reversedWidgets);
if (overlapItems.length) {
console.log('Found ovelap:', overlapItems);
const overlapItemIds = overlapItems.map(i => i.instanceId);
const layoutWithoutOverlay = widgets.filter(w => {
return !overlapItemIds.includes(w.instanceId);
});
overlapItems.map(item => {
const columns = Math.max(...layoutWithoutOverlay.map(i => i.x + i.width), 0);
const rows = Math.max(...layoutWithoutOverlay.map(i => i.y + i.height), 0);
let position = findPositionForItemInGrid({
grid: {rows, columns},
layout: layoutWithoutOverlay,
item,
});
if (!position) {
position = {
x: columns,
y: 0,
}
}
layoutWithoutOverlay.push({
...item,
...position,
});
});
setFolderDetails(folder.id, {
widgets: layoutWithoutOverlay,
});
}
}
})
.then(() => {
mountPage(<CompactModeProvider>
{/* strict mode temporary disabled due to strict https://github.com/framer/motion/issues/2094 */}
Expand Down
30 changes: 27 additions & 3 deletions src/utils/grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ export type Layout<T extends {} = {}> = LayoutItem<T>[];

type Grid2DArray = boolean[][];

export class OverlapError extends Error {
constructor() {
super('Elements in the layout have overlap');
this.name = "ValidationError";
}
}

export const calculateColumnWidth = (containerWidth: number, desiredSize: number, minBoxSize: number) => {
const columns = Math.round(containerWidth / desiredSize);
const colWidth = Math.min(Math.max(Math.floor(containerWidth / columns), minBoxSize), desiredSize);
Expand Down Expand Up @@ -132,7 +139,7 @@ const layoutItemToSectors = (item: LayoutItem) => {
return arr;
}

export const layoutTo2DArray = ({ grid, layout, allowOverlay = false }: { grid: GridDimensions, layout: Layout<any>, allowOverlay?: boolean }): Grid2DArray => {
export const layoutTo2DArray = ({ grid, layout, allowOverlay = false }: { grid: Pick<GridDimensions, 'columns' | 'rows'>, layout: Layout<any>, allowOverlay?: boolean }): Grid2DArray => {
const arr = [...Array(grid.rows)].map(() => {
return [...Array(grid.columns)].map(() => false);
});
Expand All @@ -143,7 +150,7 @@ export const layoutTo2DArray = ({ grid, layout, allowOverlay = false }: { grid:
if (s.x >= grid.columns || s.y >= grid.rows) return;
if (arr[s.y][s.x] && !allowOverlay) {
console.log('Item:', item);
throw new Error('elements in layout have overlay');
throw new OverlapError();
}
arr[s.y][s.x] = true;
})
Expand All @@ -152,6 +159,23 @@ export const layoutTo2DArray = ({ grid, layout, allowOverlay = false }: { grid:
return arr;
};

export const findOverlapItems = <T extends {}>(layout: Layout<T>): LayoutItem<T>[] => {
const overlapItems: LayoutItem<T>[] = [];
const arr: boolean[][] = [];
for (const item of layout) {
const itemSectors = layoutItemToSectors(item);
for (const s of itemSectors) {
if (!arr[s.y]) arr[s.y] = [];
if (arr[s.y][s.x]) {
overlapItems.push(item);
break;
}
arr[s.y][s.x] = true;
}
}
return overlapItems;
};

export const willItemOverlay = ({ arr, item }: { arr: Grid2DArray, item: LayoutItem }): boolean => {
const itemSectors = layoutItemToSectors(item);
for (const sector of itemSectors) {
Expand All @@ -171,7 +195,7 @@ export const canPlaceItemInGrid = ({ grid, layout, item, position }: { grid: Gri
return true;
};

export const findPositionForItemInGrid = ({ grid, layout, item }: { grid: GridDimensions, layout: Layout, item: LayoutItemSize }): false | Position => {
export const findPositionForItemInGrid = ({ grid, layout, item }: { grid: Pick<GridDimensions, 'columns' | 'rows'>, layout: Layout, item: LayoutItemSize }): false | Position => {
const arr = layoutTo2DArray({ grid, layout });

for (let i = 0; i < arr.length; i++) {
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"include": ["declarations.d.ts", "src/**/*", "webpack.config.ts"],
"exclude": ["node_modules", "dist", "safari-app"],
"compilerOptions": {
"lib": ["es6", "es2019", "dom", "dom.iterable", "WebWorker"],
"lib": ["es6", "es2023", "dom", "dom.iterable", "WebWorker"],
"baseUrl": ".",
"paths": {
"@utils/*": ["./src/utils/*"],
Expand Down
10 changes: 6 additions & 4 deletions webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,7 @@ const generateManifest = (
],

chrome_url_overrides: {
newtab: "pages/newtab/start.html"
},
chrome_settings_overrides: {
homepage: "pages/newtab/start.html"
newtab: "/pages/newtab/start.html"
},
web_accessible_resources: [
{
Expand Down Expand Up @@ -188,6 +185,11 @@ const generateManifest = (

if (targetBrowser === 'firefox') {
manifest.optional_permissions!.push('webRequest', 'webRequestBlocking');

// Despite the name this seem to work only in Firefox (for Chrome new tab page and home page are the same)
manifest.chrome_settings_overrides = {
homepage: "pages/newtab/start.html"
};
}

return manifest;
Expand Down
17 changes: 5 additions & 12 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1409,14 +1409,7 @@
dependencies:
"@babel/runtime" "^7.13.10"

"@radix-ui/[email protected]":
version "1.0.1"
resolved "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz"
integrity sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==
dependencies:
"@babel/runtime" "^7.13.10"

"@radix-ui/react-direction@^1.0.1":
"@radix-ui/[email protected]", "@radix-ui/react-direction@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.0.1.tgz#9cb61bf2ccf568f3421422d182637b7f47596c9b"
integrity sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==
Expand Down Expand Up @@ -6511,10 +6504,10 @@ typed-function@^4.1.0:
resolved "https://registry.npmjs.org/typed-function/-/typed-function-4.1.0.tgz"
integrity sha512-DGwUl6cioBW5gw2L+6SMupGwH/kZOqivy17E4nsh1JI9fKF87orMmlQx3KISQPmg3sfnOUGlwVkroosvgddrlg==

typescript@^5.0.4:
version "5.0.4"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz"
integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
typescript@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.2.tgz#00d1c7c1c46928c5845c1ee8d0cc2791031d4c43"
integrity sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==

unbox-primitive@^1.0.2:
version "1.0.2"
Expand Down

0 comments on commit bb78269

Please sign in to comment.