mirror of
https://github.com/open-goal/launcher.git
synced 2024-10-20 04:57:38 -04:00
lint: deleting more dead code
This commit is contained in:
parent
4456f114d3
commit
4f9b0dfd62
|
@ -7,7 +7,6 @@
|
|||
import Sidebar from "./components/sidebar/Sidebar.svelte";
|
||||
import Background from "./components/background/Background.svelte";
|
||||
import { appWindow } from "@tauri-apps/api/window";
|
||||
import { log } from "$lib/utils/log";
|
||||
import Header from "./components/header/Header.svelte";
|
||||
import Textures from "./routes/Textures.svelte";
|
||||
import Update from "./routes/Update.svelte";
|
||||
|
@ -53,7 +52,6 @@
|
|||
// Shift+Ctrl F12
|
||||
if (e.code == "F12" && e.ctrlKey && e.shiftKey) {
|
||||
revokeSpecificActions = false;
|
||||
log.info("Hello World - Dev Tools Enabled!");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { getGameTitle, getInternalName, SupportedGame } from "$lib/constants";
|
||||
import { openDir } from "$lib/rpc/commands";
|
||||
import { openDir } from "$lib/rpc/window";
|
||||
import Icon from "@iconify/svelte";
|
||||
import { configDir, join } from "@tauri-apps/api/path";
|
||||
import { createEventDispatcher, onMount } from "svelte";
|
||||
|
|
|
@ -8,7 +8,11 @@
|
|||
import { progressTracker } from "$lib/stores/ProgressStore";
|
||||
import type { Job } from "$lib/jobs/jobs";
|
||||
import { getInternalName, type SupportedGame } from "$lib/constants";
|
||||
import { runCompiler, runDecompiler, updateDataDirectory } from "$lib/rpc/extractor";
|
||||
import {
|
||||
runCompiler,
|
||||
runDecompiler,
|
||||
updateDataDirectory,
|
||||
} from "$lib/rpc/extractor";
|
||||
import { finalizeInstallation } from "$lib/rpc/config";
|
||||
import { generateSupportPackage } from "$lib/rpc/support";
|
||||
|
||||
|
@ -57,7 +61,7 @@
|
|||
progressTracker.init([
|
||||
{
|
||||
status: "queued",
|
||||
label: "Copy Files"
|
||||
label: "Copy Files",
|
||||
},
|
||||
{
|
||||
status: "queued",
|
||||
|
|
|
@ -1,68 +1,21 @@
|
|||
import { log } from "$lib/utils/log";
|
||||
import { invoke } from "@tauri-apps/api/tauri";
|
||||
import { appDir, join } from "@tauri-apps/api/path";
|
||||
|
||||
export async function getHighestSimd(): Promise<string> {
|
||||
try {
|
||||
return await invoke("get_highest_simd");
|
||||
} catch (e) {
|
||||
if (e === "AVXNotSupported") {
|
||||
return "noavx";
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function openDir(dir: string): Promise<void> {
|
||||
try {
|
||||
return await invoke("open_dir", { dir });
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
export async function closeSplashScreen() {
|
||||
try {
|
||||
invoke("close_splashscreen");
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
export async function copyDirectory(source: string, destination: string) {
|
||||
try {
|
||||
return await invoke("copy_dir", { dirSrc: source, dirDest: destination });
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
export async function extractTextures(texturesArray: Array<String>) {
|
||||
try {
|
||||
return await invoke("extract_textures", { texturesArray });
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
export async function getAllTexturePacks() {
|
||||
const textureZipDir = await join(await appDir(), "data/texture_zips/");
|
||||
try {
|
||||
return await invoke("get_all_texture_packs", { dir: textureZipDir });
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
export async function openREPL() {
|
||||
const appDirPath = await appDir();
|
||||
try {
|
||||
return await invoke("open_repl", {
|
||||
projPath: `${appDirPath}data`,
|
||||
currDir: appDirPath,
|
||||
});
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
|
9
src/lib/rpc/window.ts
Normal file
9
src/lib/rpc/window.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { invoke } from "@tauri-apps/api/tauri";
|
||||
|
||||
export async function openDir(dir: string): Promise<void> {
|
||||
try {
|
||||
return await invoke("open_dir", { dir });
|
||||
} catch (e) {
|
||||
console.log(`[OG] Error encountered when trying to open dir - ${dir}`, e);
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
import { Command } from "@tauri-apps/api/shell";
|
||||
import { os } from "@tauri-apps/api";
|
||||
import { resolveErrorCode } from "./setup_errors";
|
||||
import { installLog, log } from "$lib/utils/log";
|
||||
|
||||
// We'll leave this check here since it's the only thing still using a sidecar
|
||||
//
|
||||
// TODO - longterm, we should build this validation checking into the `extractor`
|
||||
// because other things like Vulkan don't have a glewinfo equivalent
|
||||
export async function isOpenGLVersionSupported(
|
||||
version: string
|
||||
): Promise<boolean> {
|
||||
if ((await os.platform()) === "darwin") {
|
||||
console.log("[OG]: MacOS isn't supported, OpenGL won't work here!");
|
||||
return false;
|
||||
}
|
||||
// Otherwise, query for the version
|
||||
let command = Command.sidecar("bin/glewinfo", ["-version", version]);
|
||||
const output = await command.execute();
|
||||
if (output.code === 0) {
|
||||
return true;
|
||||
}
|
||||
log.error("opengl requirement check failed", {
|
||||
version: version,
|
||||
statusCode: output.code,
|
||||
stdout: output.stdout,
|
||||
stderr: output.stderr,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
async function handleErrorCode(code: number, stepName: string) {
|
||||
// isInstalling.update(() => false);
|
||||
// const explaination = await resolveErrorCode(code);
|
||||
// if (explaination === undefined) {
|
||||
// throw new Error(`${stepName} exited with unexpected code: ${code}`);
|
||||
// }
|
||||
// throw new Error(explaination);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
import { fileExists } from "../utils/file";
|
||||
import { appDir, join } from "@tauri-apps/api/path";
|
||||
import { readTextFile } from "@tauri-apps/api/fs";
|
||||
import { log } from "$lib/utils/log";
|
||||
|
||||
interface ErrorCodeMetadataEntry {
|
||||
msg: string;
|
||||
}
|
||||
|
||||
let errorMetadata = new Map<string, ErrorCodeMetadataEntry>();
|
||||
|
||||
export async function resolveErrorCode(
|
||||
code: number
|
||||
): Promise<string | undefined> {
|
||||
if (errorMetadata === undefined || errorMetadata.size == 0) {
|
||||
// first time, load the metadata
|
||||
const errorMetadataPath = await join(
|
||||
await appDir(),
|
||||
"data",
|
||||
"launcher",
|
||||
"error-code-metadata.json"
|
||||
);
|
||||
if (!(await fileExists(errorMetadataPath))) {
|
||||
log.warn("could not locate error metadata file at path", {
|
||||
path: errorMetadataPath,
|
||||
});
|
||||
return undefined;
|
||||
}
|
||||
const jsonData = JSON.parse(await readTextFile(errorMetadataPath));
|
||||
for (var value in jsonData) {
|
||||
errorMetadata.set(value, jsonData[value]);
|
||||
}
|
||||
}
|
||||
|
||||
if (errorMetadata.has(code.toString())) {
|
||||
return errorMetadata.get(code.toString()).msg;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
|
@ -1,24 +1,24 @@
|
|||
import type { VersionFolders } from "$lib/rpc/versions";
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
export interface VersionStoreSelectedInfo {
|
||||
official: string | undefined;
|
||||
unofficial: string | undefined;
|
||||
devel: string | undefined;
|
||||
}
|
||||
|
||||
export interface VersionStoreIFace {
|
||||
activeVersionType: VersionFolders;
|
||||
activeVersionName: string | undefined;
|
||||
selectedVersions: VersionStoreSelectedInfo;
|
||||
}
|
||||
|
||||
export const VersionStore = writable<VersionStoreIFace>({
|
||||
activeVersionType: undefined,
|
||||
activeVersionName: undefined,
|
||||
selectedVersions: {
|
||||
official: undefined,
|
||||
unofficial: undefined,
|
||||
devel: undefined,
|
||||
},
|
||||
});
|
||||
import type { VersionFolders } from "$lib/rpc/versions";
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
export interface VersionStoreSelectedInfo {
|
||||
official: string | undefined;
|
||||
unofficial: string | undefined;
|
||||
devel: string | undefined;
|
||||
}
|
||||
|
||||
export interface VersionStoreIFace {
|
||||
activeVersionType: VersionFolders;
|
||||
activeVersionName: string | undefined;
|
||||
selectedVersions: VersionStoreSelectedInfo;
|
||||
}
|
||||
|
||||
export const VersionStore = writable<VersionStoreIFace>({
|
||||
activeVersionType: undefined,
|
||||
activeVersionName: undefined,
|
||||
selectedVersions: {
|
||||
official: undefined,
|
||||
unofficial: undefined,
|
||||
devel: undefined,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Convert } from "./translation_schema";
|
||||
import type { TranslationSchema } from "./translation_schema";
|
||||
import english from "$assets/translations/english.json";
|
||||
import { log } from "$lib/utils/log";
|
||||
|
||||
let supportedTranslations = ["english"];
|
||||
|
||||
|
@ -9,9 +8,6 @@ export let TranslatedStrings: TranslationSchema;
|
|||
|
||||
export function loadTranslations(language: string) {
|
||||
if (!supportedTranslations.includes(language)) {
|
||||
log.error("Language not supported!", {
|
||||
language: language,
|
||||
});
|
||||
}
|
||||
// TODO - would prefer to import this by a raw path but have to import
|
||||
// for vite reasons -- maybe there is a different way to ensure they are bundled?
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
import { copyDirectory } from "$lib/rpc/commands";
|
||||
import { readTextFile } from "@tauri-apps/api/fs";
|
||||
import { join, appDir, resourceDir } from "@tauri-apps/api/path";
|
||||
import { dirExists, fileExists } from "./file";
|
||||
import { log } from "./log";
|
||||
|
||||
export async function dataDirectoryExists(): Promise<boolean> {
|
||||
return await dirExists(await join(await appDir(), "data"));
|
||||
}
|
||||
|
||||
export async function isDataDirectoryUpToDate(): Promise<boolean> {
|
||||
const resourceDirPath = await resourceDir();
|
||||
const appDirPath = await appDir();
|
||||
// There should be a `metadata.json` which will help us know if the directory is out of date
|
||||
// aka, does the app have updated files compared to what the user has in their appDir.
|
||||
const userMetaPath = await join(appDirPath, "data", "metadata.json");
|
||||
const appMetaPath = await join(resourceDirPath, "data", "metadata.json");
|
||||
if (!(await fileExists(userMetaPath))) {
|
||||
log.warn("couldn't locate user's metadata file at path", {
|
||||
path: userMetaPath,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
// If it's there, read it in and check the version, compare with the app's
|
||||
const userMetaVersion = JSON.parse(await readTextFile(userMetaPath)).version;
|
||||
const appMetaVersion = JSON.parse(await readTextFile(appMetaPath)).version;
|
||||
if (userMetaVersion != appMetaVersion) {
|
||||
log.warn("user version does not match app version", {
|
||||
userVersion: userMetaVersion,
|
||||
appVersion: appMetaVersion,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
// NOTE - the user can of course mess up their directory more, but we can only hold their hands so much
|
||||
// TODO - better to add some sort of "verify local data" feature in the app imo
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function copyDataDirectory(): Promise<boolean> {
|
||||
const resourceDirPath = await resourceDir();
|
||||
const appDirPath = await appDir();
|
||||
|
||||
let src = `${resourceDirPath.replaceAll("\\\\?\\", "")}data`;
|
||||
let dst = `${appDirPath}data`;
|
||||
|
||||
try {
|
||||
await copyDirectory(src, dst);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -46,6 +46,15 @@ export async function saveFilePrompt(
|
|||
});
|
||||
}
|
||||
|
||||
export async function saveFolderPrompt(
|
||||
fileType: string,
|
||||
fileExtensions: string[]
|
||||
): Promise<string | null> {
|
||||
return await save({
|
||||
filters: [{ name: fileType, extensions: fileExtensions }],
|
||||
});
|
||||
}
|
||||
|
||||
export async function isoPrompt(): Promise<string | undefined> {
|
||||
const path = await filePrompt(["ISO", "iso"], "Jak ISO File");
|
||||
if (path === null) {
|
||||
|
|
|
@ -1,203 +0,0 @@
|
|||
import {
|
||||
writeFile,
|
||||
createDir,
|
||||
readTextFile,
|
||||
readDir,
|
||||
} from "@tauri-apps/api/fs";
|
||||
import { logDir, join, dirname, basename } from "@tauri-apps/api/path";
|
||||
import { dirExists, fileExists } from "./file";
|
||||
|
||||
enum LogLevel {
|
||||
Debug = "debug",
|
||||
Info = "info",
|
||||
Warn = "warn",
|
||||
Error = "error",
|
||||
}
|
||||
|
||||
export class Logger {
|
||||
metadata: Object = {};
|
||||
level: LogLevel = LogLevel.Debug;
|
||||
fileNamePrefix: string;
|
||||
|
||||
logFileName: string = undefined;
|
||||
maxFileRotate: number = 10;
|
||||
buffer: string[] = [];
|
||||
flushMillisecondInterval: number = 500;
|
||||
flushImmediately: boolean = false;
|
||||
flushInterval: any;
|
||||
|
||||
constructor(
|
||||
metadata: Object,
|
||||
level: LogLevel,
|
||||
fileNamePrefix: string,
|
||||
flushImmediately: boolean
|
||||
) {
|
||||
this.metadata = metadata;
|
||||
this.level = level;
|
||||
this.fileNamePrefix = fileNamePrefix;
|
||||
this.flushImmediately = flushImmediately;
|
||||
if (!this.flushImmediately) {
|
||||
this.flushInterval = setInterval(
|
||||
this.flushBuffer.bind(this),
|
||||
this.flushMillisecondInterval
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private logMessage(msg: string, level: LogLevel, meta?: Object): string {
|
||||
let val = this.metadata;
|
||||
// Apply provided metadata
|
||||
if (meta !== undefined) {
|
||||
for (const [key, value] of Object.entries(meta)) {
|
||||
val[key] = `${value}`;
|
||||
}
|
||||
}
|
||||
val["level"] = level;
|
||||
val["message"] = msg;
|
||||
val["timestamp"] = new Date().toISOString();
|
||||
return JSON.stringify(val);
|
||||
}
|
||||
|
||||
private async flushBuffer() {
|
||||
if (this.buffer.length > 0) {
|
||||
await this.writeToFile();
|
||||
}
|
||||
this.buffer = [];
|
||||
}
|
||||
|
||||
private async appendToBuffer(logData: string) {
|
||||
if (logData === undefined) {
|
||||
return;
|
||||
}
|
||||
this.buffer.push(logData);
|
||||
// Flush immediately if configured to do so
|
||||
if (this.flushImmediately) {
|
||||
this.flushBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
private async writeToFile() {
|
||||
// If we havn't figured out our log file name yet, figure it out now
|
||||
// This is so we don't have to clear our logs manually, just rotate files
|
||||
if (this.logFileName === undefined) {
|
||||
this.logFileName = await this.rotateLogFile();
|
||||
}
|
||||
|
||||
// Check if the file exists and read it's contents if so
|
||||
const dir = await logDir();
|
||||
const fullPath = await join(dir, this.logFileName);
|
||||
const logExists = await fileExists(fullPath);
|
||||
let contents = "";
|
||||
if (logExists) {
|
||||
contents = await readTextFile(fullPath);
|
||||
if (contents === null || contents === undefined) {
|
||||
contents = "";
|
||||
}
|
||||
} else {
|
||||
await createDir(await dirname(fullPath), { recursive: true });
|
||||
}
|
||||
|
||||
// Build up the string to append and write it
|
||||
this.buffer.forEach((data) => {
|
||||
if (data !== undefined && data !== null) {
|
||||
contents += data + "\n";
|
||||
}
|
||||
});
|
||||
await writeFile({ contents: contents, path: fullPath });
|
||||
}
|
||||
|
||||
private async rotateLogFile(): Promise<string> {
|
||||
const dir = await logDir();
|
||||
const logDirExists = await dirExists(dir);
|
||||
if (!logDirExists) {
|
||||
await createDir(await dirname(dir), { recursive: true });
|
||||
// The directory didn't exist, so it has no files!
|
||||
return `${this.fileNamePrefix}_0.log`;
|
||||
}
|
||||
|
||||
const logFiles = await readDir(dir);
|
||||
let numLogs = 0;
|
||||
let oldestLogIndex = 0;
|
||||
for (let i = 0; i < logFiles.length; i++) {
|
||||
const logFile = logFiles[i];
|
||||
const logFileName = await basename(logFile.path);
|
||||
// prefix_number.log
|
||||
const [prefix, number] = logFileName.split("_");
|
||||
if (prefix === this.fileNamePrefix) {
|
||||
numLogs++;
|
||||
oldestLogIndex = Math.min(oldestLogIndex, parseInt(number));
|
||||
}
|
||||
}
|
||||
if (numLogs > this.maxFileRotate) {
|
||||
return `${this.fileNamePrefix}_${oldestLogIndex}.log`;
|
||||
} else {
|
||||
return `${this.fileNamePrefix}_${numLogs}.log`;
|
||||
}
|
||||
}
|
||||
|
||||
child(meta: Object): Logger {
|
||||
let newLogger = new Logger(
|
||||
this.metadata,
|
||||
this.level,
|
||||
this.fileNamePrefix,
|
||||
this.flushImmediately
|
||||
);
|
||||
let newMeta = this.metadata;
|
||||
for (const [key, value] of Object.entries(meta)) {
|
||||
newMeta[key] = `${value}`;
|
||||
}
|
||||
newLogger.metadata = newMeta;
|
||||
newLogger.logFileName = this.logFileName;
|
||||
return newLogger;
|
||||
}
|
||||
|
||||
debug(msg: string, meta?: Object) {
|
||||
if (this.level <= LogLevel.Debug) {
|
||||
const logData = this.logMessage(msg, LogLevel.Debug, meta);
|
||||
console.log(logData);
|
||||
this.appendToBuffer(logData);
|
||||
}
|
||||
}
|
||||
|
||||
info(msg: string, meta?: Object) {
|
||||
if (this.level <= LogLevel.Info) {
|
||||
const logData = this.logMessage(msg, LogLevel.Info, meta);
|
||||
console.log(logData);
|
||||
this.appendToBuffer(logData);
|
||||
}
|
||||
}
|
||||
|
||||
warn(msg: string, meta?: Object) {
|
||||
if (this.level <= LogLevel.Warn) {
|
||||
const logData = this.logMessage(msg, LogLevel.Warn, meta);
|
||||
console.warn(logData);
|
||||
this.appendToBuffer(logData);
|
||||
}
|
||||
}
|
||||
|
||||
error(msg: string, meta?: Object) {
|
||||
if (this.level <= LogLevel.Error) {
|
||||
const logData = this.logMessage(msg, LogLevel.Error, meta);
|
||||
console.error(logData);
|
||||
this.appendToBuffer(logData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const log = new Logger(
|
||||
{
|
||||
name: "launcher",
|
||||
},
|
||||
LogLevel.Debug,
|
||||
"launcher",
|
||||
false
|
||||
);
|
||||
|
||||
export const installLog = new Logger(
|
||||
{
|
||||
name: "launcher-install",
|
||||
},
|
||||
LogLevel.Debug,
|
||||
"launcher-install",
|
||||
true
|
||||
);
|
|
@ -1,11 +1,6 @@
|
|||
<script>
|
||||
import { openDir } from "$lib/rpc/commands";
|
||||
import { appDir, join } from "@tauri-apps/api/path";
|
||||
import { Alert, Button, Tabs, TabItem } from "flowbite-svelte";
|
||||
import { onMount } from "svelte";
|
||||
import { handleCheckUpdate } from "$lib/utils/updates";
|
||||
import { UpdateStore } from "$lib/stores/AppStore";
|
||||
import { Route, Router, useLocation, useParams } from "svelte-navigator";
|
||||
import { Tabs, TabItem } from "flowbite-svelte";
|
||||
import { useParams } from "svelte-navigator";
|
||||
import General from "./settings/General.svelte";
|
||||
import Folders from "./settings/Folders.svelte";
|
||||
import Versions from "./settings/Versions.svelte";
|
||||
|
@ -13,14 +8,6 @@
|
|||
const params = useParams();
|
||||
$: activeTab = $params["tab"];
|
||||
|
||||
let directory = undefined;
|
||||
let logDir = undefined;
|
||||
|
||||
onMount(async () => {
|
||||
directory = await appDir();
|
||||
logDir = await join(directory, "/logs");
|
||||
});
|
||||
|
||||
const tabItemActiveClasses =
|
||||
"inline-block text-sm font-bold text-center disabled:cursor-not-allowed p-4 text-orange-500 border-b-2 border-orange-500 dark:text-orange-500 dark:border-orange-500";
|
||||
const tabItemInactiveClasses =
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import {
|
||||
getActiveVersion,
|
||||
getActiveVersionFolder,
|
||||
getActiveVersion,
|
||||
getActiveVersionFolder,
|
||||
listDownloadedVersions,
|
||||
openVersionFolder,
|
||||
removeVersion,
|
||||
|
@ -49,7 +49,10 @@
|
|||
}
|
||||
|
||||
async function onSaveVersionChange(evt: any) {
|
||||
await saveActiveVersionChange("devel", $VersionStore.selectedVersions.devel);
|
||||
await saveActiveVersionChange(
|
||||
"devel",
|
||||
$VersionStore.selectedVersions.devel
|
||||
);
|
||||
// TODO if save was successful
|
||||
$VersionStore.activeVersionType = "devel";
|
||||
$VersionStore.activeVersionName = $VersionStore.selectedVersions.devel;
|
||||
|
|
|
@ -79,14 +79,15 @@
|
|||
}
|
||||
|
||||
// Sort releases by published date
|
||||
releases = releases.sort((a, b) =>
|
||||
b.date.localeCompare(a.date)
|
||||
);
|
||||
releases = releases.sort((a, b) => b.date.localeCompare(a.date));
|
||||
versionsLoaded = true;
|
||||
}
|
||||
|
||||
async function saveOfficialVersionChange(evt) {
|
||||
await saveActiveVersionChange("official", $VersionStore.selectedVersions.official);
|
||||
await saveActiveVersionChange(
|
||||
"official",
|
||||
$VersionStore.selectedVersions.official
|
||||
);
|
||||
// TODO if save was successful
|
||||
$VersionStore.activeVersionType = "official";
|
||||
$VersionStore.activeVersionName = $VersionStore.selectedVersions.official;
|
||||
|
@ -106,7 +107,10 @@
|
|||
}
|
||||
}
|
||||
releases = releases;
|
||||
await downloadOfficialVersion(event.detail.version, event.detail.downloadUrl);
|
||||
await downloadOfficialVersion(
|
||||
event.detail.version,
|
||||
event.detail.downloadUrl
|
||||
);
|
||||
// TODO - indicate success or failure (toast)
|
||||
// Then mark it as downloaded
|
||||
for (const release of releases) {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import {
|
||||
getActiveVersion,
|
||||
getActiveVersionFolder,
|
||||
getActiveVersion,
|
||||
getActiveVersionFolder,
|
||||
listDownloadedVersions,
|
||||
openVersionFolder,
|
||||
removeVersion,
|
||||
|
@ -26,7 +26,8 @@
|
|||
$VersionStore.activeVersionType = await getActiveVersionFolder();
|
||||
$VersionStore.activeVersionName = await getActiveVersion();
|
||||
if ($VersionStore.activeVersionType === "unofficial") {
|
||||
$VersionStore.selectedVersions.unofficial = $VersionStore.activeVersionName;
|
||||
$VersionStore.selectedVersions.unofficial =
|
||||
$VersionStore.activeVersionName;
|
||||
}
|
||||
// Check the backend to see if the folder has any versions
|
||||
const installedVersions = await listDownloadedVersions("unofficial");
|
||||
|
@ -50,7 +51,10 @@
|
|||
}
|
||||
|
||||
async function onSaveVersionChange(evt: any) {
|
||||
await saveActiveVersionChange("unofficial", $VersionStore.selectedVersions.unofficial);
|
||||
await saveActiveVersionChange(
|
||||
"unofficial",
|
||||
$VersionStore.selectedVersions.unofficial
|
||||
);
|
||||
// TODO if save was successful
|
||||
$VersionStore.activeVersionType = "unofficial";
|
||||
$VersionStore.activeVersionName = $VersionStore.selectedVersions.unofficial;
|
||||
|
|
|
@ -1,190 +1,194 @@
|
|||
<script lang="ts">
|
||||
import type { VersionFolders } from "$lib/rpc/versions";
|
||||
import { VersionStore, type VersionStoreIFace } from "$lib/stores/VersionStore";
|
||||
import type { ReleaseInfo } from "$lib/utils/github";
|
||||
import Icon from "@iconify/svelte";
|
||||
import {
|
||||
Button,
|
||||
Radio,
|
||||
Spinner,
|
||||
TabItem,
|
||||
Table,
|
||||
TableBody,
|
||||
TableBodyCell,
|
||||
TableBodyRow,
|
||||
TableHead,
|
||||
TableHeadCell,
|
||||
} from "flowbite-svelte";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
export let name: string;
|
||||
export let description: string;
|
||||
export let releaseList: ReleaseInfo[];
|
||||
export let loaded: boolean;
|
||||
export let releaseType: VersionFolders;
|
||||
export let initiallyOpen: boolean;
|
||||
|
||||
const tabItemActiveClasses =
|
||||
"inline-block text-sm font-bold text-center disabled:cursor-not-allowed p-4 text-orange-500 border-b-2 border-orange-500 dark:text-orange-500 dark:border-orange-500";
|
||||
const tabItemInactiveClasses =
|
||||
"inline-block text-sm font-normal text-center disabled:cursor-not-allowed p-4 border-b-2 border-transparent text-gray-400 hover:text-orange-300 hover:border-orange-500 dark:hover:text-orange-300 dark:text-orange-400";
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function changesPending(versionStore: VersionStoreIFace): boolean {
|
||||
return (
|
||||
versionStore.selectedVersions[releaseType] !== undefined &&
|
||||
versionStore.selectedVersions[releaseType] !== "" &&
|
||||
versionStore.selectedVersions[releaseType] !== versionStore.activeVersionName
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<TabItem
|
||||
open={initiallyOpen}
|
||||
activeClasses={tabItemActiveClasses}
|
||||
inactiveClasses={tabItemInactiveClasses}
|
||||
>
|
||||
<span slot="title">{name}</span>
|
||||
{#if !loaded}
|
||||
<div class="flex flex-col justify-center items-center">
|
||||
<Spinner color="yellow" size={"12"} />
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex items-center mb-2">
|
||||
<div class="grow">
|
||||
<p class="text-sm text-gray-400 dark:text-gray-300">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex">
|
||||
{#if changesPending($VersionStore)}
|
||||
<Button
|
||||
btnClass="!p-2 mr-2 rounded-md dark:bg-green-500 hover:dark:bg-green-600 text-slate-900"
|
||||
on:click={() => dispatch("versionChange")}
|
||||
>
|
||||
<Icon
|
||||
icon="material-symbols:save"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="save version change"
|
||||
/>
|
||||
</Button>
|
||||
{/if}
|
||||
<Button
|
||||
btnClass="!p-2 mr-2 rounded-md dark:bg-orange-500 hover:dark:bg-orange-600 text-slate-900"
|
||||
on:click={() => dispatch("refreshVersions")}
|
||||
>
|
||||
<Icon
|
||||
icon="material-symbols:refresh"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="refresh version list"
|
||||
/>
|
||||
</Button>
|
||||
<Button
|
||||
btnClass="!p-2 rounded-md dark:bg-orange-500 hover:dark:bg-orange-600 text-slate-900"
|
||||
on:click={() => dispatch("openVersionFolder")}
|
||||
>
|
||||
<Icon
|
||||
icon="material-symbols:folder-open-rounded"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="open version folder"
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableHeadCell>
|
||||
<span class="sr-only">Select</span>
|
||||
</TableHeadCell>
|
||||
<TableHeadCell>
|
||||
<span class="sr-only">Controls</span>
|
||||
</TableHeadCell>
|
||||
<TableHeadCell>Version</TableHeadCell>
|
||||
<TableHeadCell>Date</TableHeadCell>
|
||||
<TableHeadCell>Changes</TableHeadCell>
|
||||
</TableHead>
|
||||
<TableBody tableBodyClass="divide-y">
|
||||
{#each releaseList as release (release.version)}
|
||||
<TableBodyRow>
|
||||
<TableBodyCell tdClass="px-6 py-2 whitespace-nowrap font-medium">
|
||||
{#if release.isDownloaded}
|
||||
<Radio
|
||||
class="disabled:cursor-not-allowed p-0"
|
||||
bind:group={$VersionStore.selectedVersions[releaseType]}
|
||||
value={release.version}
|
||||
disabled={!release.isDownloaded}
|
||||
name={`${releaseType}-release`}
|
||||
/>
|
||||
{/if}
|
||||
</TableBodyCell>
|
||||
<TableBodyCell
|
||||
tdClass="px-6 py-2 whitespace-nowrap font-medium"
|
||||
style="line-height: 0;"
|
||||
>
|
||||
<Button
|
||||
btnClass="dark:bg-transparent hover:dark:bg-transparent focus:ring-0 focus:ring-offset-0"
|
||||
disabled={release.pendingAction}
|
||||
on:click={async () => {
|
||||
if (release.isDownloaded) {
|
||||
dispatch("removeVersion", { version: release.version });
|
||||
} else {
|
||||
dispatch("downloadVersion", {
|
||||
version: release.version,
|
||||
downloadUrl: release.downloadUrl,
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
{#if release.isDownloaded}
|
||||
<Icon
|
||||
icon="ic:baseline-delete-forever"
|
||||
width="24"
|
||||
height="24"
|
||||
color="red"
|
||||
/>
|
||||
{:else if release.pendingAction}
|
||||
<Spinner color="yellow" size={"6"} />
|
||||
{:else if release.releaseType === "official"}
|
||||
<Icon
|
||||
icon="ic:baseline-download"
|
||||
color="#00d500"
|
||||
width="24"
|
||||
height="24"
|
||||
/>
|
||||
{/if}
|
||||
</Button>
|
||||
</TableBodyCell>
|
||||
<TableBodyCell tdClass="px-6 py-2 whitespace-nowrap font-medium"
|
||||
>{release.version}</TableBodyCell
|
||||
>
|
||||
<TableBodyCell tdClass="px-6 py-2 whitespace-nowrap font-medium">
|
||||
{#if release.date}
|
||||
{new Date(release.date).toLocaleDateString()}
|
||||
{/if}
|
||||
</TableBodyCell>
|
||||
<TableBodyCell tdClass="px-6 py-2 whitespace-nowrap font-medium">
|
||||
{#if release.githubLink}
|
||||
<a
|
||||
class="inline-block"
|
||||
href={release.githubLink}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
><Icon
|
||||
class="inline"
|
||||
icon="mdi:github"
|
||||
width="24"
|
||||
height="24"
|
||||
/></a
|
||||
>
|
||||
{/if}
|
||||
</TableBodyCell>
|
||||
</TableBodyRow>
|
||||
{/each}
|
||||
</TableBody>
|
||||
</Table>
|
||||
{/if}
|
||||
</TabItem>
|
||||
<script lang="ts">
|
||||
import type { VersionFolders } from "$lib/rpc/versions";
|
||||
import {
|
||||
VersionStore,
|
||||
type VersionStoreIFace,
|
||||
} from "$lib/stores/VersionStore";
|
||||
import type { ReleaseInfo } from "$lib/utils/github";
|
||||
import Icon from "@iconify/svelte";
|
||||
import {
|
||||
Button,
|
||||
Radio,
|
||||
Spinner,
|
||||
TabItem,
|
||||
Table,
|
||||
TableBody,
|
||||
TableBodyCell,
|
||||
TableBodyRow,
|
||||
TableHead,
|
||||
TableHeadCell,
|
||||
} from "flowbite-svelte";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
export let name: string;
|
||||
export let description: string;
|
||||
export let releaseList: ReleaseInfo[];
|
||||
export let loaded: boolean;
|
||||
export let releaseType: VersionFolders;
|
||||
export let initiallyOpen: boolean;
|
||||
|
||||
const tabItemActiveClasses =
|
||||
"inline-block text-sm font-bold text-center disabled:cursor-not-allowed p-4 text-orange-500 border-b-2 border-orange-500 dark:text-orange-500 dark:border-orange-500";
|
||||
const tabItemInactiveClasses =
|
||||
"inline-block text-sm font-normal text-center disabled:cursor-not-allowed p-4 border-b-2 border-transparent text-gray-400 hover:text-orange-300 hover:border-orange-500 dark:hover:text-orange-300 dark:text-orange-400";
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function changesPending(versionStore: VersionStoreIFace): boolean {
|
||||
return (
|
||||
versionStore.selectedVersions[releaseType] !== undefined &&
|
||||
versionStore.selectedVersions[releaseType] !== "" &&
|
||||
versionStore.selectedVersions[releaseType] !==
|
||||
versionStore.activeVersionName
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<TabItem
|
||||
open={initiallyOpen}
|
||||
activeClasses={tabItemActiveClasses}
|
||||
inactiveClasses={tabItemInactiveClasses}
|
||||
>
|
||||
<span slot="title">{name}</span>
|
||||
{#if !loaded}
|
||||
<div class="flex flex-col justify-center items-center">
|
||||
<Spinner color="yellow" size={"12"} />
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex items-center mb-2">
|
||||
<div class="grow">
|
||||
<p class="text-sm text-gray-400 dark:text-gray-300">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex">
|
||||
{#if changesPending($VersionStore)}
|
||||
<Button
|
||||
btnClass="!p-2 mr-2 rounded-md dark:bg-green-500 hover:dark:bg-green-600 text-slate-900"
|
||||
on:click={() => dispatch("versionChange")}
|
||||
>
|
||||
<Icon
|
||||
icon="material-symbols:save"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="save version change"
|
||||
/>
|
||||
</Button>
|
||||
{/if}
|
||||
<Button
|
||||
btnClass="!p-2 mr-2 rounded-md dark:bg-orange-500 hover:dark:bg-orange-600 text-slate-900"
|
||||
on:click={() => dispatch("refreshVersions")}
|
||||
>
|
||||
<Icon
|
||||
icon="material-symbols:refresh"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="refresh version list"
|
||||
/>
|
||||
</Button>
|
||||
<Button
|
||||
btnClass="!p-2 rounded-md dark:bg-orange-500 hover:dark:bg-orange-600 text-slate-900"
|
||||
on:click={() => dispatch("openVersionFolder")}
|
||||
>
|
||||
<Icon
|
||||
icon="material-symbols:folder-open-rounded"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="open version folder"
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableHeadCell>
|
||||
<span class="sr-only">Select</span>
|
||||
</TableHeadCell>
|
||||
<TableHeadCell>
|
||||
<span class="sr-only">Controls</span>
|
||||
</TableHeadCell>
|
||||
<TableHeadCell>Version</TableHeadCell>
|
||||
<TableHeadCell>Date</TableHeadCell>
|
||||
<TableHeadCell>Changes</TableHeadCell>
|
||||
</TableHead>
|
||||
<TableBody tableBodyClass="divide-y">
|
||||
{#each releaseList as release (release.version)}
|
||||
<TableBodyRow>
|
||||
<TableBodyCell tdClass="px-6 py-2 whitespace-nowrap font-medium">
|
||||
{#if release.isDownloaded}
|
||||
<Radio
|
||||
class="disabled:cursor-not-allowed p-0"
|
||||
bind:group={$VersionStore.selectedVersions[releaseType]}
|
||||
value={release.version}
|
||||
disabled={!release.isDownloaded}
|
||||
name={`${releaseType}-release`}
|
||||
/>
|
||||
{/if}
|
||||
</TableBodyCell>
|
||||
<TableBodyCell
|
||||
tdClass="px-6 py-2 whitespace-nowrap font-medium"
|
||||
style="line-height: 0;"
|
||||
>
|
||||
<Button
|
||||
btnClass="dark:bg-transparent hover:dark:bg-transparent focus:ring-0 focus:ring-offset-0"
|
||||
disabled={release.pendingAction}
|
||||
on:click={async () => {
|
||||
if (release.isDownloaded) {
|
||||
dispatch("removeVersion", { version: release.version });
|
||||
} else {
|
||||
dispatch("downloadVersion", {
|
||||
version: release.version,
|
||||
downloadUrl: release.downloadUrl,
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
{#if release.isDownloaded}
|
||||
<Icon
|
||||
icon="ic:baseline-delete-forever"
|
||||
width="24"
|
||||
height="24"
|
||||
color="red"
|
||||
/>
|
||||
{:else if release.pendingAction}
|
||||
<Spinner color="yellow" size={"6"} />
|
||||
{:else if release.releaseType === "official"}
|
||||
<Icon
|
||||
icon="ic:baseline-download"
|
||||
color="#00d500"
|
||||
width="24"
|
||||
height="24"
|
||||
/>
|
||||
{/if}
|
||||
</Button>
|
||||
</TableBodyCell>
|
||||
<TableBodyCell tdClass="px-6 py-2 whitespace-nowrap font-medium"
|
||||
>{release.version}</TableBodyCell
|
||||
>
|
||||
<TableBodyCell tdClass="px-6 py-2 whitespace-nowrap font-medium">
|
||||
{#if release.date}
|
||||
{new Date(release.date).toLocaleDateString()}
|
||||
{/if}
|
||||
</TableBodyCell>
|
||||
<TableBodyCell tdClass="px-6 py-2 whitespace-nowrap font-medium">
|
||||
{#if release.githubLink}
|
||||
<a
|
||||
class="inline-block"
|
||||
href={release.githubLink}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
><Icon
|
||||
class="inline"
|
||||
icon="mdi:github"
|
||||
width="24"
|
||||
height="24"
|
||||
/></a
|
||||
>
|
||||
{/if}
|
||||
</TableBodyCell>
|
||||
</TableBodyRow>
|
||||
{/each}
|
||||
</TableBody>
|
||||
</Table>
|
||||
{/if}
|
||||
</TabItem>
|
||||
|
|
Loading…
Reference in a new issue