Allow selecting Skyrim folder, more language tweaks

This commit is contained in:
Tyler Hallada 2022-03-15 22:33:44 -04:00
parent 8c30a7bd92
commit 0616a92bbc
5 changed files with 70 additions and 26 deletions

View File

@ -47,12 +47,15 @@ const DataDirPicker: React.FC<Props> = () => {
return (
<>
<p className={styles["no-top-margin"]}>
Select or drag-and-drop your{" "}
Select or drag-and-drop your Skyrim{" "}
<strong>
<code>Data</code>
</strong>{" "}
directory below to load the plugins and see all of the cell edits and
folder below to load the plugins and see all of the cell edits and
conflicts for your current mod load order.
<br />
<br />
The Data folder can be found in the installation directory of the game.
</p>
<input
type="file"

View File

@ -17,6 +17,29 @@ export const DropZone: React.FC<Props> = ({ children, workerPool }) => {
const [entered, setEntered] = useState(0);
const overlay = useRef<HTMLDivElement>(null);
const findPluginsInDirHandle = async (
dirHandle: FileSystemDirectoryHandle & { values: any }
) => {
const plugins: { getFile: () => Promise<File> }[] = [];
const values = dirHandle.values();
// I'm scared of yield and generators so I'm just going to do a lame while loop
while (true) {
const next = await values.next();
if (next.done) {
break;
}
if (next.value.kind === "file" && isPluginPath(next.value.name)) {
plugins.push(next.value);
} else if (
next.value.kind === "directory" &&
next.value.name === "Data"
) {
plugins.push(...(await findPluginsInDirHandle(next.value)));
}
}
return plugins;
};
const handleDropFileSystemHandle = async (
item: DataTransferItem
): Promise<boolean> => {
@ -29,20 +52,9 @@ export const DropZone: React.FC<Props> = ({ children, workerPool }) => {
dispatch(setPluginsTxtAndApplyLoadOrder(await file.text()));
return true;
} else if (entry?.kind === "directory") {
const plugins: { getFile: () => Promise<File> }[] = [];
const values = (
const plugins = await findPluginsInDirHandle(
entry as FileSystemDirectoryHandle & { values: any }
).values();
// I'm scared of yield and generators so I'm just going to do a lame while loop
while (true) {
const next = await values.next();
if (next.done) {
break;
}
if (next.value.kind == "file" && isPluginPath(next.value.name)) {
plugins.push(next.value);
}
}
);
const pluginFiles = await Promise.all(
plugins.map(async (plugin) => plugin.getFile())
);
@ -74,12 +86,26 @@ export const DropZone: React.FC<Props> = ({ children, workerPool }) => {
(resolve, reject) => {
const plugins: FileSystemFileEntry[] = [];
reader.readEntries((entries) => {
let isData = true;
entries.forEach((entry) => {
if (entry?.isFile && isPluginPath(entry.name)) {
plugins.push(entry as FileSystemFileEntry);
} else if (entry?.isDirectory && entry.name === "Data") {
isData = false;
const dataReader = (
entry as FileSystemDirectoryEntry
).createReader();
dataReader.readEntries((entries) => {
entries.forEach((entry) => {
if (entry?.isFile && isPluginPath(entry.name)) {
plugins.push(entry as FileSystemFileEntry);
}
});
resolve(plugins);
});
}
});
if (isData) resolve(plugins);
}, reject);
}
);

View File

@ -33,15 +33,19 @@ const PluginsLoader: React.FC<Props> = () => {
return (
<>
<p>
<p className={styles["top-spacing"]}>
Paste or drag-and-drop your{" "}
<strong>
<code>plugins.txt</code>
</strong>{" "}
below to sort and enable the loaded plugins by your current load order.
<br />
<br />
The plugins.txt file is typically found at{" "}
<strong>
<code>%LOCALAPPDATA%\Skyrim Special Edition\plugins.txt</code>
<code className={styles["break-word"]}>
C:\Users\username\AppData\Local\Skyrim Special Edition
</code>
</strong>
</p>
<button onClick={onPluginsTxtButtonClick} className={styles.button}>
@ -54,16 +58,21 @@ const PluginsLoader: React.FC<Props> = () => {
<p>
The plugins.txt file is typically found at{" "}
<strong>
<code>
<code className={styles["break-word"]}>
C:\Users\username\AppData\Local\Skyrim Special Edition
</code>
</strong>{" "}
(or{" "}
<strong>
<code>%LOCALAPPDATA%\Skyrim Special Edition</code>
<code className={styles["break-word"]}>
%LOCALAPPDATA%\Skyrim Special Edition
</code>
</strong>
) . You can also drag-and-drop the file anywhere on the window to
load the file.
).
<br />
<br />
You can also drag-and-drop the file anywhere on the window to load
the file.
</p>
<textarea
value={editPluginsTxt ?? undefined}

View File

@ -12,9 +12,7 @@ export const excludedPlugins = [
export const isPluginPath = (path: string) => {
if (
path.endsWith(".esp") ||
path.endsWith(".esm") ||
path.endsWith(".esl")
/^((Skyrim Special Edition|Skyrim|SkyrimVR)\/)?(Data\/)?[^/\\]*\.es[mpl]$/i.test(path)
) {
return true;
}
@ -22,7 +20,7 @@ export const isPluginPath = (path: string) => {
}
export const isPlugin = (file: File) => {
return isPluginPath(file.name);
return isPluginPath(file.webkitRelativePath ?? file.name);
}
export const parsePluginFiles = (pluginFiles: File[], workerPool: WorkerPool) => {

View File

@ -25,3 +25,11 @@
.button {
margin-bottom: 24px;
}
.top-spacing {
margin-top: 34px;
}
.break-word {
word-break: break-word;
}