diff --git a/src/components/modals/_utils/WindowedModal.tsx b/src/components/modals/_utils/WindowedModal.tsx
index 37af621..970247f 100644
--- a/src/components/modals/_utils/WindowedModal.tsx
+++ b/src/components/modals/_utils/WindowedModal.tsx
@@ -1,6 +1,6 @@
import { useEffect, useRef, useState } from "react";
import { useScreenDimensions } from "../../../hooks/_utils/screen";
-import Vector2 from "../../../features/math/vector2";
+import { Vector2 } from "../../../features/math/vector2";
import styles from "./WindowedModal.module.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faXmark } from "@fortawesome/free-solid-svg-icons";
@@ -10,28 +10,22 @@ import utilStyles from "../../../styles/utils.module.css";
import { ModalProps } from "../ModalView";
export function WindowedModal({ modal, params, children, ...props }: ModalProps) {
- const { iconUrl, title } = params;
-
const nodeRef = useRef(null);
- const [startPosition, setStartPosition] = useState(modal.position);
+ const [startPosition, setStartPosition] = useState(modal?.position);
const [screenWidth, screenHeight] = useScreenDimensions();
useEffect(() => {
- if (screenWidth == null || screenHeight == null)
- return;
+ if (screenWidth == null || screenHeight == null) return;
- if (modal.size.x > screenWidth || modal.size.y > screenHeight) {
- setStartPosition(new Vector2(0, 0));
+
+ if (modal?.position != null) {
+ if (modal.position.x > screenWidth) modal.position.x = 0;
+ if (modal.position.y > screenHeight) modal.position.y = 0;
+
+ setStartPosition(modal.position);
} else {
- if (modal.position.x > screenWidth) {
- modal.position.x = 0;
- setStartPosition(modal.position);
- }
- if (modal.position.y > screenHeight) {
- modal.position.y = 0;
- setStartPosition(modal.position);
- }
+ setStartPosition(new Vector2(0, 0));
}
}, [modal, screenHeight, screenWidth]);
@@ -39,13 +33,13 @@ export function WindowedModal({ modal, params, children, ...props }: ModalProps)
axis="both"
handle={".Window-handle"}
defaultPosition={startPosition}
- position={null}
+ position={undefined}
scale={1}
bounds={{
- 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
+ top: -(modal?.position.y ?? 0) - 1,
+ bottom: (screenHeight ?? 0) - 55 - (modal?.position.y ?? 0),
+ left: -(modal?.size.x ?? 0) + 85 - (modal?.position.x ?? 0),
+ right: (screenWidth ?? 0) - 5 - (modal?.position.x ?? 0)
}}
cancel="button"
nodeRef={nodeRef}
@@ -54,18 +48,18 @@ export function WindowedModal({ modal, params, children, ...props }: ModalProps)
className={styles.WindowedModal}
ref={nodeRef}
style={{
- width: modal.size.x,
- height: modal.size.y,
+ width: modal?.size.x ?? 0,
+ height: modal?.size.y ?? 0,
}}
>
-
{title}
+
{params?.title as string}
diff --git a/src/components/modals/dialog-box/DialogBox.tsx b/src/components/modals/dialog-box/DialogBox.tsx
index 55f5931..6baba97 100644
--- a/src/components/modals/dialog-box/DialogBox.tsx
+++ b/src/components/modals/dialog-box/DialogBox.tsx
@@ -6,11 +6,14 @@ import styles from "./DialogBox.module.css";
export function DialogBox({ modal, params, children, ...props }: ModalProps) {
const onClick = (event: MouseEvent) => {
event.preventDefault();
- const type = parseInt((event.target as HTMLElement).getAttribute("data-type"));
+ const attribute = (event.target as HTMLElement).getAttribute("data-type");
+ if (attribute == null) return;
+
+ const type = parseInt(attribute);
switch (type) {
- case DIALOG_CONTENT_TYPES.CloseButton:
- modal.close();
+ case DIALOG_CONTENT_TYPES.closeButton:
+ modal?.close();
break;
}
};
diff --git a/src/components/modals/file-properties/FileProperties.tsx b/src/components/modals/file-properties/FileProperties.tsx
index 6df97e3..6f9ce7a 100644
--- a/src/components/modals/file-properties/FileProperties.tsx
+++ b/src/components/modals/file-properties/FileProperties.tsx
@@ -3,7 +3,7 @@ import { WindowedModal } from "../_utils/WindowedModal";
import styles from "./FileProperties.module.css";
import utilStyles from "../../../styles/utils.module.css";
import { StorageManager } from "../../../features/storage/storageManager";
-import AppsManager from "../../../features/apps/appsManager";
+import { AppsManager } from "../../../features/apps/appsManager";
import { ModalProps } from "../ModalView.js";
import { VirtualFile } from "../../../features/virtual-drive/file";
@@ -12,7 +12,7 @@ interface FilePropetiesProps extends ModalProps {
}
export function FileProperties({ modal, params, file, ...props }: FilePropetiesProps) {
- const associatedApp = AppsManager.getAppByFileExtension(file.extension);
+ const associatedApp = file.extension != null ? AppsManager.getAppByFileExtension(file.extension) : null;
return
@@ -21,15 +21,17 @@ export function FileProperties({ modal, params, file, ...props }: FilePropetiesP
Type: {file.getType()}
-
- Opens with:
-
- {associatedApp.name}
-
+ {associatedApp != null &&
+
+ Opens with:
+
+ {associatedApp.name}
+
+ }
Location: {file.path}
- Size: {StorageManager.getByteSize(file.source ?? file.content)} bytes
+ Size: {StorageManager.getByteSize(file.source ?? file.content as string | null)} bytes
Size on drive: {StorageManager.getByteSize(file.toString())} bytes
diff --git a/src/components/modals/file-selector/FileSelector.tsx b/src/components/modals/file-selector/FileSelector.tsx
index bb26e63..c121fe4 100644
--- a/src/components/modals/file-selector/FileSelector.tsx
+++ b/src/components/modals/file-selector/FileSelector.tsx
@@ -18,8 +18,8 @@ interface FileSelectorProps extends ModalProps {
export function FileSelector({ modal, params, type, allowedFormats, onFinish, ...props }: FileSelectorProps) {
const multi = (type === SELECTOR_MODE.MULTIPLE);
- const [selection, setSelection] = useState(multi ? [] : null);
- const [directory, setDirectory] = useState(null);
+ const [selection, setSelection] = useState(multi ? [] : null);
+ const [directory, setDirectory] = useState(null);
const finish = (event: Event) => {
event?.preventDefault();
@@ -28,19 +28,19 @@ export function FileSelector({ modal, params, type, allowedFormats, onFinish, ..
return;
const files = selection.map((id) => {
- const { name, extension } = VirtualFile.convertId(id);
+ const { name, extension } = VirtualFile.splitId(id);
return directory.findFile(name, extension);
}).filter((file) => {
if (file == null)
return false;
- const validFormat = (allowedFormats == null || allowedFormats.includes(file.extension));
+ const validFormat = (allowedFormats == null || (file.extension != null && allowedFormats.includes(file.extension)));
return validFormat;
- });
+ }) as VirtualFile[];
if (files.length === 0)
return;
- modal.close();
+ modal?.close();
onFinish?.(multi ? files : files[0]);
};
@@ -55,7 +55,7 @@ export function FileSelector({ modal, params, type, allowedFormats, onFinish, ..
{multi
- ? Selected file(s): {selection.join(", ")}
+ ? Selected file(s): {selection != null ? selection.join(", ") : ""}
: Selected file: {selection ?? ""}
}
@@ -63,15 +63,15 @@ export function FileSelector({ modal, params, type, allowedFormats, onFinish, ..
-
}
onSelectionChange={({ files, directory }) => {
- setSelection(files);
- setDirectory(directory);
+ setSelection(files as string[] | null);
+ setDirectory(directory as VirtualFolder);
}}
onSelectionFinish={finish}
/>
diff --git a/src/components/modals/share/Option.tsx b/src/components/modals/share/Option.tsx
index 6c99cc3..5775228 100644
--- a/src/components/modals/share/Option.tsx
+++ b/src/components/modals/share/Option.tsx
@@ -7,7 +7,7 @@ interface OptionProps {
setOption: Function;
}
-export default function Option({ name, label, setOption }: OptionProps) {
+export function Option({ name, label, setOption }: OptionProps) {
const [value, setValue] = useState("");
const onChange = (event: Event) => {
diff --git a/src/components/modals/share/Share.tsx b/src/components/modals/share/Share.tsx
index 5f6114a..5e627e0 100644
--- a/src/components/modals/share/Share.tsx
+++ b/src/components/modals/share/Share.tsx
@@ -1,12 +1,12 @@
-import { ChangeEventHandler, ReactEventHandler, UIEventHandler, useEffect, useRef, useState } from "react";
-import ModalsManager from "../../../features/modals/modalsManager";
+import { ChangeEventHandler, MutableRefObject, ReactEventHandler, UIEventHandler, useEffect, useRef, useState } from "react";
+import { ModalsManager } from "../../../features/modals/modalsManager";
import { WindowedModal } from "../_utils/WindowedModal";
import styles from "./Share.module.css";
import { copyToClipboard, generateUrl } from "../../../features/_utils/browser.utils";
-import AppsManager from "../../../features/apps/appsManager";
+import { AppsManager } from "../../../features/apps/appsManager";
import utilStyles from "../../../styles/utils.module.css";
import { Button } from "../../_utils/button/Button";
-import Option from "./Option";
+import { Option } from "./Option";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faSquare } from "@fortawesome/free-regular-svg-icons";
import { faSquareCheck } from "@fortawesome/free-solid-svg-icons";
@@ -46,15 +46,15 @@ const APP_OPTIONS: Record