Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
41 changes: 21 additions & 20 deletions cmd/opensave-app/frontend/src/App.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script>
import { t as translateUI } from './lib/i18n.js';
import { onMount, onDestroy } from 'svelte';
import { pageOut } from './lib/motion.js';
import { initApi, connectWS, native } from './lib/api.js';
Expand Down Expand Up @@ -111,13 +112,13 @@
const { now, fresh } = newlyEmptied(emptiedBefore, all);
emptiedBefore = now;
for (const g of fresh) {
toast(`Every save file of ${g.name} was deleted here. Your other devices keep theirs until you choose.`, 'warning', {
toast($translateUI('app.everySaveFileOfWasDeletedHere', { p0: g.name }), 'warning', {
ttl: 15000,
action: { label: 'Choose', run: () => navigate('game', { gameId: g.id }) }
action: { label: $translateUI('app.choose'), run: () => navigate('game', { gameId: g.id }) }
});
demandAttention('emptied', {
title: g.name,
body: 'Every save file was deleted here. Your other devices keep theirs until you choose.',
body: $translateUI('app.everySaveFileWasDeletedHereYour'),
game: g
});
}
Expand Down Expand Up @@ -198,45 +199,45 @@
<div class="update-banner installing">
<span class="with-icon">
{#if $appUpdate.state === 'downloading'}
<Download size={16} /> Updating OpenSave — downloading {$appUpdate.percentage ?? 0}%…
<Download size={16} /> {$translateUI('app.updatingOpenSaveDownloading')} {$appUpdate.percentage ?? 0}%…
{:else if $appUpdate.state === 'installing'}
<Wrench size={16} /> Installing update…
<Wrench size={16} /> {$translateUI('app.installingUpdate')}
{:else}
<RefreshCw size={16} /> Restarting with the new version…
<RefreshCw size={16} /> {$translateUI('app.restartingWithTheNewVersion')}
{/if}
<em>The app restarts itself when done — your games keep syncing.</em>
<em>{$translateUI('app.theAppRestartsItselfWhenDone')}</em>
</span>
</div>
{:else if update}
<div class="update-banner">
<span class="with-icon"><Sparkles size={16} /> OpenSave {update.latest} is available — you're on {update.current}.</span>
<span class="with-icon"><Sparkles size={16} /> OpenSave {update.latest} {$translateUI('app.isAvailableYouReOn')} {update.current}.</span>
<div class="update-actions">
{#if update.notes}
<button class="btn small ghost" on:click={() => (showNotes = !showNotes)}>
{showNotes ? 'Hide notes' : "What's new"}
{showNotes ? $translateUI('app.hideNotes') : $translateUI('app.whatSNew')}
</button>
{/if}
{#if update.assetUrl}
<button class="btn small primary" disabled={installStarted} on:click={installRelease}>
{installStarted ? 'Starting…' : 'Install & restart'}
{installStarted ? $translateUI('app.starting') : $translateUI('app.installRestart')}
</button>
{:else if update.flatpak}
<button class="btn small primary" on:click={() => native.openExternal(update.url)}>Get .flatpak</button>
<button class="btn small primary" on:click={() => native.openExternal(update.url)}>{$translateUI('app.getFlatpak')}</button>
{:else}
<button class="btn small primary" on:click={() => native.openExternal(update.url)}>Download</button>
<button class="btn small primary" on:click={() => native.openExternal(update.url)}>{$translateUI('app.download')}</button>
{/if}
<button class="btn small ghost icon" on:click={() => (update = null)} aria-label="Dismiss" title="Dismiss"><X size={15} /></button>
<button class="btn small ghost icon" on:click={() => (update = null)} aria-label="{$translateUI('common.dismiss')}" title="{$translateUI('common.dismiss')}"><X size={15} /></button>
</div>
</div>
{#if showNotes && update.notes}
<div class="update-notes">{update.notes}</div>
{/if}
{:else if updatedTo}
<div class="update-banner">
<span class="with-icon"><Sparkles size={16} /> OpenSave was updated to v{updatedTo}.</span>
<span class="with-icon"><Sparkles size={16} /> {$translateUI('app.openSaveWasUpdatedToV')}{updatedTo}.</span>
<div class="update-actions">
<button class="btn small primary" on:click={openWhatsNew}>What's new</button>
<button class="btn small ghost icon" on:click={() => (updatedTo = '')} aria-label="Dismiss" title="Dismiss"><X size={15} /></button>
<button class="btn small primary" on:click={openWhatsNew}>{$translateUI('app.whatSNew')}</button>
<button class="btn small ghost icon" on:click={() => (updatedTo = '')} aria-label="{$translateUI('common.dismiss')}" title="{$translateUI('common.dismiss')}"><X size={15} /></button>
</div>
</div>
{/if}
Expand All @@ -252,13 +253,13 @@
{#if bootError}
<div class="boot-error">
<img class="boot-logo" src={logoUrl} alt="OpenSave" />
<h2>OpenSave failed to start</h2>
<h2>{$translateUI('app.openSaveFailedToStart')}</h2>
<p>{bootError}</p>
<button class="btn primary" disabled={retrying} on:click={boot}>
{retrying ? 'Retrying…' : 'Retry'}
{retrying ? $translateUI('app.retrying') : $translateUI('app.retry')}
</button>
<p class="boot-hint">
Details are saved to <code>.opensave\opensave.log</code> in your user folder.
{$translateUI('app.detailsAreSavedTo')} <code>.opensave\opensave.log</code> {$translateUI('app.inYourUserFolder')}
</p>
</div>
{:else if ready}
Expand Down Expand Up @@ -290,7 +291,7 @@
{:else}
<div class="boot-loading">
<img class="boot-logo pulse" src={logoUrl} alt="OpenSave" />
<span>Starting OpenSave…</span>
<span>{$translateUI('app.startingOpenSave')}</span>
</div>
{/if}
</div>
Expand Down
18 changes: 9 additions & 9 deletions cmd/opensave-app/frontend/src/components/AboutModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import { navigate } from '../lib/stores.js';
import { backdropClose } from '../lib/backdrop.js';
import { DISCORD_URL, GITHUB_URL } from '../lib/links.js';
import { t } from '../lib/i18n.js';
import { t as translateUI } from '../lib/i18n.js';
import logoUrl from '../assets/logo.png';
import X from 'lucide-svelte/icons/x';
import ExternalLink from 'lucide-svelte/icons/external-link';
Expand Down Expand Up @@ -40,33 +40,33 @@
<svelte:window on:keydown={onKeydown} />

<div class="backdrop" use:backdropClose={onClose} role="presentation" out:dialogOut|global>
<div class="modal" role="dialog" aria-modal="true" aria-label={$t('about.title')}>
<button class="btn ghost icon x" on:click={onClose} title={$t('common.close')} aria-label={$t('common.close')}><X size={18} /></button>
<div class="modal" role="dialog" aria-modal="true" aria-label={$translateUI('about.title')}>
<button class="btn ghost icon x" on:click={onClose} title={$translateUI('common.close')} aria-label={$translateUI('common.close')}><X size={18} /></button>
<img class="logo" src={logoUrl} alt="" />
<h2>{info?.name ?? 'OpenSave'}</h2>
<div class="ver">
{$t('about.version', { version: info?.version ?? '—' })}{#if buildLabel}<span class="build">{$t('about.builtAt', { time: buildLabel })}</span>{/if}
{$translateUI('about.version', { version: info?.version ?? '—' })}{#if buildLabel}<span class="build">{$translateUI('about.builtAt', { time: buildLabel })}</span>{/if}
</div>
<p class="tagline">{info?.tagline ?? ''}</p>

<div class="meta">
<div><span>{$t('about.license')}</span> {info?.license ?? 'MIT'}</div>
<div><span>{$t('about.builtWith')}</span> {info?.tech ?? 'Go + Wails'}</div>
<div><span>{$translateUI('about.license')}</span> {info?.license ?? 'MIT'}</div>
<div><span>{$translateUI('about.builtWith')}</span> {info?.tech ?? 'Go + Wails'}</div>
</div>

<div class="links">
<button class="btn small discord" on:click={() => native.openExternal(DISCORD_URL)}>
<svg viewBox="0 0 24 18" width="16" height="12" fill="currentColor" aria-hidden="true">
<path d="M20.32 1.53A19.8 19.8 0 0 0 15.43 0c-.21.38-.46.9-.63 1.31a18.3 18.3 0 0 0-5.6 0C9.03.9 8.77.38 8.56 0A19.74 19.74 0 0 0 3.67 1.53C.57 6.19-.27 10.73.15 15.21A19.9 19.9 0 0 0 6.18 18c.49-.66.92-1.37 1.29-2.11-.71-.27-1.39-.6-2.03-.98.17-.13.34-.26.5-.4a14.2 14.2 0 0 0 12.12 0c.16.14.33.27.5.4-.64.38-1.32.71-2.03.98.37.74.8 1.45 1.29 2.11a19.87 19.87 0 0 0 6.03-2.79c.5-5.19-.84-9.69-3.53-13.68ZM8.02 12.46c-1.18 0-2.15-1.08-2.15-2.4s.95-2.4 2.15-2.4c1.2 0 2.17 1.09 2.15 2.4 0 1.32-.95 2.4-2.15 2.4Zm7.96 0c-1.18 0-2.15-1.08-2.15-2.4s.95-2.4 2.15-2.4c1.2 0 2.17 1.09 2.15 2.4 0 1.32-.95 2.4-2.15 2.4Z" />
</svg>
{$t('about.joinDiscord')}
{$translateUI('about.joinDiscord')}
</button>
<button class="btn small" on:click={() => native.openExternal(GITHUB_URL)}>GitHub<ExternalLink size={13} /></button>
<button class="btn small" on:click={openChangelog}><ScrollText size={14} />{$t('about.changelog')}</button>
<button class="btn small" on:click={openChangelog}><ScrollText size={14} />{$translateUI('about.changelog')}</button>
</div>

<p class="copy">{info?.copyright ?? ''}</p>
<p class="note">{$t('about.note')}</p>
<p class="note">{$translateUI('about.note')}</p>
</div>
</div>

Expand Down
20 changes: 10 additions & 10 deletions cmd/opensave-app/frontend/src/components/CollectionsDialog.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Trash2 from 'lucide-svelte/icons/trash-2';
import Plus from 'lucide-svelte/icons/plus';
import Modal from './ui/Modal.svelte';
import { t } from '../lib/i18n.js';
import { t as translateUI } from '../lib/i18n.js';
import ModalFoot from './ui/ModalFoot.svelte';
import { askConfirm } from '../lib/stores.js';
import { collectionsDialog } from '../lib/gameactions.js';
Expand Down Expand Up @@ -46,14 +46,14 @@

async function remove(c) {
const n = c.gameIds.length;
const body = $t('collections.deleteConfirmBody', { name: c.name }) + ' ' + (n ? $t('collections.deleteConfirmGames', { n }) : $t('collections.deleteConfirmEmpty'));
if (!(await askConfirm(body, { title: $t('collections.deleteConfirmTitle'), confirmText: $t('common.delete'), danger: true }))) return;
const body = $translateUI('collections.deleteConfirmBody', { name: c.name }) + ' ' + (n ? $translateUI('collections.deleteConfirmGames', { n }) : $translateUI('collections.deleteConfirmEmpty'));
if (!(await askConfirm(body, { title: $translateUI('collections.deleteConfirmTitle'), confirmText: $translateUI('common.delete'), danger: true }))) return;
await deleteCollection(c.id);
}
</script>

{#if game}
<Modal title={$t('collections.title')} icon={Tags} onClose={close} width={460} height="auto" maxHeight="min(78vh, 620px)">
<Modal title={$translateUI('collections.title')} icon={Tags} onClose={close} width={460} height="auto" maxHeight="min(78vh, 620px)">
<svelte:fragment slot="sub">{game.name}</svelte:fragment>
<div class="body">
<ul>
Expand Down Expand Up @@ -82,22 +82,22 @@
<span class="count">{c.gameIds.length}</span>
</label>
{#if !c.builtin}
<button class="btn small ghost icon" title={$t('common.rename')} aria-label={$t('collections.renameAria', { name: c.name })} on:click={() => startRename(c)}><Pencil size={13} /></button>
<button class="btn small ghost icon" title={$t('common.delete')} aria-label={$t('collections.deleteAria', { name: c.name })} on:click={() => remove(c)}><Trash2 size={13} /></button>
<button class="btn small ghost icon" title={$translateUI('common.rename')} aria-label={$translateUI('collections.renameAria', { name: c.name })} on:click={() => startRename(c)}><Pencil size={13} /></button>
<button class="btn small ghost icon" title={$translateUI('common.delete')} aria-label={$translateUI('collections.deleteAria', { name: c.name })} on:click={() => remove(c)}><Trash2 size={13} /></button>
{/if}
{/if}
</li>
{/each}
</ul>
<form class="new" on:submit|preventDefault={add}>
<input placeholder={$t('collections.newPlaceholder')} maxlength="40" bind:value={newName} />
<button class="btn small" type="submit" disabled={!newName.trim()}><Plus size={14} />{$t('common.add')}</button>
<input placeholder={$translateUI('collections.newPlaceholder')} maxlength="40" bind:value={newName} />
<button class="btn small" type="submit" disabled={!newName.trim()}><Plus size={14} />{$translateUI('common.add')}</button>
</form>
<p class="hint">{$t('collections.hint')}</p>
<p class="hint">{$translateUI('collections.hint')}</p>
</div>
<ModalFoot>
<span></span>
<button class="btn primary" on:click={close}>{$t('common.done')}</button>
<button class="btn primary" on:click={close}>{$translateUI('common.done')}</button>
</ModalFoot>
</Modal>
{/if}
Expand Down
Loading