Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
e718384
test(server): signin handler, IGDB provider, prioritylist edge cases
Jul 26, 2026
9dcdc26
test(cli): upload command | test(desktop): client initialization
Jul 26, 2026
cbd9ae6
fix(sonar): batch mechanical code quality fixes (#69)
Jul 26, 2026
e243fa0
fix(server): SonarCloud real bugs (#68 #74 #79)
Jul 26, 2026
b75fe93
fix(a11y): alt text, labels, status role, and form semantics (#71)
Jul 26, 2026
beb454a
docs: TSDoc pass + AGENTS.md update
Jul 26, 2026
cdd6ffa
refactor: reduce cognitive complexity in auth/session modules (#73 #99)
Jul 27, 2026
b416dde
style: format upload_test.rs with cargo fmt
Jul 27, 2026
5c38e81
fix: address CodeRabbit review findings
Jul 27, 2026
f0ab410
style: format files with prettier
Jul 27, 2026
bd98915
fix: address remaining CodeRabbit findings
Jul 27, 2026
35793a2
style: format EmulatorWidget.vue with prettier
Jul 27, 2026
b176d66
fix: remove unused execSync import
Jul 27, 2026
efb0aa0
fix: session filter returns false when userId/oidc criteria specified…
Jul 27, 2026
11c3a97
fix: harden PATH in exec calls for S4036 compliance
Jul 27, 2026
2181bde
fix: add new keyword to Array() calls for S7723 compliance
Jul 27, 2026
e7beba8
fix: use toSorted() instead of sort() for S4043 compliance
Jul 27, 2026
650756e
fix: replace array index keys with stable identifiers for S6479 compl…
Jul 27, 2026
64e8b13
fix: correct NOSONAR suppression format for OIDC schema URL S5332
Jul 27, 2026
8b8cbe0
fix: rename catch param from response to error_ for S7718 compliance
Jul 27, 2026
f68eacd
fix: use structuredClone instead of JSON.parse(JSON.stringify(...)) f…
Jul 27, 2026
94231f0
fix: remove redundant DropletManifest alias, suppress ObjectReference…
Jul 27, 2026
c8c569d
feat(ci): add SonarCloud PR comment workflow
Jul 27, 2026
d4e7aa0
fix(sonar): format nuxt.config.ts and add NOSONAR comment for PATH sa…
Jul 27, 2026
3760fba
merge: resolve conflicts with develop branch
Jul 27, 2026
5049796
fix(ci): fix top issues table in SonarCloud PR comment
Jul 27, 2026
2e71dc5
style: remove trailing whitespace in sonarcloud-pr-comment.sh
Jul 27, 2026
d180a03
fix: address CodeRabbit findings
Jul 27, 2026
a2c2467
feat(ci): add quality gate conditions to SonarCloud PR JSON summary
Jul 27, 2026
23b278c
fix(ci): filter SonarCloud PR issues by current finding keys
Jul 27, 2026
0e23066
fix(security): replace shell exec with trusted paths, fail closed
Jul 27, 2026
044545b
fix(ci): shellcheck SC2086 fix + prettier formatting + pre-commit hook
Jul 27, 2026
e62a340
fix(ci): run sonar-pr-comment even when scan fails quality gate
Jul 27, 2026
d593ec5
feat(ci): include files needing coverage in SonarCloud PR JSON
Jul 27, 2026
d231be9
fix(ci): simplify sonar-pr-comment condition to just pull_request
Jul 27, 2026
aa23f6e
fix(ci): show all project issues not just PR-introduced ones
Jul 27, 2026
e8096f8
fix(ci): fetch project-wide coverage data for filesNeedingCoverage
Jul 27, 2026
0c6aa5a
fix(ci): use new_coverage/new_uncovered_lines metrics for PR coverage…
Jul 27, 2026
1d2a2dd
test(server): add castManifest unit tests (4 cases)
Jul 27, 2026
1d3ce39
refactor(objects): replace ObjectReference type alias with string
Jul 27, 2026
3f520f3
style: fix JSX spacing, nested ternary, and v-if placement
Jul 27, 2026
2823541
refactor(settings): replace .then() with top-level await
Jul 27, 2026
1c9e6d8
fix: replace single-iteration loop and nested template literal
Jul 27, 2026
dc837a9
fix(versions): remove redundant | undefined from optional types
Jul 27, 2026
f401add
refactor: rename Map() to WorldMap() to avoid built-in name conflict
Jul 27, 2026
2fc7fd5
fix(sponsors): remove dead code after return in CallToAction
Jul 27, 2026
5c08e76
fix(a11y): improve img alt text and table header semantics
Jul 27, 2026
a548a86
fix: resolve 50+ SonarCloud issues across codebase
Jul 27, 2026
f7ec67f
style: format manifest-utils.test.ts with prettier
Jul 27, 2026
18db7f4
fix(lint): unnecessary escape in pcgamingwiki.ts, any type in filter.ts
Jul 27, 2026
b919b3b
fix(ci): revert invalid --ignore-scripts on pnpm exec in e2e.yml
Jul 27, 2026
4dc4cce
fix: address CodeRabbit review findings
Jul 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,25 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash scripts/sonarcloud-sync.sh

sonar-pr-comment:
name: SonarCloud PR Comment
runs-on: ubuntu-latest
needs: sonar
if: github.event_name == 'pull_request'
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 0
- name: Post SonarCloud findings to PR
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
run: bash scripts/sonarcloud-pr-comment.sh

dockerfile:
name: Dockerfile Lint
runs-on: ubuntu-latest
Expand Down
10 changes: 10 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ fallow audit --format json --quiet --explain --gate-marker agent || exit 1

pnpm --filter drop lint-staged && pnpm --filter drop typecheck

# Check shell scripts
changed_sh=$(git diff --cached --name-only --diff-filter=ACM -- '*.sh')
if [ -n "$changed_sh" ]; then
if command -v shellcheck >/dev/null 2>&1; then
echo "$changed_sh" | xargs shellcheck --severity=warning || exit 1
else
echo "shellcheck not installed — skipping shell script checks"
fi
fi

# Check Rust formatting on changed .rs files, filtered by workspace
changed_rs=$(git diff --cached --name-only --diff-filter=ACM -- '*.rs')
if [ -n "$changed_rs" ]; then
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
&& rm -rf /var/lib/apt/lists/*
WORKDIR /build
COPY . .
RUN cargo build --release --manifest-path ./torrential/Cargo.toml
RUN cargo build --locked --release --manifest-path ./torrential/Cargo.toml

### BUILD APP
FROM base AS build-system
Expand All @@ -43,7 +43,7 @@
ENV NUXT_TELEMETRY_DISABLED=1

## add git so drop can determine its git ref at build
RUN apt-get update && apt-get install -y --no-install-recommends git \

Check failure on line 46 in Dockerfile

View workflow job for this annotation

GitHub Actions / Dockerfile Lint

DL3008 warning: Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>`
&& rm -rf /var/lib/apt/lists/*

## copy deps and rest of project files
Expand Down
170 changes: 83 additions & 87 deletions desktop/main/components/GameOptions/ProtonSelector.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
<template>
<Listbox
as="div"
v-model="model.overrideProtonPath"
class="mt-6"
>
<ListboxLabel class="block text-sm/6 font-medium text-white"
>Proton override</ListboxLabel
>
<Listbox as="div" v-model="model.overrideProtonPath" class="mt-6">
<ListboxLabel class="block text-sm/6 font-medium text-white">Proton override</ListboxLabel>
<div class="relative mt-2">
<ListboxButton
class="grid w-full cursor-default grid-cols-1 rounded-md bg-white/5 py-1.5 pr-2 pl-3 text-left text-white outline-1 -outline-offset-1 outline-white/10 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-blue-500 sm:text-sm/6"
>
<span
v-if="currentProtonPath"
class="col-start-1 row-start-1 truncate pr-6"
<span v-if="currentProtonPath" class="col-start-1 row-start-1 truncate pr-6"
>{{ currentProtonPath.name }} ({{ currentProtonPath.path }})</span
>
<span
v-else
class="col-start-1 row-start-1 truncate pr-6 italic text-zinc-400"
<span v-else class="col-start-1 row-start-1 truncate pr-6 italic text-zinc-400"
>No override configured</span
>
<ChevronUpDownIcon
Expand All @@ -35,22 +25,14 @@
<ListboxOptions
class="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-zinc-800 py-1 text-base outline-1 -outline-offset-1 outline-white/10 sm:text-sm"
>
<ListboxOption
as="template"
:value="undefined"
v-slot="{ active, selected }"
>
<ListboxOption as="template" :value="undefined" v-slot="{ active, selected }">
<li
:class="[
active ? 'bg-blue-500 text-white outline-hidden' : 'text-white',
'relative cursor-default py-2 pr-9 pl-3 select-none',
]"
>
<span
:class="[
selected ? 'font-semibold' : 'font-normal',
'block truncate italic',
]"
<span :class="[selected ? 'font-semibold' : 'font-normal', 'block truncate italic']"
>Use global default</span
>

Expand All @@ -65,90 +47,106 @@
</span>
</li>
</ListboxOption>
<h1 class="text-white text-sm font-semibold bg-zinc-900 py-2 px-2">
Auto-discovered
</h1>
<h1 class="text-white text-sm font-semibold bg-zinc-900 py-2 px-2">Auto-discovered</h1>
<template v-if="protonPaths.autodiscovered.length > 0">
<ListboxOption
as="template"
v-for="proton in protonPaths.autodiscovered"
:key="proton.path"
:value="proton.path"
v-slot="{ active, selected }"
>
<li
:class="[
active ? 'bg-blue-500 text-white outline-hidden' : 'text-white',
'relative cursor-default py-2 pr-9 pl-3 select-none',
]"
>
<span :class="[selected ? 'font-semibold' : 'font-normal', 'block truncate']"
>{{ proton.name }} ({{ proton.path }})</span
>

<span
v-if="selected"
:class="[
active ? 'text-white' : 'text-blue-400',
'absolute inset-y-0 right-0 flex items-center pr-4',
]"
>
<CheckIcon class="size-5" aria-hidden="true" />
</span>
</li>
</ListboxOption>
</template>
<ListboxOption
v-else
as="template"
v-if="protonPaths.autodiscovered.length > 0"
v-for="proton in protonPaths.autodiscovered"
:key="proton.path"
:value="proton.path"
v-slot="{ active, selected }"
disabled
:value="null"
v-slot="{ active }"
>
<li
:class="[
active ? 'bg-blue-500 text-white outline-hidden' : 'text-white',
'relative cursor-default py-2 pr-9 pl-3 select-none',
active ? 'bg-zinc-800' : '',
'italic text-zinc-400 py-2 pr-9 pl-3',
]"
>
<span
No auto-discovered layers.
</li>
</ListboxOption>
<h1 class="text-white text-sm font-semibold bg-zinc-900 py-2 px-2">Manually added</h1>
<template v-if="protonPaths.custom.length > 0">
<ListboxOption
as="template"
v-for="proton in protonPaths.custom"
:key="proton.path"
:value="proton.path"
v-slot="{ active, selected }"
>
<li
:class="[
selected ? 'font-semibold' : 'font-normal',
'block truncate',
active ? 'bg-blue-500 text-white outline-hidden' : 'text-white',
'relative cursor-default py-2 pr-9 pl-3 select-none',
]"
>{{ proton.name }} ({{ proton.path }})</span
>
<span :class="[selected ? 'font-semibold' : 'font-normal', 'block truncate']"
>{{ proton.name }} ({{ proton.path }})</span
>

<span
v-if="selected"
:class="[
active ? 'text-white' : 'text-blue-400',
'absolute inset-y-0 right-0 flex items-center pr-4',
]"
>
<CheckIcon class="size-5" aria-hidden="true" />
</span>
</li>
</ListboxOption>
<li v-else class="italic text-zinc-400 py-2 pr-9 pl-3">
No auto-discovered layers.
</li>
<h1 class="text-white text-sm font-semibold bg-zinc-900 py-2 px-2">
Manually added
</h1>
<span
v-if="selected"
:class="[
active ? 'text-white' : 'text-blue-400',
'absolute inset-y-0 right-0 flex items-center pr-4',
]"
>
<CheckIcon class="size-5" aria-hidden="true" />
</span>
</li>
</ListboxOption>
</template>
<ListboxOption
v-else
as="template"
v-if="protonPaths.custom.length > 0"
v-for="proton in protonPaths.custom"
:key="proton.path"
:value="proton.path"
v-slot="{ active, selected }"
disabled
:value="null"
v-slot="{ active }"
>
<li
:class="[
active ? 'bg-blue-500 text-white outline-hidden' : 'text-white',
'relative cursor-default py-2 pr-9 pl-3 select-none',
active ? 'bg-zinc-800' : '',
'italic text-zinc-400 py-2 pr-9 pl-3',
]"
>
<span
:class="[
selected ? 'font-semibold' : 'font-normal',
'block truncate',
]"
>{{ proton.name }} ({{ proton.path }})</span
>

<span
v-if="selected"
:class="[
active ? 'text-white' : 'text-blue-400',
'absolute inset-y-0 right-0 flex items-center pr-4',
]"
>
<CheckIcon class="size-5" aria-hidden="true" />
</span>
No manually added layers.
</li>
</ListboxOption>
<li v-else class="italic text-zinc-400 py-2 pr-9 pl-3">
No manually added layers.
</li>
</ListboxOptions>
</transition>
</div>
<p class="mt-2 text-sm text-zinc-400" id="launch-description">
Override the Proton layer used to launch this game. You can add or remove
your custom Proton layer paths in
Override the Proton layer used to launch this game. You can add or remove your custom Proton
layer paths in
<PageWidget to="/settings/compat">
<WrenchIcon class="size-3" />
Settings </PageWidget
Expand Down Expand Up @@ -181,9 +179,7 @@ const protonPaths = await invoke<{
}>("fetch_proton_paths");
const currentProtonPath = computed(
() =>
protonPaths.autodiscovered.find(
(v) => v.path == model.value.overrideProtonPath,
) ??
protonPaths.autodiscovered.find((v) => v.path == model.value.overrideProtonPath) ??
protonPaths.custom.find((v) => v.path == model.value.overrideProtonPath),
);
</script>
2 changes: 1 addition & 1 deletion desktop/main/composables/current-page-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const useCurrentNavigationIndex = (
.map((e, i) => ({ ...e, index: i }))
.filter((e) => to.fullPath.startsWith(e.prefix));
const bestOption = validOptions
.sort((a, b) => b.route.length - a.route.length)
.toSorted((a, b) => b.route.length - a.route.length)
.at(0);

return bestOption?.index ?? -1;
Expand Down
17 changes: 8 additions & 9 deletions desktop/main/pages/settings/index.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
<template>
<div class="border-b border-zinc-700 py-5">
<h3 class="text-base font-semibold font-display leading-6 text-zinc-100">
General
</h3>
<h3 class="text-base font-semibold font-display leading-6 text-zinc-100">General</h3>
</div>

<div class="mt-5 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>
<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>
Expand Down Expand Up @@ -42,9 +38,12 @@ defineProps<{}>();
const autostartEnabled = ref<boolean>(false);

// Load initial state
invoke("get_autostart_enabled").then((enabled) => {
autostartEnabled.value = enabled as boolean;
});
try {
const initialAutostart = await invoke<boolean>("get_autostart_enabled");
autostartEnabled.value = initialAutostart;
} catch {
// Keep default false if IPC fails
}

// Watch for changes and update autostart
watch(autostartEnabled, async (newValue: boolean) => {
Expand Down
Loading
Loading