From 67dc8209331cef513cee67dd549f4341bfc886b7 Mon Sep 17 00:00:00 2001
From: grimsi <9295182+grimsi@users.noreply.github.com>
Date: Sat, 5 Apr 2025 21:46:26 +0200
Subject: [PATCH] Fix for multi-platform compatibility (Windows FS sucks)
---
.run/UI debug.run.xml | 2 +-
.../components/general/input/FileTreeView.tsx | 34 ++++++++---
.../general/modals/LibraryCreationModal.tsx | 2 +-
gameyfin/src/main/frontend/views/TestView.tsx | 2 +-
.../core/filesystem/FilesystemEndpoint.kt | 8 ++-
.../core/filesystem/FilesystemService.kt | 58 +++++++++++++++++--
.../core/filesystem/OperatingSystemType.kt | 8 +++
7 files changed, 96 insertions(+), 18 deletions(-)
create mode 100644 gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/filesystem/OperatingSystemType.kt
diff --git a/.run/UI debug.run.xml b/.run/UI debug.run.xml
index 1a2afd9..ccfbe55 100644
--- a/.run/UI debug.run.xml
+++ b/.run/UI debug.run.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/gameyfin/src/main/frontend/components/general/input/FileTreeView.tsx b/gameyfin/src/main/frontend/components/general/input/FileTreeView.tsx
index 71ec15c..102c16c 100644
--- a/gameyfin/src/main/frontend/components/general/input/FileTreeView.tsx
+++ b/gameyfin/src/main/frontend/components/general/input/FileTreeView.tsx
@@ -5,6 +5,7 @@ import {FilesystemEndpoint} from "Frontend/generated/endpoints";
import FileDto from "Frontend/generated/de/grimsi/gameyfin/core/filesystem/FileDto";
import FileType from "Frontend/generated/de/grimsi/gameyfin/core/filesystem/FileType";
import {IFlatMetadata} from "react-accessible-treeview/dist/TreeView/utils";
+import OperatingSystemType from "Frontend/generated/de/grimsi/gameyfin/core/filesystem/OperatingSystemType";
interface ITreeNode {
id?: NodeId;
@@ -14,7 +15,7 @@ interface ITreeNode {
metadata?: M;
}
-export default function FileTreeView({setSelectedPath}: { setSelectedPath: (file: string) => void }) {
+export default function FileTreeView({onPathChange}: { onPathChange: (file: string) => void }) {
const rootNode: INode = {
id: "root",
name: "",
@@ -22,14 +23,21 @@ export default function FileTreeView({setSelectedPath}: { setSelectedPath: (file
parent: null
}
+ const [hostOSType, setHostOSType] = useState();
const [fileTree, setFileTree] = useState();
const [flattenedFileTree, setFlattenedFileTree] = useState([rootNode]);
useEffect(() => {
- FilesystemEndpoint.listSubDirectories(undefined).then(
+ FilesystemEndpoint.getHostOperatingSystem().then(
+ result => {
+ if (result === undefined) return;
+ setHostOSType(result);
+ }
+ )
+
+ FilesystemEndpoint.listSubDirectories("").then(
result => {
if (result === undefined) return;
- result = result.filter(r => r !== undefined);
const nodes = fileDtosToTree(result as FileDto[]);
const tree = flattenTree(nodes);
setFileTree(nodes);
@@ -39,14 +47,25 @@ export default function FileTreeView({setSelectedPath}: { setSelectedPath: (file
}, []);
function getAbsolutePath(node: INode, path: string = ""): string {
- if (node.parent === null) {
- return path ? `${node.name}/${path}` : node.name;
+ let pathSeparator = "/";
+
+ if (hostOSType === OperatingSystemType.WINDOWS) {
+ pathSeparator = "\\";
+ if (path.startsWith(pathSeparator)) path = path.substring(1);
}
+
+ path = path.replace(`${pathSeparator}${pathSeparator}`, pathSeparator);
+
+ if (node.parent === null) {
+ if (hostOSType === OperatingSystemType.WINDOWS) return path;
+ return `${pathSeparator}${path}`;
+ }
+
const parentNode = flattenedFileTree.find(n => n.id === node.parent);
if (!parentNode) {
throw new Error(`Parent node with id ${node.parent} not found`);
}
- return getAbsolutePath(parentNode, `${node.name}/${path}`);
+ return getAbsolutePath(parentNode, `${node.name}${pathSeparator}${path}`);
}
async function onLoadData({element}: { element: INode }) {
@@ -54,14 +73,13 @@ export default function FileTreeView({setSelectedPath}: { setSelectedPath: (file
let subDirectories = await FilesystemEndpoint.listSubDirectories(absolutePath);
if (subDirectories === undefined) return;
- subDirectories = subDirectories.filter(r => r !== undefined);
const newNodes = fileDtosToNodes(subDirectories as FileDto[]);
const updatedTree = updateTreeWithNewNodes(fileTree!!, element.id, newNodes);
setFileTree(updatedTree);
setFlattenedFileTree(flattenTree(updatedTree));
- setSelectedPath(absolutePath);
+ onPathChange(absolutePath);
}
function updateTreeWithNewNodes(tree: ITreeNode, nodeId: NodeId, newNodes: ITreeNode[]): ITreeNode {
diff --git a/gameyfin/src/main/frontend/components/general/modals/LibraryCreationModal.tsx b/gameyfin/src/main/frontend/components/general/modals/LibraryCreationModal.tsx
index 51472af..39d2098 100644
--- a/gameyfin/src/main/frontend/components/general/modals/LibraryCreationModal.tsx
+++ b/gameyfin/src/main/frontend/components/general/modals/LibraryCreationModal.tsx
@@ -74,7 +74,7 @@ export default function LibraryCreationModal({
/>
{selectedPath}
-
+