Merge develop into main (#25)

* chore(process manager): refactor for generic way to implement cross
platform launchers

* feat(game): game uninstalling & partial compat

* chore(metadata): update metadata

* feat(errors): better download manager errors + modal

* feat(process): better process management, including running state

* feat(downloads): lockless tracking of downloaded chunks

* fix(sign on): add message about nonce expiration

* feat(download ui): add speed and time remaining information

closes #7

Co-authored-by: AdenMGB <140392385+AdenMGB@users.noreply.github.com>

* chore: Ran cargo clippy

Signed-off-by: quexeky <git@quexeky.dev>

* fix(auth initiate): add better error message

* feat(auth): offer manual signin

* feat(install modal): add note about more install dirs

* fix(install flow): clear stale data before requesting new

* Delete pages/library.vue

* Add files via upload

* adds nvm rc!

* feat(install modal): add note about more install dirs

* fix(install flow): clear stale data before requesting new

* Delete pages/library.vue

* Add files via upload

* fix(library page): fix install button

* fix(process): fix poorly designed parsing for executables with spaces

* fix(scrollbars): fix ugly scrollbars on edge webview

* feat(Compat): Implemented spawning with umu (using umu-wrapper-lib)

Signed-off-by: quexeky <git@quexeky.dev>

* feat(process manager): Game kill tauri command

Signed-off-by: quexeky <git@quexeky.dev>

* fix(deep links): Re-enabled deep links

Signed-off-by: quexeky <git@quexeky.dev>

* feat(process): shared child with stop command

* squash(autostart): added adenmgb's autostart feature

Squashed commit of the following:

commit 085cd9481d
Author: Aden Lindsay <140392385+AdenMGB@users.noreply.github.com>
Date:   Mon Dec 30 16:29:41 2024 +1030

    Update lib.rs for the DB sync of autostart

commit 86f2fb19bd
Author: Aden Lindsay <140392385+AdenMGB@users.noreply.github.com>
Date:   Mon Dec 30 16:29:13 2024 +1030

    Update db.rs to accomidate the settings sync

commit ece11e7581
Author: Aden Lindsay <140392385+AdenMGB@users.noreply.github.com>
Date:   Mon Dec 30 16:27:48 2024 +1030

    Update autostart.rs to include DB

commit 7ea8a24fdc
Author: Aden Lindsay <140392385+AdenMGB@users.noreply.github.com>
Date:   Mon Dec 30 15:17:38 2024 +1030

    Add files via upload

commit af2f232d94
Author: Aden Lindsay <140392385+AdenMGB@users.noreply.github.com>
Date:   Mon Dec 30 15:17:09 2024 +1030

    Delete src-tauri/Cargo.toml

commit 5d27b65612
Author: Aden Lindsay <140392385+AdenMGB@users.noreply.github.com>
Date:   Mon Dec 30 15:15:42 2024 +1030

    Add files via upload

commit 2eea7b97a8
Author: Aden Lindsay <140392385+AdenMGB@users.noreply.github.com>
Date:   Mon Dec 30 15:15:31 2024 +1030

    Delete src-tauri/src/lib.rs

commit 9a635a10d1
Author: Aden Lindsay <140392385+AdenMGB@users.noreply.github.com>
Date:   Mon Dec 30 15:14:49 2024 +1030

    Add files via upload

commit 2fb049531a
Author: Aden Lindsay <140392385+AdenMGB@users.noreply.github.com>
Date:   Mon Dec 30 15:13:37 2024 +1030

    Add files via upload

commit ea1be4d750
Author: Aden Lindsay <140392385+AdenMGB@users.noreply.github.com>
Date:   Mon Dec 30 15:13:20 2024 +1030

    Delete pages/settings/index.vue

* fix(download manager): fix incorrect error assumptions & update types

* feat(account settings): Add signout functionality (#16)

* Create account.vue with logout button

* Update auth.rs to add signout command

* Update lib.rs to pass sign_out command to frontend

* feat(settings): add debug page

* Create debug.rs

* Update settings.vue to add tab for debug

* Update main.scss to add light theme

* Update interface.vue to add light mode

* Create debug.vue

* Update debug.vue too add open log button

* Update lib.rs

* Update debug.rs

* Update debug.rs

* Update lib.rs

* Update lib.rs

* Update debug.rs

* Update debug.vue

* fix(debug): refactor and cleanup

* revert(theme): revert light theming

---------

Co-authored-by: DecDuck <declanahofmeyr@gmail.com>

* feat(library ui): add installed ui in the library menu

* chore(tool manager): Progress on adding tools

Going to try changing around the download manager to take a generic trait rather than specifically for game downloads

Signed-off-by: quexeky <git@quexeky.dev>

* refactor(download manager): Moved download manager to separate directory

Signed-off-by: quexeky <git@quexeky.dev>

* refactor(download manager): Added Downloadable trait and replaced references to GameDownloadAgent

Signed-off-by: quexeky <git@quexeky.dev>

* chore(download manager): Renamed most instances of "game" outside of actual game downloads

Signed-off-by: quexeky <git@quexeky.dev>

* refactor(download manager): Renamed GameDonwloadError to ApplicationDownloadError and moved

Signed-off-by: quexeky <git@quexeky.dev>

* chore(download manager): Some easy cleanup of the download manager

Signed-off-by: quexeky <git@quexeky.dev>

* chore(download manager): Ensure that Downloadable is also send and sync

Signed-off-by: quexeky <git@quexeky.dev>

* refactor(download manager): Moved manifest and stored_manifest to download_manager

Signed-off-by: quexeky <git@quexeky.dev>

* Revert "refactor(download manager): Moved manifest and stored_manifest to download_manager"

This reverts commit 8db2393346.

* chore(tool manager): Added ToolDownloadAgent

Signed-off-by: quexeky <git@quexeky.dev>

* chore(download manager): Added manage_queue_signal

Signed-off-by: quexeky <git@quexeky.dev>

* chore(download manager): Added manage_go_signal command

Signed-off-by: quexeky <git@quexeky.dev>

* refactor(download manager): Removed all references to anything outside of the DownloadManager

Signed-off-by: quexeky <git@quexeky.dev>

* refactor(download manager): Fully separate & generic download manager

Signed-off-by: quexeky <git@quexeky.dev>

* refactor(download manager): Removed Arc requirement for DownloadableMetadata

Signed-off-by: quexeky <git@quexeky.dev>

* feat(download manager): Added generic download manager

Signed-off-by: quexeky <git@quexeky.dev>

* fix(game launcher): Renamed game_id to id

Signed-off-by: quexeky <git@quexeky.dev>

* fix(uninstalling): Re-enabled uninstalling apps

Signed-off-by: quexeky <git@quexeky.dev>

* refactor(downloads): Moved all files relevant to game downloads to their own directory

Signed-off-by: quexeky <git@quexeky.dev>

* fix(kill game): Re-enabled killing games

Signed-off-by: quexeky <git@quexeky.dev>

* feat(recovery): Added database recovery

Signed-off-by: quexeky <git@quexeky.dev>

* feat(database): Added database corruption dialog

Signed-off-by: quexeky <git@quexeky.dev>

* chore(README): Updated README.md

Signed-off-by: quexeky <git@quexeky.dev>

* perf(game downloads): Moved some variable declarations outside of the spawned download thread

Signed-off-by: quexeky <git@quexeky.dev>

* fix(game downloads): Accidentally was attempting to lock onto something that was already in scope

Signed-off-by: quexeky <git@quexeky.dev>

* fix(db): Added Settings component

Signed-off-by: quexeky <git@quexeky.dev>

* refactor: Ran cargo clippy & fmt

Signed-off-by: quexeky <git@quexeky.dev>

* chore: More cleanup after cargo clippy

Also added some type efficiency improvements (using references where possible and added SliceDeque crate)

Signed-off-by: quexeky <git@quexeky.dev>

* feat(settings): Added max_download_threads setting and separated settings from db

Signed-off-by: quexeky <git@quexeky.dev>

* chore: Moved generateGameMeta.ts to composables, using PathBuf instead of String for install_dirs

Signed-off-by: quexeky <git@quexeky.dev>

* chore: General cleanup

- Changed some info!() statements to debug!() and warn!()
- Removed most Turbofish syntax cases
- Removed InvalidCodeError and replaced it with InvalidResponse

Signed-off-by: quexeky <git@quexeky.dev>

* chore: Removed tests/

Signed-off-by: quexeky <git@quexeky.dev>

* chore: Removed tools/

Signed-off-by: quexeky <git@quexeky.dev>

* chore: More refining info!() statements

Signed-off-by: quexeky <git@quexeky.dev>

* feat(download manager): Added UI to change download threads

Co-authored-by: AdenMGB <140392385+AdenMGB@users.noreply.github.com>
Signed-off-by: quexeky <git@quexeky.dev>

* fix(metadata): update routes for new server

* fix(handle invalid database): use set_file_name instead of pushing to
strings

* refactor(compat): remove unnecessary compat code (#20)

* Delete pages/settings/compatibility.vue

* Update settings.vue

* Update debug.vue

* Update lib.rs

* Update compat.rs

* feat(debug): use shift or DEBUG RUST_LOG to show Debug Info

* Update settings.vue to have a conditional debug page

* Update debug.rs to add RUST_LOG status fetching

* Implement better error system and segregate errors and commands (#23)

* chore: Progress on amend_settings command

Signed-off-by: quexeky <git@quexeky.dev>

* chore(errors): Progress on better error handling with segragation of files

* chore: Progress on amend_settings command

Signed-off-by: quexeky <git@quexeky.dev>

* chore(commands): Separated commands under each subdirectory into respective commands.rs files

Signed-off-by: quexeky <git@quexeky.dev>

* chore(errors): Almost all errors and commands have been segregated

* chore(errors): Added drop server error

Signed-off-by: quexeky <git@quexeky.dev>

* feat(core): Update to using nightly compiler

Signed-off-by: quexeky <git@quexeky.dev>

* chore(errors): More progress on error handling

Signed-off-by: quexeky <git@quexeky.dev>

* chore(errors): Implementing Try and FromResidual for UserValue

Signed-off-by: quexeky <git@quexeky.dev>

* refactor(errors): Segregated errors and commands from code, and made commands return UserValue struct

Signed-off-by: quexeky <git@quexeky.dev>

* fix(errors): Added missing files

* chore(errors): Convert match statement to map_err

* feat(settings): Implemented settings editing from UI

* feat(errors): Clarified return values from retry_connect command

* chore(errors): Moved autostart commands to autostart.rs

* chore(process manager): Converted launch_process function for games to use game_id

---------

Signed-off-by: quexeky <git@quexeky.dev>

* fix(settings): Broken command invoke logic in settings/downloads.vue

* feat(logging): Added line numbers to file logging and highlighting to console

* chore(progress): Added rolling_progress_updates.rs

Signed-off-by: quexeky <git@quexeky.dev>

* chore(exit): Progress on cleanup and exit

* chore(downloads): Progress on terminator

* chore: Progress on rolling progress window

* feat(progress): Added rolling progress window

Still needs tweaks on specific timings, as well as cleanup

* refactor(remote): Created separate function to generate requests

* fix(install ui): stop loading on error

* fix: fix other metadata endpoints

* feat(errors): Using SerializeDisplay for better error management with Result

* chore: Update .gitlab-ci.yml

* refactor(logging): Using more appropriate logging statements

Still probably needs some work, but that's enough for now

* chore(logging): Imported appropriate logging macros

* Revert "chore: Update .gitlab-ci.yml"

This reverts commit fc6bab9381.

* feat(settings): Allow settings to update UI using fetch_settings command

* style(logging): Ensured that all logs start with lowercase capital and have no trailing punctuation

* fix(download manager): don't crash download manager if multiple errors
come in

* feat(downloads): re-enable checksums

* fix(logs): add file & line to console logs

* fix(ui): modal stack doesn't cover whole app

* feat(database): Ensure that any database issues are resolved by standalone functions

Functions are as follows:
- save_db()
- borrow_db_checked()
- borrow_db_mut_checked()

* chore: Ran cargo clippy & cargo fmt

* fix: assorted fixes

* fix(download agent): fixed completed indexes

* fix: Adding usize to completed_contexts_lock instead of &usize

* fix(game downloads): Added error handling for chunk request errors

* chore: Apply stashed changes

* feat(games): Added multi-argument game launch and setup support

* fix: Games not launching due to string semantics

* build: Version bump & appimage build

* chore: Update .gitlab-ci.yml

* Update .gitlab-ci.yml

* Update .gitlab-ci.yml with artifacts

* feat(settings): Made save button include user feedback & only allow numeric characters

* fix(library): Added "LIbrary Failed to Update" content to recover from library load fail

* fix(logging): Restored RUST_LOG env functionality

* Update changelog.md

---------

Signed-off-by: quexeky <git@quexeky.dev>
Signed-off-by: DecDuck <declanahofmeyr@gmail.com>
Co-authored-by: DecDuck <declanahofmeyr@gmail.com>
Co-authored-by: AdenMGB <140392385+AdenMGB@users.noreply.github.com>
Co-authored-by: seethruhead <shane.keulen@gmail.com>
This commit is contained in:
quexeky
2025-01-25 18:49:54 +11:00
committed by GitHub
parent 6e4ac4ad83
commit f5bd12b43a
96 changed files with 4812 additions and 2538 deletions

136
pages/settings/debug.vue Normal file
View File

@ -0,0 +1,136 @@
<template>
<div class="divide-y divide-zinc-700">
<div class="py-6">
<h2 class="text-base font-semibold font-display leading-7 text-zinc-100">
Debug Information
</h2>
<p class="mt-1 text-sm leading-6 text-zinc-400">
Technical information about your Drop client installation, helpful for
debugging.
</p>
<div class="mt-10 space-y-8">
<div>
<div class="flex items-center gap-x-3">
<FingerPrintIcon class="h-5 w-5 text-zinc-400" />
<h3 class="text-sm font-medium leading-6 text-zinc-100">
Client ID
</h3>
</div>
<p class="mt-2 text-sm text-zinc-400 font-mono ml-8">
{{ clientId || "Not signed in" }}
</p>
</div>
<div>
<div class="flex items-center gap-x-3">
<ComputerDesktopIcon class="h-5 w-5 text-zinc-400" />
<h3 class="text-sm font-medium leading-6 text-zinc-100">
Platform
</h3>
</div>
<p class="mt-2 text-sm text-zinc-400 font-mono ml-8">
{{ platformInfo }}
</p>
</div>
<div>
<div class="flex items-center gap-x-3">
<ServerIcon class="h-5 w-5 text-zinc-400" />
<h3 class="text-sm font-medium leading-6 text-zinc-100">
Server URL
</h3>
</div>
<p class="mt-2 text-sm text-zinc-400 font-mono ml-8">
{{ baseUrl || "Not connected" }}
</p>
</div>
<div>
<div class="flex items-center gap-x-3">
<FolderIcon class="h-5 w-5 text-zinc-400" />
<h3 class="text-sm font-medium leading-6 text-zinc-100">
Data Directory
</h3>
</div>
<p class="mt-2 text-sm text-zinc-400 font-mono ml-8">
{{ dataDir || "Unknown" }}
</p>
</div>
<div class="pt-6 flex gap-x-4">
<button
@click="() => openDataDir()"
type="button"
class="inline-flex items-center gap-x-2 rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
>
<FolderIcon class="h-5 w-5" aria-hidden="true" />
Open Data Directory
</button>
<button
@click="() => openLogFile()"
type="button"
class="inline-flex items-center gap-x-2 rounded-md bg-blue-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
>
<DocumentTextIcon class="h-5 w-5" aria-hidden="true" />
Open Log File
</button>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { invoke } from "@tauri-apps/api/core";
import { platform, type } from "@tauri-apps/plugin-os";
import {
FingerPrintIcon,
TagIcon,
ComputerDesktopIcon,
ServerIcon,
FolderIcon,
CubeIcon,
DocumentTextIcon,
} from "@heroicons/vue/24/outline";
import { open } from "@tauri-apps/plugin-shell";
const clientId = ref<string | null>(null);
const platformInfo = ref("Loading...");
const baseUrl = ref<string | null>(null);
const dataDir = ref<string | null>(null);
const systemData = await invoke<{
clientId: string;
baseUrl: string;
dataDir: string;
}>("fetch_system_data");
console.log(systemData);
clientId.value = systemData.clientId;
baseUrl.value = systemData.baseUrl;
dataDir.value = systemData.dataDir;
const currentPlatform = await platform();
platformInfo.value = currentPlatform;
async function openDataDir() {
if (!dataDir.value) return;
try {
await open(dataDir.value);
} catch (error) {
console.error("Failed to open data dir:", error);
}
}
async function openLogFile() {
if (!dataDir.value) return;
try {
const logPath = `${dataDir.value}/drop.log`;
await open(logPath);
} catch (error) {
console.error("Failed to open log file:", error);
}
}
</script>

View File

@ -59,6 +59,54 @@
</div>
</li>
</ul>
<div class="border-t border-zinc-600 py-6">
<h3 class="text-base font-display font-semibold text-zinc-100">
Download Settings
</h3>
<p class="mt-1 text-sm text-zinc-400 max-w-xl">
Configure how Drop downloads games and other content.
</p>
<div class="mt-6 max-w-xl">
<label for="threads" class="block text-sm font-medium text-zinc-100">
Maximum Download Threads
</label>
<div class="mt-2">
<input
type="number"
name="threads"
id="threads"
min="1"
max="32"
v-model="downloadThreads"
@keypress="validateNumberInput"
@paste="validatePaste"
class="block w-full rounded-md border-0 py-1.5 text-zinc-100 shadow-sm ring-1 ring-inset ring-zinc-700 bg-zinc-800 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6"
/>
</div>
<p class="mt-2 text-sm text-zinc-400">
The maximum number of concurrent download threads. Higher values may
download faster but use more system resources. Default is 4.
</p>
</div>
<div class="mt-6">
<button
type="button"
@click="saveDownloadThreads"
:disabled="saveState.loading"
:class="[
'inline-flex items-center rounded-md px-3 py-2 text-sm font-semibold text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 transition-colors duration-300',
saveState.success
? 'bg-green-600 hover:bg-green-500 focus-visible:outline-green-600'
: 'bg-blue-600 hover:bg-blue-500 focus-visible:outline-blue-600',
'disabled:bg-blue-600/50 disabled:cursor-not-allowed'
]"
>
{{ saveState.success ? 'Saved' : 'Save Changes' }}
</button>
</div>
</div>
</div>
<TransitionRoot as="template" :show="open">
<Dialog class="relative z-50" @close="open = false">
@ -172,6 +220,7 @@ import {
} from "@headlessui/vue";
import { FolderIcon, TrashIcon, XCircleIcon } from "@heroicons/vue/16/solid";
import { invoke } from "@tauri-apps/api/core";
import { type Settings } from "~/types";
const open = ref(false);
const currentDirectory = ref<string | undefined>(undefined);
@ -180,6 +229,14 @@ const createDirectoryLoading = ref(false);
const dirs = ref<Array<string>>([]);
const settings = await invoke<Settings>("fetch_settings");
const downloadThreads = ref(settings?.maxDownloadThreads ?? 4);
const saveState = reactive({
loading: false,
success: false
});
async function updateDirs() {
const newDirs = await invoke<Array<string>>("fetch_download_dir_stats");
dirs.value = newDirs;
@ -213,7 +270,7 @@ async function submitDirectory() {
try {
error.value = undefined;
if (!currentDirectory.value)
throw new Error("Please select a directory first.");
throw new Error("Please select a directory first");
createDirectoryLoading.value = true;
// Add directory
@ -235,4 +292,42 @@ async function deleteDirectory(index: number) {
await invoke("delete_download_dir", { index });
await updateDirs();
}
async function saveDownloadThreads() {
try {
saveState.loading = true;
await invoke("update_settings", {
newSettings: { maxDownloadThreads: downloadThreads.value },
});
// Show success state
saveState.success = true;
// Reset back to normal state after 2 seconds
setTimeout(() => {
saveState.success = false;
}, 2000);
} catch (error) {
console.error('Failed to save settings:', error);
} finally {
saveState.loading = false;
}
}
function validateNumberInput(event: KeyboardEvent) {
// Allow only numbers and basic control keys
if (!/^\d$/.test(event.key) &&
!['Backspace', 'Delete', 'Tab', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
event.preventDefault();
}
}
function validatePaste(event: ClipboardEvent) {
// Prevent paste if content contains non-numeric characters
const pastedData = event.clipboardData?.getData('text');
if (pastedData && !/^\d+$/.test(pastedData)) {
event.preventDefault();
}
}
</script>

View File

@ -1,3 +1,60 @@
<template>
</template>
<div class="divide-y divide-zinc-700">
<div class="py-6">
<h2 class="text-base font-semibold font-display leading-7 text-zinc-100">General</h2>
<p class="mt-1 text-sm leading-6 text-zinc-400">
Configure basic application settings
</p>
<div class="mt-10 space-y-8">
<div class="flex flex-row items-center justify-between">
<div>
<h3 class="text-sm font-medium leading-6 text-zinc-100">Start with system</h3>
<p class="mt-1 text-sm leading-6 text-zinc-400">
Drop will automatically start when you log into your computer
</p>
</div>
<Switch
v-model="autostartEnabled"
:class="[
autostartEnabled ? 'bg-blue-600' : 'bg-zinc-700',
'relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out'
]"
>
<span
:class="[
autostartEnabled ? 'translate-x-5' : 'translate-x-0',
'pointer-events-none relative inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out'
]"
/>
</Switch>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { Switch } from '@headlessui/vue'
import { invoke } from "@tauri-apps/api/core";
defineProps<{}>()
const autostartEnabled = ref<boolean>(false)
// Load initial state
invoke('get_autostart_enabled').then((enabled) => {
autostartEnabled.value = enabled as boolean
})
// Watch for changes and update autostart
watch(autostartEnabled, async (newValue: boolean) => {
try {
await invoke('toggle_autostart', { enabled: newValue })
} catch (error) {
console.error('Failed to toggle autostart:', error)
// Revert the toggle if it failed
autostartEnabled.value = !newValue
}
})
</script>

View File

@ -1,3 +1,7 @@
<template>
</template>
</template>
<script setup lang="ts">
</script>