Skip to content

Commit 6cbd7f8

Browse files
committed
Fix tray icon unwrap, clean up store timeouts, fix passphrase dialog UX
- Replace unwrap() on default_window_icon with expect() for clear panic message - Clear debounce timeout in status store stopListening() to prevent leaks - Add cleanup() to disks store to clear unmount timeout, called on destroy - Keep passphrase dialog open while mounting instead of close/reopen flicker - Add submitting state to PassphraseDialog with disabled inputs and loading text
1 parent 8117557 commit 6cbd7f8

5 files changed

Lines changed: 28 additions & 13 deletions

File tree

src-tauri/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ pub fn run() {
110110
.build()?;
111111

112112
let _tray = TrayIconBuilder::new()
113-
.icon(app.default_window_icon().unwrap().clone())
113+
.icon(app.default_window_icon().expect("default window icon must be set in tauri.conf.json").clone())
114114
.icon_as_template(true)
115115
.menu(&menu)
116116
.on_tray_icon_event(|tray, event| {

src/components/DiskList.svelte

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
5555
return () => {
5656
unlisten.then((fn) => fn());
57+
disks.cleanup();
5758
};
5859
});
5960
@@ -78,14 +79,18 @@
7879
const device = passphraseDevice;
7980
const ro = passphraseReadOnly;
8081
const extra = passphraseExtraOptions;
81-
passphraseDevice = null; // Close dialog while mounting
8282
const result = await disks.mount(device, passphrase, ro, extra);
8383
if (result === 'success') {
84+
passphraseDevice = null;
85+
passphraseError = null;
8486
status.refresh();
8587
} else if (result === 'encryption_required') {
86-
// Wrong passphrase — re-show dialog with error
87-
passphraseDevice = device;
88+
// Wrong passphrase — keep dialog open with error
8889
passphraseError = 'Incorrect passphrase. Please try again.';
90+
} else {
91+
// Other error — close dialog, error shown in main banner
92+
passphraseDevice = null;
93+
passphraseError = null;
8994
}
9095
} finally {
9196
submittingPassphrase = false;
@@ -237,6 +242,7 @@
237242
<PassphraseDialog
238243
device={passphraseDevice}
239244
errorMessage={passphraseError}
245+
submitting={submittingPassphrase}
240246
onSubmit={handlePassphraseSubmit}
241247
onCancel={handlePassphraseCancel}
242248
/>

src/components/PassphraseDialog.svelte

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
interface Props {
33
device: string;
44
errorMessage?: string | null;
5+
submitting?: boolean;
56
onSubmit: (passphrase: string) => void;
67
onCancel: () => void;
78
}
89
9-
let { device, errorMessage = null, onSubmit, onCancel }: Props = $props();
10+
let { device, errorMessage = null, submitting = false, onSubmit, onCancel }: Props = $props();
1011
1112
let passphrase = $state('');
1213
let showPassphrase = $state(false);
@@ -20,11 +21,8 @@
2021
2122
function handleSubmit(e: Event) {
2223
e.preventDefault();
23-
if (passphrase.trim()) {
24-
const value = passphrase;
25-
passphrase = '';
26-
showPassphrase = false;
27-
onSubmit(value);
24+
if (passphrase.trim() && !submitting) {
25+
onSubmit(passphrase);
2826
}
2927
}
3028
@@ -65,6 +63,7 @@
6563
autocomplete="off"
6664
autocorrect="off"
6765
spellcheck="false"
66+
disabled={submitting}
6867
/>
6968
<button
7069
type="button"
@@ -78,13 +77,13 @@
7877
</form>
7978
</div>
8079
<div class="dialog-footer">
81-
<button class="btn-secondary" onclick={handleCancel}>Cancel</button>
80+
<button class="btn-secondary" onclick={handleCancel} disabled={submitting}>Cancel</button>
8281
<button
8382
class="btn-primary"
8483
onclick={handleSubmit}
85-
disabled={!passphrase.trim()}
84+
disabled={!passphrase.trim() || submitting}
8685
>
87-
Mount
86+
{submitting ? 'Mounting...' : 'Mount'}
8887
</button>
8988
</div>
9089
</div>

src/lib/stores/disks.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ function createDisksStore() {
138138
},
139139
clearMounting() {
140140
update((s) => ({ ...s, mountingDevice: null }));
141+
},
142+
cleanup() {
143+
if (unmountTimeout) {
144+
clearTimeout(unmountTimeout);
145+
unmountTimeout = null;
146+
}
141147
}
142148
};
143149
}

src/lib/stores/status.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ function createStatusStore() {
9797
pollInterval = setInterval(() => this.refresh(), FALLBACK_POLL_INTERVAL);
9898
},
9999
stopListening() {
100+
if (debounceTimeout) {
101+
clearTimeout(debounceTimeout);
102+
debounceTimeout = null;
103+
}
100104
if (unlisten) {
101105
unlisten();
102106
unlisten = null;

0 commit comments

Comments
 (0)