diff --git a/package-lock.json b/package-lock.json
index 40714b3..11c12ba 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,7 +20,6 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-draggable": "^4.4.5",
- "react-iframe": "^1.8.5",
"react-scripts": "5.0.1",
"react-svg": "^16.1.18",
"web-vitals": "^2.1.4"
@@ -14853,17 +14852,6 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
},
- "node_modules/react-iframe": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/react-iframe/-/react-iframe-1.8.5.tgz",
- "integrity": "sha512-F4cQJGs3ydaG6fJWfuz9yLwOU0Trzl6kttXuUG+vYwosH8enOOFxZWEDQCSbNVO8ayjfYZeqLxEvdvcsSy4GvA==",
- "dependencies": {
- "object-assign": "^4.1.1"
- },
- "peerDependencies": {
- "react": ">=16.x.x"
- }
- },
"node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
diff --git a/package.json b/package.json
index 974ecfc..c1249a3 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,6 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-draggable": "^4.4.5",
- "react-iframe": "^1.8.5",
"react-scripts": "5.0.1",
"react-svg": "^16.1.18",
"web-vitals": "^2.1.4"
@@ -40,20 +39,31 @@
"jsdoc"
],
"rules": {
- "indent": ["error", "tab", { "SwitchCase": 1 }],
+ "indent": [
+ "error",
+ "tab",
+ {
+ "SwitchCase": 1
+ }
+ ],
"semi": "error",
"no-var": "error",
"prefer-const": "error",
- "quotes": ["error", "double"],
-
+ "quotes": [
+ "error",
+ "double"
+ ],
"jsdoc/no-undefined-types": "warn",
"jsdoc/require-param": "warn",
"jsdoc/check-tag-names": "warn",
- "jsdoc/check-types": ["warn", {}],
+ "jsdoc/check-types": [
+ "warn",
+ {}
+ ],
"jsdoc/check-values": "warn",
"jsdoc/empty-tags": "warn",
"jsdoc/check-param-names": "warn",
- "jsdoc/check-property-names": "warn",
+ "jsdoc/check-property-names": "warn",
"jsdoc/check-access": "warn",
"jsdoc/check-alignment": "warn",
"jsdoc/multiline-blocks": "warn",
@@ -63,10 +73,10 @@
"settings": {
"jsdoc": {
"preferredTypes": {
- "Object":"object",
- "object.<>":"Object<>",
- "Object.<>":"Object<>",
- "object<>":"Object<>"
+ "Object": "object",
+ "object.<>": "Object<>",
+ "Object.<>": "Object<>",
+ "object<>": "Object<>"
}
}
}
diff --git a/src/components/applications/.templates/WebView.jsx b/src/components/applications/.templates/WebView.jsx
index f7c8c6f..f39faf9 100644
--- a/src/components/applications/.templates/WebView.jsx
+++ b/src/components/applications/.templates/WebView.jsx
@@ -1,13 +1,47 @@
-import Iframe from "react-iframe";
+import { useCallback, useEffect, useState } from "react";
import styles from "./WebView.module.css";
/**
* @param {Object} props
* @param {String} props.source
- * @returns
*/
export function WebView(props) {
+ const [hovered, setHovered] = useState(false);
+
+ const { source, focus } = props;
+
+ useEffect(() => {
+ window.focus();
+
+ const onBlur = (event) => {
+ if (hovered) {
+ focus(event);
+ }
+ };
+
+ window.addEventListener("blur", onBlur);
+
+ return () => {
+ window.removeEventListener("blur", onBlur);
+ };
+ }, [hovered]);
+
+ const onMouseOver = () => {
+ setHovered(true);
+ };
+
+ const onMouseOut = () => {
+ window.focus();
+ setHovered(false);
+ };
+
return (
-
+
+
+
+
);
}
\ No newline at end of file
diff --git a/src/components/applications/.templates/WebView.module.css b/src/components/applications/.templates/WebView.module.css
index d111fa1..43bee91 100644
--- a/src/components/applications/.templates/WebView.module.css
+++ b/src/components/applications/.templates/WebView.module.css
@@ -1,3 +1,11 @@
+.Container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ height: 100%;
+}
+
.Web-view {
width: 100%;
height: 100%;
diff --git a/src/components/windows/Window.jsx b/src/components/windows/Window.jsx
index 90d001e..3b0f6e6 100644
--- a/src/components/windows/Window.jsx
+++ b/src/components/windows/Window.jsx
@@ -4,10 +4,8 @@ import { faMinus, faWindowMaximize as fasWindowMaximize, faXmark } from "@fortaw
import { ReactSVG } from "react-svg";
import { useWindowsManager } from "../../hooks/windows/WindowsManagerContext.js";
import Draggable from "react-draggable";
-import { useEffect, useRef, useState } from "react";
-
+import { memo, useEffect, useRef, useState } from "react";
import Application from "../../features/applications/application.js";
-
import Vector2 from "../../features/math/vector2.js";
import { faWindowMaximize } from "@fortawesome/free-regular-svg-icons";
@@ -21,7 +19,7 @@ import { faWindowMaximize } from "@fortawesome/free-regular-svg-icons";
* @param {Function} props.onInteract
* @param {object} props.options
*/
-export function Window({ id, app, size, position, focused = false, onInteract, options }) {
+export const Window = memo(function Window({ id, app, size, position, focused = false, onInteract, options }) {
const windowsManager = useWindowsManager();
const nodeRef = useRef(null);
@@ -72,12 +70,15 @@ export function Window({ id, app, size, position, focused = false, onInteract, o
windowsManager.close(id);
};
- const focus = (event) => {
+ const focus = (event, force = false) => {
+ if (force)
+ return onInteract();
+
if (event.defaultPrevented)
return;
- if ((event.target.closest(".Handle") == null || event.target.closest("button") == null))
- onInteract(event);
+ if (event.target?.closest?.(".Handle") == null || event.target?.closest?.("button") == null)
+ onInteract();
};
const classNames = [styles["Window-container"]];
@@ -86,8 +87,11 @@ export function Window({ id, app, size, position, focused = false, onInteract, o
if (minimized)
classNames.push(styles.Minimized);
+ // console.log(`Rendering window: ${id}`);
+
return (
setMinimized(!minimized)}>
-
);
-}
\ No newline at end of file
+});
\ No newline at end of file
diff --git a/src/components/windows/WindowsView.jsx b/src/components/windows/WindowsView.jsx
index a15b6d6..39b88fa 100644
--- a/src/components/windows/WindowsView.jsx
+++ b/src/components/windows/WindowsView.jsx
@@ -1,17 +1,23 @@
import { Window } from "./Window.jsx";
import { useWindows } from "../../hooks/windows/WindowsContext.js";
import { useWindowsManager } from "../../hooks/windows/WindowsManagerContext.js";
+import { useEffect, useState } from "react";
export function WindowsView() {
const windows = useWindows();
const windowsManager = useWindowsManager();
+ const [sortedWindows, setSortedWindows] = useState([]);
+
+ useEffect(() => {
+ setSortedWindows([...windows].sort((windowA, windowB) =>
+ windowA.lastInteraction - windowB.lastInteraction
+ ));
+ }, [windows]);
// TO DO: prevent windows from being rerendered when order is changed
return (
- {windows.sort((windowA, windowB) =>
- windowA.lastInteraction - windowB.lastInteraction
- ).map(({ id, app, size, position, options }) =>
+ {sortedWindows.map(({ id, app, size, position, options }) =>
{ windowsManager.focus(id); }}
id={id}
diff --git a/src/features/applications/applications.js b/src/features/applications/applications.js
index ee8a3f2..2db8b55 100644
--- a/src/features/applications/applications.js
+++ b/src/features/applications/applications.js
@@ -13,7 +13,7 @@ export default class ApplicationsManager {
new Application("Terminal", "terminal", Terminal),
new Application("Settings", "settings", Settings),
// new Application("Browser", "browser"),
- new Application("Calculator", "calculator", Calculator, { size: new Vector2(400, 600) }),
+ // new Application("Calculator", "calculator", Calculator, { size: new Vector2(400, 600) }),
new Application("Text Editor", "text-editor", TextEditor),
// new Application("Code Editor", "code-editor"),
new Application("File Explorer", "file-explorer", FileExplorer),