diff --git a/src/components/applications/file-explorer/FileExplorer.jsx b/src/components/applications/file-explorer/FileExplorer.jsx index c4c5aab..c0d252f 100644 --- a/src/components/applications/file-explorer/FileExplorer.jsx +++ b/src/components/applications/file-explorer/FileExplorer.jsx @@ -5,34 +5,34 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faArrowUp, faCaretLeft, faCaretRight, faCog, faDesktop, faFileLines, faHouse, faImage, faPlus, faSearch } from "@fortawesome/free-solid-svg-icons"; import { useWindowsManager } from "../../../hooks/windows/windowsManagerContext.js"; import { useContextMenu } from "../../../hooks/modals/contextMenu.js"; -import { useModals } from "../../../hooks/modals/modals.js"; -import { ModalsView } from "../../modals/ModalsView.jsx"; import { QuickAccessButton } from "./QuickAccessButton.jsx"; import { useDialogBox } from "../../../hooks/modals/dialogBox.js"; import Vector2 from "../../../features/math/vector2.js"; import { DIALOG_CONTENT_TYPES } from "../../../constants/modals.js"; import { DirectoryList } from "./directory-list/DirectoryList.jsx"; -export function FileExplorer({ startPath, app }) { +/** + * @param {import("../../windows/WindowView.jsx").windowProps} props + */ +export function FileExplorer({ startPath, app, modalsManager }) { const virtualRoot = useVirtualRoot(); const [currentDirectory, setCurrentDirectory] = useState(virtualRoot.navigate(startPath ?? "~")); const [path, setPath] = useState(currentDirectory?.path ?? ""); const windowsManager = useWindowsManager(); const [showHidden] = useState(true); - const [modalsManager, modals] = useModals(); const { onContextMenu: onContextMenuFile } = useContextMenu({ modalsManager, options: { - "Open": ({ file }) => { windowsManager.openFile(file); }, - "Delete": ({ file }) => { file.delete(); }, + "Open": (file) => { file.open(windowsManager); }, + "Delete": (file) => { file.delete(); }, } }); const { onContextMenu: onContextMenuFolder } = useContextMenu({ modalsManager, options: { - "Open": ({ name }) => { changeDirectory(name); }, - "Delete": ({ name }) => { currentDirectory.findSubFolder(name)?.delete(); } + "Open": (folder) => { changeDirectory(folder.name); }, + "Delete": (folder) => { folder.delete(); } } }); // const { onContextMenu: onNew } = useContextMenu({ @@ -78,7 +78,6 @@ export function FileExplorer({ startPath, app }) { return (
-
{wallpaper diff --git a/src/components/modals/dialog-box/DialogBox.jsx b/src/components/modals/dialog-box/DialogBox.jsx index 6097621..28c30a1 100644 --- a/src/components/modals/dialog-box/DialogBox.jsx +++ b/src/components/modals/dialog-box/DialogBox.jsx @@ -65,10 +65,10 @@ export function DialogBox({ modal, params }) { position={null} scale={1} bounds={{ - top: 0, - bottom: screenHeight - 55, - left: -modal.size.x + 85, - right: screenWidth - 5 + top: -modal.position.y - 1, + bottom: screenHeight - 55 - modal.position.y, + left: -modal.size.x + 85 - modal.position.x, + right: screenWidth - 5 - modal.position.x }} cancel="button" nodeRef={nodeRef} diff --git a/src/components/modals/dialog-box/DialogBox.module.css b/src/components/modals/dialog-box/DialogBox.module.css index 4a67e13..0c92dac 100644 --- a/src/components/modals/dialog-box/DialogBox.module.css +++ b/src/components/modals/dialog-box/DialogBox.module.css @@ -7,9 +7,7 @@ flex-direction: column; min-width: 300px; min-height: 150px; - background-color: var(--background-color-c); - border-radius: 0.5rem; - box-shadow: var(--window-box-shadow); + background-color: var(--background-color-c) !important; resize: both; overflow: hidden; } diff --git a/src/components/windows/WindowView.jsx b/src/components/windows/WindowView.jsx index e2c74f1..2e4e82d 100644 --- a/src/components/windows/WindowView.jsx +++ b/src/components/windows/WindowView.jsx @@ -14,6 +14,17 @@ import { ModalsView } from "../modals/ModalsView.jsx"; import { useContextMenu } from "../../hooks/modals/contextMenu.js"; import AppsManager from "../../features/applications/applications.js"; +/** + * @typedef {object} windowProps + * @property {Application} app + * @property {Function} setTitle + * @property {Function} setIconUrl + * @property {Function} close + * @property {Function} focus + * @property {boolean} active + * @property {import("../../features/modals/modals.js").default} modalsManager + */ + /** * @param {object} props * @param {string} props.id @@ -172,6 +183,7 @@ export const WindowView = memo(({ id, app, size, position, onInteract, options, close={close} focus={focus} active={active} + modalsManager={modalsManager} />
diff --git a/src/constants/applications.js b/src/constants/applications.js index 54b7861..bc27ce5 100644 --- a/src/constants/applications.js +++ b/src/constants/applications.js @@ -4,4 +4,12 @@ export const APPS = { MEDIA_VIEWER: "media-viewer", TEXT_EDITOR: "text-editor", FILE_EXPLORER: "file-explorer" +}; + +export const APP_NAMES = { + TERMINAL: "Commands", + SETTINGS: "Settings", + MEDIA_VIEWER: "Photos", + TEXT_EDITOR: "Notes", + FILE_EXPLORER: "Files" }; \ No newline at end of file diff --git a/src/features/modals/modals.js b/src/features/modals/modals.js index 99cce7f..7b29aa2 100644 --- a/src/features/modals/modals.js +++ b/src/features/modals/modals.js @@ -42,11 +42,11 @@ export default class ModalsManager { modalId = modalId.toString(); if (!this.modalIds.includes(modalId)) { - console.log(`Failed to close modal ${modalId}: modal not found`); + console.warn(`Failed to close modal ${modalId}: modal not found`); return; } - console.log(`Closing modal ${modalId}`); + console.info(`Closing modal ${modalId}`); delete this.modals[modalId]; if (sendModalsUpdate) @@ -60,7 +60,7 @@ export default class ModalsManager { modalId = modalId.toString(); if (!this.modalIds.includes(modalId)) { - console.log(`Failed to focus modal ${modalId}: modal not found`); + console.warn(`Failed to focus modal ${modalId}: modal not found`); return; } diff --git a/src/features/virtual-drive/VirtualFileLink.js b/src/features/virtual-drive/VirtualFileLink.js index 2a3f6eb..ae475fb 100644 --- a/src/features/virtual-drive/VirtualFileLink.js +++ b/src/features/virtual-drive/VirtualFileLink.js @@ -98,6 +98,11 @@ export class VirtualFileLink extends VirtualFile { return this.isValid() ? this.linkedFile.id : null; } + /** @type {VirtualFile["open"]} */ + open(...args) { + if (this.isValid()) return this.linkedFile.open(...args); + } + /** @type {VirtualFile["read"]} */ read(...args) { if (this.isValid()) return this.linkedFile.read(...args); diff --git a/src/features/virtual-drive/VirtualFolderLink.js b/src/features/virtual-drive/VirtualFolderLink.js index f0ccc9b..cb8be1c 100644 --- a/src/features/virtual-drive/VirtualFolderLink.js +++ b/src/features/virtual-drive/VirtualFolderLink.js @@ -130,4 +130,9 @@ export class VirtualFolderLink extends VirtualFolder { getSubFolders(...args) { if (this.isValid()) return this.linkedFolder.getSubFolders(...args); } + + /** @type {VirtualFolder["open"]} */ + open(...args) { + if (this.isValid()) return this.linkedFolder.open(...args); + } } \ No newline at end of file diff --git a/src/features/virtual-drive/virtualBase.js b/src/features/virtual-drive/virtualBase.js index 7cefed0..1248d81 100644 --- a/src/features/virtual-drive/virtualBase.js +++ b/src/features/virtual-drive/virtualBase.js @@ -94,8 +94,6 @@ export class VirtualBase extends EventEmitter { if (!this.canBeEdited) return; - console.log(this); - const parent = this.parent; if (parent == null) diff --git a/src/features/virtual-drive/virtualFile.js b/src/features/virtual-drive/virtualFile.js index 217b7bd..195c3d0 100644 --- a/src/features/virtual-drive/virtualFile.js +++ b/src/features/virtual-drive/virtualFile.js @@ -1,3 +1,4 @@ +import WindowsManager from "../windows/windows.js"; import { VirtualBase } from "./virtualBase.js"; /** @@ -72,6 +73,14 @@ export class VirtualFile extends VirtualBase { return `${this.name}.${this.extension}`; } + /** + * Opens this file in an app associated with its extension + * @param {WindowsManager} windowsManager + */ + open(windowsManager) { + return windowsManager.openFile(this); + } + /** * @returns {Promise} */ diff --git a/src/features/virtual-drive/virtualFolder.js b/src/features/virtual-drive/virtualFolder.js index 7d6d2ee..1fa9638 100644 --- a/src/features/virtual-drive/virtualFolder.js +++ b/src/features/virtual-drive/virtualFolder.js @@ -1,4 +1,6 @@ +import { APPS } from "../../constants/applications.js"; import { removeFromArray } from "../utils/array.js"; +import WindowsManager from "../windows/windows.js"; import { VirtualFileLink } from "./VirtualFileLink.js"; import { VirtualFolderLink } from "./VirtualFolderLink.js"; import { VirtualBase } from "./virtualBase.js"; @@ -339,6 +341,14 @@ export class VirtualFolder extends VirtualBase { } } + /** + * Opens this folder in file explorer + * @param {WindowsManager} windowsManager + */ + open(windowsManager) { + return windowsManager.open(APPS.FILE_EXPLORER, { startPath: this.path }); + } + /** * Deletes this folder and all its files and sub-folders recursively */ diff --git a/src/features/windows/windowsManager.js b/src/features/windows/windows.js similarity index 94% rename from src/features/windows/windowsManager.js rename to src/features/windows/windows.js index 4523e94..ab2c7f1 100644 --- a/src/features/windows/windowsManager.js +++ b/src/features/windows/windows.js @@ -34,7 +34,7 @@ export default class WindowsManager { id = id.toString(); - console.log(`Opening window ${id}:${app.id}`); + console.info(`Opening window ${id}:${app.id}`); this.windows[id] = { id, @@ -56,7 +56,7 @@ export default class WindowsManager { * @returns {object} */ openFile(file, options = {}) { - const app = AppsManager.getFileApp(file.extension); + const app = AppsManager.getFileApp(file?.extension); if (app != null) return this.open(app.id, { file, ...options }); } @@ -72,7 +72,7 @@ export default class WindowsManager { return; } - console.log(`Closing window ${windowId}`); + console.info(`Closing window ${windowId}`); delete this.windows[windowId]; this.updateWindows(this.windows); diff --git a/src/hooks/modals/ContextMenu.js b/src/hooks/modals/ContextMenu.js index c983794..672d475 100644 --- a/src/hooks/modals/ContextMenu.js +++ b/src/hooks/modals/ContextMenu.js @@ -22,6 +22,9 @@ import { useShortcuts } from "../utils/keyboard.js"; export function useContextMenu({ modalsManager, options, shortcuts }) { // Open a new modal when context menu is triggered const onContextMenu = useCallback((event, params = {}) => { + event.preventDefault(); + event.stopPropagation(); + let positionX = (event?.clientX ?? 0); let positionY = (event?.clientY ?? 0); diff --git a/src/hooks/windows/WindowsContext.js b/src/hooks/windows/WindowsContext.js index 697aa47..d1a9556 100644 --- a/src/hooks/windows/WindowsContext.js +++ b/src/hooks/windows/WindowsContext.js @@ -12,7 +12,6 @@ export function WindowsProvider({ children, windowsManager }) { const [windows, setWindows] = useState([]); const updateWindows = useCallback((updatedWindows) => { - // console.log(updatedWindows); setWindows(Object.values(updatedWindows)); }, []); diff --git a/src/hooks/windows/WindowsManagerContext.js b/src/hooks/windows/WindowsManagerContext.js index bf746c4..da0727c 100644 --- a/src/hooks/windows/WindowsManagerContext.js +++ b/src/hooks/windows/WindowsManagerContext.js @@ -1,5 +1,5 @@ import { createContext, useContext } from "react"; -import WindowsManager from "../../features/windows/windowsManager.js"; +import WindowsManager from "../../features/windows/windows.js"; import { WindowsProvider } from "./windowsContext.js"; const WindowsManagerContext = createContext();