Fixed bugs

This commit is contained in:
Prozilla 2024-06-14 21:07:54 +02:00
parent a396cbaf88
commit ea4e274798
No known key found for this signature in database
GPG key ID: 5858DFE71CAF31EE
15 changed files with 248 additions and 173 deletions

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -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;
}

View file

@ -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);
});

View file

@ -10,8 +10,12 @@ interface ClickActionProps extends ActionProps {
icon?: string | object;
}
export const ClickAction = memo(({ actionId, label, shortcut, onTrigger, icon }: ClickActionProps) => {
return (<button key={actionId} className={styles.Button} tabIndex={0} onClick={onTrigger as unknown as MouseEventHandler}>
export const ClickAction = memo(({ actionId, label, shortcut, disabled, onTrigger, icon }: ClickActionProps) => {
const classNames = [styles.Button];
if (disabled)
classNames.push(styles.Disabled);
return (<button key={actionId} className={classNames.join(" ")} tabIndex={0} disabled={disabled} onClick={onTrigger as unknown as MouseEventHandler}>
<span className={styles.Label}>
{icon && <div className={styles.Icon}>
{typeof icon == "string"

View file

@ -1,10 +1,14 @@
import styles from "./HeaderMenu.module.css";
import { ActionsProps, Actions } from "../../../actions/Actions";
import { STYLES } from "../../../../config/actions.config";
import { useZIndex } from "../../../../hooks/z-index/zIndex";
import { ZIndexManager } from "../../../../features/z-index/zIndexManager";
export function HeaderMenu({ children, ...props }: ActionsProps) {
return <div className={styles.HeaderMenu}>
const zIndex = useZIndex({ groupIndex: ZIndexManager.GROUPS.MODALS, index: 0 });
return <div className={styles.HeaderMenu} style={{ zIndex }}>
<Actions className={STYLES.HEADER_MENU} {...props}>
{children}
</Actions>

View file

@ -22,6 +22,8 @@ import App from "../../../features/apps/app";
import WindowsManager from "../../../features/windows/windowsManager";
import { MarkdownBlockquote } from "./overrides/MarkdownBlockquote";
import { useVirtualRoot } from "../../../hooks/virtual-drive/virtualRootContext";
import { APP_NAMES } from "../../../config/apps.config";
import { Divider } from "../../actions/actions/Divider";
const OVERRIDES = {
a: MarkdownLink,
@ -53,6 +55,7 @@ export function TextEditor({ file, path, setTitle, setIconUrl, close, mode, app,
const [content, setContent] = useState(file?.content ?? "");
const [unsavedChanges, setUnsavedChanges] = useState(file == null);
const [zoom, setZoom] = useState(DEFAULT_ZOOM);
const [initialised, setInitialised] = useState(false);
const { openWindowedModal } = useWindowedModal();
useEffect(() => {
@ -103,14 +106,14 @@ export function TextEditor({ file, path, setTitle, setIconUrl, close, mode, app,
}, [currentFile, setTitle, unsavedChanges, currentMode, app.name]);
useEffect(() => {
if (currentFile == null && path != null) {
if (!initialised && currentFile == null && path != null) {
const newFile = virtualRoot.navigate(path);
if (newFile == null || !newFile.isFile())
return;
setCurrentFile(newFile as VirtualFile);
path = null;
setInitialised(true);
}
}, [path, currentFile]);
@ -176,16 +179,22 @@ export function TextEditor({ file, path, setTitle, setIconUrl, close, mode, app,
/>
});
}} shortcut={["Control", "o"]}/>
<Divider/>
<ClickAction label="Save" onTrigger={() => { saveText(); }} shortcut={["Control", "s"]}/>
<ClickAction label={`Reveal in ${APP_NAMES.FILE_EXPLORER}`} disabled={currentFile == null} onTrigger={() => {
currentFile.parent.open(windowsManager);
}}/>
<Divider/>
<ClickAction label="Quit" onTrigger={() => { close(); }} shortcut={["Control", "q"]}/>
</DropdownAction>
<DropdownAction label="View" showOnHover={false}>
<ClickAction label={currentMode === "view" ? "Edit mode" : "Preview mode"} onTrigger={() => {
setCurrentMode(currentMode === "view" ? "edit" : "view");
}} shortcut={["Control", "v"]}/>
<Divider/>
<ClickAction label="Zoom in" onTrigger={() => { setZoom(zoom + ZOOM_FACTOR); }} shortcut={["Control", "+"]}/>
<ClickAction label="Zoom out" onTrigger={() => { setZoom(zoom - ZOOM_FACTOR); }} shortcut={["Control", "-"]}/>
<ClickAction label="Reset Zoom" onTrigger={() => { setZoom(DEFAULT_ZOOM); }} shortcut={["Control", "0"]}/>
<ClickAction label="Reset Zoom" disabled={zoom == DEFAULT_ZOOM} onTrigger={() => { setZoom(DEFAULT_ZOOM); }} shortcut={["Control", "0"]}/>
</DropdownAction>
</HeaderMenu>
{currentMode === "view"

View file

@ -55,6 +55,14 @@
padding: 0 !important;
}
.HomeContainer,
.HomeContainer > div,
.SearchContainer,
.SearchContainer > div {
height: 100%;
width: auto;
}
.HomeButton * {
fill: var(--foreground-color-0);
filter: none;
@ -102,10 +110,10 @@
height: 1.25rem;
}
.AppIcons div,
.AppIcons div > svg,
.MenuIcons div,
.MenuIcons div > svg {
.AppIcons > button div,
.AppIcons > button div > svg,
.MenuButton div,
.MenuButton div > svg {
height: 100%;
width: auto;
}

View file

@ -1,4 +1,4 @@
import { CSSProperties, memo, ReactEventHandler, UIEventHandler, useEffect, useMemo, useRef, useState } from "react";
import { CSSProperties, memo, ReactEventHandler, UIEventHandler, useEffect, useRef, useState } from "react";
import styles from "./Taskbar.module.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCog, faSearch } from "@fortawesome/free-solid-svg-icons";
@ -24,6 +24,7 @@ import { SettingsManager } from "../../features/settings/settingsManager";
import { useWindows } from "../../hooks/windows/windowsContext";
import { ZIndexManager } from "../../features/z-index/zIndexManager";
import { useZIndex } from "../../hooks/z-index/zIndex";
import App from "../../features/apps/app";
export const Taskbar = memo(() => {
const ref = useRef(null);
@ -48,38 +49,31 @@ export const Taskbar = memo(() => {
}}/>
</Actions>
});
const [pins, setPins] = useState([]);
const [apps, setApps] = useState<App[]>([]);
const zIndex = useZIndex({ groupIndex: ZIndexManager.GROUPS.TASKBAR, index: 0 });
const apps = useMemo(() => AppsManager.APPS.sort((appA, appB) => {
const indexA = pins.indexOf(appA.id);
const indexB = pins.indexOf(appB.id);
if (indexA < 0 && indexB > 0) {
return 1;
} else if (indexA > 0 && indexB < 0) {
return -1;
} else if (indexA < 0 && indexB < 0) {
return 0;
} else {
return indexA - indexB;
}
}).map((app) => {
const isActive = windows.map((window) => window.app.id).includes(app.id);
const shouldBeShown = (pins.includes(app.id) || isActive);
return (<AppButton
windowsManager={windowsManager}
pins={pins}
app={app}
key={app.id}
active={isActive}
visible={shouldBeShown}
/>);
}), [pins, windows, windowsManager]);
useEffect(() => {
const settings = settingsManager.get(SettingsManager.VIRTUAL_PATHS.taskbar);
void settings.get("pins", (pins) => {
setPins(pins.split(","));
void settings.get("pins", (pinList: string) => {
const pins = pinList.split(",");
const newApps = AppsManager.APPS.sort((appA, appB) => {
const indexA = pins.indexOf(appA.id);
const indexB = pins.indexOf(appB.id);
if (indexA < 0 && indexB > 0) {
return 1;
} else if (indexA > 0 && indexB < 0) {
return -1;
} else if (indexA < 0 && indexB < 0) {
return 0;
} else {
return indexA - indexB;
}
}).map((app) => {
app.isPinned = pins.includes(app.id);
return app;
});
setApps(newApps);
});
}, [settingsManager]);
@ -95,6 +89,7 @@ export const Taskbar = memo(() => {
const updateShowSearch = (show: boolean) => {
setShowSearch(show);
if (show) {
if (searchQuery !== "") {
setSearchQuery("");
@ -126,68 +121,76 @@ export const Taskbar = memo(() => {
updateShowSearch(true);
};
return (<>
<div
style={{ "--taskbar-height": `${TASKBAR_HEIGHT}px`, zIndex } as CSSProperties}
className={styles.Taskbar}
data-allow-context-menu={true}
onContextMenu={(event) => {
if ((event.target as HTMLElement).getAttribute("data-allow-context-menu"))
onContextMenu(event);
}}
>
<div className={styles.MenuIcons}>
<div className={styles.HomeContainer}>
<OutsideClickListener onOutsideClick={() => { updateShowHome(false); }}>
<button
title="Home"
tabIndex={0}
className={`${styles.MenuButton} ${styles.HomeButton}`}
onClick={() => { updateShowHome(!showHome); }}
>
<ReactSVG src={"/icon.svg"}/>
</button>
<HomeMenu active={showHome} setActive={updateShowHome} search={search}/>
</OutsideClickListener>
</div>
<div className={styles.SearchContainer}>
<OutsideClickListener onOutsideClick={() => { updateShowSearch(false); }}>
<button
title="Search"
tabIndex={0}
className={styles.MenuButton}
onClick={() => { updateShowSearch(!showSearch); }}
>
<FontAwesomeIcon icon={faSearch}/>
</button>
<SearchMenu
active={showSearch}
setActive={updateShowSearch}
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
inputRef={inputRef}
/>
</OutsideClickListener>
</div>
return <div
style={{ "--taskbar-height": `${TASKBAR_HEIGHT}px`, zIndex } as CSSProperties}
className={styles.Taskbar}
data-allow-context-menu={true}
onContextMenu={(event) => {
if ((event.target as HTMLElement).getAttribute("data-allow-context-menu"))
onContextMenu(event);
}}
>
<div className={styles.MenuIcons}>
<div className={styles.HomeContainer}>
<OutsideClickListener onOutsideClick={() => { updateShowHome(false); }}>
<button
title="Home"
tabIndex={0}
className={`${styles.MenuButton} ${styles.HomeButton}`}
onClick={() => { updateShowHome(!showHome); }}
>
<ReactSVG src={"/icon.svg"}/>
</button>
<HomeMenu active={showHome} setActive={updateShowHome} search={search}/>
</OutsideClickListener>
</div>
<div className={styles.AppIconsContainer} data-allow-context-menu={true} style={{ boxShadow }}>
<div
className={styles.AppIcons}
data-allow-context-menu={true}
onScroll={onUpdate as unknown as UIEventHandler}
onResize={onUpdate as unknown as ReactEventHandler}
ref={ref}
>
{apps}
</div>
</div>
<div className={styles.UtilIcons}>
<Battery showUtilMenu={showUtilMenu} hideUtilMenus={hideUtilMenus}/>
<Network showUtilMenu={showUtilMenu} hideUtilMenus={hideUtilMenus}/>
<Volume showUtilMenu={showUtilMenu} hideUtilMenus={hideUtilMenus}/>
<Calendar showUtilMenu={showUtilMenu} hideUtilMenus={hideUtilMenus}/>
<button title="Show Desktop" id="desktop-button" onClick={() => { windowsManager.minimizeAll(); }}/>
<div className={styles.SearchContainer}>
<OutsideClickListener onOutsideClick={() => { updateShowSearch(false); }}>
<button
title="Search"
tabIndex={0}
className={styles.MenuButton}
onClick={() => { updateShowSearch(!showSearch); }}
>
<FontAwesomeIcon icon={faSearch}/>
</button>
<SearchMenu
active={showSearch}
setActive={updateShowSearch}
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
inputRef={inputRef}
/>
</OutsideClickListener>
</div>
</div>
</>);
<div className={styles.AppIconsContainer} data-allow-context-menu={true} style={{ boxShadow }}>
<div
className={styles.AppIcons}
data-allow-context-menu={true}
onScroll={onUpdate as unknown as UIEventHandler}
onResize={onUpdate as unknown as ReactEventHandler}
ref={ref}
>
{apps.map((app) => {
const isActive = windows.map((window) => window.app.id).includes(app.id);
const shouldBeShown = (app.isPinned || isActive);
return (<AppButton
windowsManager={windowsManager}
app={app}
key={app.id}
active={isActive}
visible={shouldBeShown}
/>);
})}
</div>
</div>
<div className={styles.UtilIcons}>
<Battery showUtilMenu={showUtilMenu} hideUtilMenus={hideUtilMenus}/>
<Network showUtilMenu={showUtilMenu} hideUtilMenus={hideUtilMenus}/>
<Volume showUtilMenu={showUtilMenu} hideUtilMenus={hideUtilMenus}/>
<Calendar showUtilMenu={showUtilMenu} hideUtilMenus={hideUtilMenus}/>
<button title="Show Desktop" id="desktop-button" onClick={() => { windowsManager.minimizeAll(); }}/>
</div>
</div>;
});

View file

@ -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<AppButtonProps> = memo(({ app, windowsManager, pins, active, visible }: AppButtonProps) => {
const isPinned = pins.includes(app.id);
export const AppButton: FC<AppButtonProps> = memo(({ app, windowsManager, active, visible }: AppButtonProps) => {
const settingsManager = useSettingsManager();
const { onContextMenu } = useContextMenu({ Actions: (props) =>
<Actions avoidTaskbar={false} {...props}>
<ClickAction label={app.name} icon={AppsManager.getAppIconUrl(app.id)} onTrigger={() => {
windowsManager.open(app.id);
}}/>
<ClickAction label={isPinned ? "Unpin from taskbar" : "Pin to taskbar"} icon={faThumbTack} onTrigger={() => {
{/* <ClickAction label={isPinned ? "Unpin from taskbar" : "Pin to taskbar"} icon={faThumbTack} onTrigger={() => {
const newPins = [...pins];
if (isPinned) {
removeFromArray(app.id, pins);
@ -42,7 +39,7 @@ export const AppButton: FC<AppButtonProps> = memo(({ app, windowsManager, pins,
}}/>
{active && <ClickAction label="Close window" icon={faTimes} onTrigger={() => {
windowsManager.close(windowsManager.getAppWindowId(app.id));
}}/>}
}}/>} */}
</Actions>
});

View file

@ -99,7 +99,7 @@ export function HomeMenu({ active, setActive, search }: HomeMenuProps) {
<div className={styles.Apps}>
<h1 className={utilStyles.TextBold}>{NAME}</h1>
<div className={appStyles.AppList}>
{AppsManager.APPS.map(({ name, id }) =>
{AppsManager.APPS.sort((a, b) => a.name.localeCompare(b.name)).map(({ name, id }) =>
<button
key={id}
className={appStyles.AppButton}

View file

@ -4,25 +4,24 @@
flex-direction: column;
left: 0;
bottom: 100%;
height: auto !important;
max-height: 20rem;
overflow: hidden;
}
.SearchMenu {
opacity: 1;
opacity: 0;
display: flex;
gap: 0.5rem;
flex-direction: column-reverse;
flex-direction: column;
min-width: 13rem;
max-width: 19rem;
padding: 0.5rem;
margin-top: 100px;
border-top-left-radius: var(--border-radius-1);
border-top-right-radius: var(--border-radius-1);
border-bottom-right-radius: var(--border-radius-1);
backdrop-filter: var(--taskbar-filter);
transform: none;
transition: opacity 200ms ease-in-out, transform 200ms ease-in-out;
transition: opacity 200ms ease-in-out, margin-top 200ms ease-in-out;
overflow: hidden;
resize: horizontal;
}
@ -39,13 +38,13 @@
z-index: -2;
}
.SearchMenuContainer:not(.Active) {
pointer-events: none;
.SearchMenuContainer.Active .SearchMenu {
opacity: 1;
margin-top: 0px;
}
.SearchMenuContainer:not(.Active) .SearchMenu {
opacity: 0;
transform: translateY(100px);
.SearchMenuContainer:not(.Active) {
pointer-events: none;
}
.SearchMenu > div {

View file

@ -2,10 +2,10 @@ import styles from "./SearchMenu.module.css";
import appStyles from "./AppList.module.css";
import AppsManager from "../../../features/apps/appsManager";
import { useWindowsManager } from "../../../hooks/windows/windowsManagerContext";
import { ReactSVG } from "react-svg";
import { ChangeEventHandler, useEffect, useState } from "react";
import { useKeyboardListener } from "../../../hooks/_utils/keyboard";
import App from "../../../features/apps/app";
import { ReactSVG } from "react-svg";
interface SearchMenuProps {
active: boolean;
@ -32,8 +32,9 @@ export function SearchMenu({ active, setActive, searchQuery, setSearchQuery, inp
}, [inputRef]);
useEffect(() => {
setApps(AppsManager.APPS.filter(({ name }) =>
setApps(AppsManager.APPS.filter(({ name, id }) =>
name.toLowerCase().includes(searchQuery.toLowerCase().trim())
|| id.toLowerCase().includes(searchQuery.toLowerCase().trim())
).sort((a, b) =>
a.name.toLowerCase().localeCompare(b.name.toLowerCase())
));
@ -45,7 +46,7 @@ export function SearchMenu({ active, setActive, searchQuery, setSearchQuery, inp
};
const classNames = [styles.SearchMenuContainer];
if (active && apps)
if (active && apps != null)
classNames.push(styles.Active);
const onKeyDown = (event: KeyboardEvent) => {
@ -64,36 +65,34 @@ export function SearchMenu({ active, setActive, searchQuery, setSearchQuery, inp
useKeyboardListener({ onKeyDown });
return (
<div className={classNames.join(" ")}>
<div className={styles.SearchMenu}>
<input
ref={inputRef}
className={styles.Input}
aria-label="Search query"
tabIndex={tabIndex}
value={searchQuery}
onChange={onChange as unknown as ChangeEventHandler}
spellCheck={false}
placeholder="Search..."
/>
<div className={appStyles.AppList}>
{apps?.map(({ name, id }) =>
<button
key={id}
className={appStyles.AppButton}
tabIndex={tabIndex}
onClick={() => {
setActive(false);
windowsManager.open(id);
}}
>
<ReactSVG src={AppsManager.getAppIconUrl(id)}/>
<p>{name}</p>
</button>
)}
</div>
return <div className={classNames.join(" ")}>
<div className={styles.SearchMenu}>
<div className={appStyles.AppList}>
{apps?.map(({ name, id }) =>
<button
key={id}
className={appStyles.AppButton}
tabIndex={tabIndex}
onClick={() => {
setActive(false);
windowsManager.open(id);
}}
>
<ReactSVG src={AppsManager.getAppIconUrl(id)}/>
<p>{name}</p>
</button>
)}
</div>
<input
ref={inputRef}
className={styles.Input}
aria-label="Search query"
tabIndex={tabIndex}
value={searchQuery}
onChange={onChange as unknown as ChangeEventHandler}
spellCheck={false}
placeholder="Search..."
/>
</div>
);
</div>;
}

View file

@ -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
};

View file

@ -10,6 +10,7 @@ export default class App {
size: Vector2
};
isActive: boolean = false;
isPinned?: boolean;
/**
* @param windowOptions - Default window options

View file

@ -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)
}),