From ea4e274798a51ab0f278ea35872dc3f5d1086b81 Mon Sep 17 00:00:00 2001 From: Prozilla Date: Fri, 14 Jun 2024 21:07:54 +0200 Subject: [PATCH] Fixed bugs --- .../apps/icons/{balls.svg => ball-maze.svg} | 0 src/components/actions/Actions.module.css | 80 ++++++-- src/components/actions/Actions.tsx | 11 +- .../actions/actions/ClickAction.tsx | 8 +- .../apps/_utils/header-menu/HeaderMenu.tsx | 6 +- .../apps/text-editor/TextEditor.tsx | 15 +- src/components/taskbar/Taskbar.module.css | 16 +- src/components/taskbar/Taskbar.tsx | 183 +++++++++--------- src/components/taskbar/app-icon/AppIcon.tsx | 9 +- src/components/taskbar/menus/HomeMenu.tsx | 2 +- .../taskbar/menus/SearchMenu.module.css | 19 +- src/components/taskbar/menus/SearchMenu.tsx | 65 +++---- src/config/actions.config.ts | 4 +- src/features/apps/app.tsx | 1 + src/features/apps/appsManager.ts | 2 +- 15 files changed, 248 insertions(+), 173 deletions(-) rename public/assets/apps/icons/{balls.svg => ball-maze.svg} (100%) diff --git a/public/assets/apps/icons/balls.svg b/public/assets/apps/icons/ball-maze.svg similarity index 100% rename from public/assets/apps/icons/balls.svg rename to public/assets/apps/icons/ball-maze.svg diff --git a/src/components/actions/Actions.module.css b/src/components/actions/Actions.module.css index d88e20a..d71e1b9 100644 --- a/src/components/actions/Actions.module.css +++ b/src/components/actions/Actions.module.css @@ -30,6 +30,8 @@ bottom: 0; } +/* Context menu */ + .ContextMenu.Actions { --border-radius: var(--border-radius-1); --padding: 0.375rem; @@ -147,20 +149,22 @@ .ContextMenu .TextDisplay { margin: 0; - padding: 0.25rem 0.5rem; + padding: 0.25rem 0.75rem; color: var(--foreground-color-1); font-size: 0.875rem; text-align: start; white-space: nowrap; } -.Header-menu { +/* Header menu */ + +.HeaderMenu { display: flex; width: inherit; height: inherit; } -.Header-menu .Dropdown { +.HeaderMenu .Dropdown { position: relative; display: block; width: auto; @@ -173,63 +177,105 @@ cursor: pointer; } -.Header-menu .Dropdown:hover, .Header-menu .Dropdown:focus-visible { +.HeaderMenu .Dropdown:hover, +.HeaderMenu .Dropdown:focus-visible, +.HeaderMenu .Dropdown.Active { background-color: rgba(255, 255, 255, 5%); } -.Header-menu .Dropdown > .Label { +.HeaderMenu .Dropdown > .Label { display: flex; justify-content: center; align-items: center; height: 100%; } -.Header-menu .DropdownArrow { +.HeaderMenu .DropdownArrow { display: none; } -.Header-menu .DropdownContent { +.HeaderMenu .DropdownContent { + opacity: 1; display: flex; flex-direction: column; position: absolute; top: 100%; left: 0; - padding: 0.35rem; + padding: 0.25rem; background-color: var(--background-color-1); - border-bottom-left-radius: 0.5rem; - border-bottom-right-radius: 0.5rem; + border-bottom-left-radius: var(--border-radius-1); + border-bottom-right-radius: var(--border-radius-1); + transition: opacity 100ms ease-out; + cursor: default; } -.Header-menu .Dropdown:not(.Active) .DropdownContent { +.HeaderMenu .Dropdown:not(.Active) .DropdownContent { opacity: 0; pointer-events: none; } -.Header-menu .Button { +.HeaderMenu .Button { + --icon-size: 1.25rem; + --icon-gap: 0.5rem; + display: flex; - gap: 0.75rem; + gap: 1.5rem; justify-content: space-between; + align-items: center; width: 100%; padding: 0.25rem 0.5rem; background: none; border: none; border-radius: var(--border-radius-1); outline: none; - font-size: 0.85rem; + font-size: 0.875rem; text-align: start; white-space: nowrap; cursor: pointer; } -.Header-menu .Button:hover, .Header-menu .Button:focus-visible { +.HeaderMenu .Button:not(:disabled):hover, +.HeaderMenu .Button:not(:disabled):focus-visible { background-color: color-mix(in srgb, var(--background-color-0) 75%, transparent); } -.Header-menu .Dropdown > .Label > p, .Header-menu .Button > .Label > p { +.HeaderMenu .Button:disabled { + cursor: default; +} + +.HeaderMenu .Button > .Label { + display: flex; + gap: var(--icon-gap); + flex-direction: row-reverse; + justify-content: flex-start; + align-items: center; +} + +.HeaderMenu .Button > .Label .Icon div, +.HeaderMenu .Button > .Label .Icon svg { + height: var(--icon-size); + width: var(--icon-size); +} + +.HeaderMenu .Dropdown > .Label > p, +.HeaderMenu .Button > .Label > p { margin: 0; } -.Header-menu .Shortcut { +.HeaderMenu .Button:disabled > .Label > p { + color: var(--foreground-color-1); +} + +.HeaderMenu .Shortcut { color: var(--foreground-color-1); margin: 0; + font-size: 0.875rem; +} + +.HeaderMenu .Divider { + width: calc(100% - 0.5rem); + height: 2px; + border-radius: var(--border-radius-99); + background-color: var(--foreground-color-2); + margin: 0.25rem auto; } \ No newline at end of file diff --git a/src/components/actions/Actions.tsx b/src/components/actions/Actions.tsx index 936be58..e3df666 100644 --- a/src/components/actions/Actions.tsx +++ b/src/components/actions/Actions.tsx @@ -11,6 +11,7 @@ export interface ActionProps { shortcut?: string[]; onTrigger?: (event?: Event, triggerParams?: unknown, ...args: unknown[]) => void; children?: ReactNode; + disabled?: boolean; } export interface ActionsProps { @@ -48,15 +49,18 @@ export function Actions({ children, className, onAnyTrigger, triggerParams, avoi actionId++; - const { label, shortcut, onTrigger } = child.props as ActionProps; + const { label, shortcut, disabled, onTrigger } = child.props as ActionProps; const onTriggerOverride = (event: Event, ...args: unknown[]) => { + if (disabled) + return; + onAnyTrigger?.(event, triggerParams, ...args); onTrigger?.(event, triggerParams, ...args); }; // Register shortcut - if (label != null && onTrigger != null) { + if (!disabled && label != null && onTrigger != null) { options[actionId] = onTriggerOverride; if (shortcut != null) @@ -71,7 +75,8 @@ export function Actions({ children, className, onAnyTrigger, triggerParams, avoi ...child.props, actionId, children: iterateOverChildren((child.props as ActionProps).children), - onTrigger: onTriggerOverride + onTrigger: onTriggerOverride, + disabled } as ActionProps); }); diff --git a/src/components/actions/actions/ClickAction.tsx b/src/components/actions/actions/ClickAction.tsx index 67f9f94..2630895 100644 --- a/src/components/actions/actions/ClickAction.tsx +++ b/src/components/actions/actions/ClickAction.tsx @@ -10,8 +10,12 @@ interface ClickActionProps extends ActionProps { icon?: string | object; } -export const ClickAction = memo(({ actionId, label, shortcut, onTrigger, icon }: ClickActionProps) => { - return ( - - - -
- { updateShowSearch(false); }}> - - - -
+ return
{ + if ((event.target as HTMLElement).getAttribute("data-allow-context-menu")) + onContextMenu(event); + }} + > +
+
+ { updateShowHome(false); }}> + + +
-
-
- {apps} -
-
-
- - - - - + +
- ); +
+
+ {apps.map((app) => { + const isActive = windows.map((window) => window.app.id).includes(app.id); + const shouldBeShown = (app.isPinned || isActive); + return (); + })} +
+
+
+ + + + +
+
; }); \ No newline at end of file diff --git a/src/components/taskbar/app-icon/AppIcon.tsx b/src/components/taskbar/app-icon/AppIcon.tsx index 861cbaa..b17d1f9 100644 --- a/src/components/taskbar/app-icon/AppIcon.tsx +++ b/src/components/taskbar/app-icon/AppIcon.tsx @@ -15,21 +15,18 @@ import WindowsManager from "../../../features/windows/windowsManager"; interface AppButtonProps { app: App; windowsManager: WindowsManager; - pins: string[]; active: boolean; visible: boolean; } -export const AppButton: FC = memo(({ app, windowsManager, pins, active, visible }: AppButtonProps) => { - const isPinned = pins.includes(app.id); - +export const AppButton: FC = memo(({ app, windowsManager, active, visible }: AppButtonProps) => { const settingsManager = useSettingsManager(); const { onContextMenu } = useContextMenu({ Actions: (props) => { windowsManager.open(app.id); }}/> - { + {/* { const newPins = [...pins]; if (isPinned) { removeFromArray(app.id, pins); @@ -42,7 +39,7 @@ export const AppButton: FC = memo(({ app, windowsManager, pins, }}/> {active && { windowsManager.close(windowsManager.getAppWindowId(app.id)); - }}/>} + }}/>} */} }); diff --git a/src/components/taskbar/menus/HomeMenu.tsx b/src/components/taskbar/menus/HomeMenu.tsx index 8c090a6..120c72d 100644 --- a/src/components/taskbar/menus/HomeMenu.tsx +++ b/src/components/taskbar/menus/HomeMenu.tsx @@ -99,7 +99,7 @@ export function HomeMenu({ active, setActive, search }: HomeMenuProps) {

{NAME}

- {AppsManager.APPS.map(({ name, id }) => + {AppsManager.APPS.sort((a, b) => a.name.localeCompare(b.name)).map(({ name, id }) => - )} -
+ return
+
+
+ {apps?.map(({ name, id }) => + + )}
+
- ); +
; } \ No newline at end of file diff --git a/src/config/actions.config.ts b/src/config/actions.config.ts index d9adefb..de1f701 100644 --- a/src/config/actions.config.ts +++ b/src/config/actions.config.ts @@ -2,6 +2,6 @@ import styles from "../components/actions/Actions.module.css"; export const STYLES = { CONTEXT_MENU: styles.ContextMenu, - SHORTCUTS_LISTENER: styles["Shortcuts-listener"], - HEADER_MENU: styles["Header-menu"] + SHORTCUTS_LISTENER: styles.ShortcutsListener, + HEADER_MENU: styles.HeaderMenu }; \ No newline at end of file diff --git a/src/features/apps/app.tsx b/src/features/apps/app.tsx index c776c7d..f0374ea 100644 --- a/src/features/apps/app.tsx +++ b/src/features/apps/app.tsx @@ -10,6 +10,7 @@ export default class App { size: Vector2 }; isActive: boolean = false; + isPinned?: boolean; /** * @param windowOptions - Default window options diff --git a/src/features/apps/appsManager.ts b/src/features/apps/appsManager.ts index 8d520db..deebbe6 100644 --- a/src/features/apps/appsManager.ts +++ b/src/features/apps/appsManager.ts @@ -25,7 +25,7 @@ export default class AppsManager { source: "https://prozilla.dev/wordle", size: new Vector2(400, 650) }), - new App("Balls", "balls", WebView, { + new App("Ball Maze", "ball-maze", WebView, { source: "https://prozilla.dev/ball-maze", size: new Vector2(600, 600) }),