Allow selecting Skyrim folder, more language tweaks
This commit is contained in:
parent
8c30a7bd92
commit
0616a92bbc
@ -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"
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
});
|
||||
resolve(plugins);
|
||||
if (isData) resolve(plugins);
|
||||
}, reject);
|
||||
}
|
||||
);
|
||||
|
@ -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}
|
||||
|
@ -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) => {
|
||||
|
@ -25,3 +25,11 @@
|
||||
.button {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.top-spacing {
|
||||
margin-top: 34px;
|
||||
}
|
||||
|
||||
.break-word {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user