Skip to content
Merged
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
1 change: 1 addition & 0 deletions frontend/src/locales/bg_BG/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "Избери цвят на фона",
"select-save": "Избери запис",
"select-state": "Избери бърз запис",
"slot": "Слот",
"start-fresh-hint": "Избери един по-долу, за да продължиш, или натисни Играй, за да започнеш отначало."
}
1 change: 1 addition & 0 deletions frontend/src/locales/cs_CZ/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "Vybrat barvu pozadí",
"select-save": "Vybrat uloženou pozici",
"select-state": "Vybrat stav",
"slot": "Slot",
"start-fresh-hint": "Vyberte níže pro pokračování, nebo stiskněte Hrát pro nový začátek."
}
1 change: 1 addition & 0 deletions frontend/src/locales/de_DE/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "Hintergrundfarbe auswählen",
"select-save": "Speicherstand auswählen",
"select-state": "Speicherstand auswählen",
"slot": "Slot",
"start-fresh-hint": "Wähle unten einen, um fortzufahren, oder klicke auf Play, um neu zu starten."
}
1 change: 1 addition & 0 deletions frontend/src/locales/en_GB/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "Select background color",
"select-save": "Select save",
"select-state": "Select state",
"slot": "Slot",
"start-fresh-hint": "Pick one below to resume, or hit Play to start fresh."
}
1 change: 1 addition & 0 deletions frontend/src/locales/en_US/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "Select background color",
"select-save": "Select save",
"select-state": "Select state",
"slot": "Slot",
"start-fresh-hint": "Pick one below to resume, or hit Play to start fresh."
}
1 change: 1 addition & 0 deletions frontend/src/locales/es_ES/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "Seleccionar color de fondo",
"select-save": "Seleccionar guardado",
"select-state": "Seleccionar estado",
"slot": "Ranura",
"start-fresh-hint": "Empezar desde cero — sin partidas guardadas."
}
1 change: 1 addition & 0 deletions frontend/src/locales/fr_FR/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "Sélectionner la couleur d'arrière-plan",
"select-save": "Sélectionner la sauvegarde",
"select-state": "Sélectionner l'état",
"slot": "Emplacement",
"start-fresh-hint": "Choisissez-en un ci-dessous pour reprendre, ou appuyez sur Jouer pour démarrer une nouvelle partie."
}
1 change: 1 addition & 0 deletions frontend/src/locales/hu_HU/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "Háttérszín kiválasztása",
"select-save": "Mentés kiválasztása",
"select-state": "Állás kiválasztása",
"slot": "Hely",
"start-fresh-hint": "Válassz egyet az alábbiak közül a folytatáshoz, vagy nyomd meg az Indítást egy új játékhoz."
}
1 change: 1 addition & 0 deletions frontend/src/locales/it_IT/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "Seleziona colore di sfondo",
"select-save": "Seleziona Salvataggio",
"select-state": "Seleziona Stato",
"slot": "Slot",
"start-fresh-hint": "Scegline uno qui sotto per riprendere, oppure premi Gioca per iniziare da capo."
}
1 change: 1 addition & 0 deletions frontend/src/locales/ja_JP/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "背景色を選択",
"select-save": "セーブデータを選択",
"select-state": "ステートを選択",
"slot": "スロット",
"start-fresh-hint": "下から選んで再開するか、Playを押して最初から始めてください。"
}
1 change: 1 addition & 0 deletions frontend/src/locales/ko_KR/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "배경색 선택",
"select-save": "세이브 선택",
"select-state": "상태 선택",
"slot": "슬롯",
"start-fresh-hint": "아래에서 하나를 선택하여 이어 하거나, 실행을 눌러 새로 시작하세요."
}
1 change: 1 addition & 0 deletions frontend/src/locales/pl_PL/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "Wybierz kolor tła",
"select-save": "Wybierz zapis",
"select-state": "Wybierz stan",
"slot": "Slot",
"start-fresh-hint": "Wybierz jeden poniżej, aby wznowić, lub naciśnij Graj, aby zacząć od nowa."
}
1 change: 1 addition & 0 deletions frontend/src/locales/pt_BR/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "Selecionar cor de fundo",
"select-save": "Selecionar save",
"select-state": "Selecionar estado",
"slot": "Slot",
"start-fresh-hint": "Escolha um abaixo para retomar, ou clique em Jogar para começar do zero."
}
1 change: 1 addition & 0 deletions frontend/src/locales/ro_RO/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "Selectează culoarea de fundal",
"select-save": "Selectează salvare",
"select-state": "Selectează stare",
"slot": "Slot",
"start-fresh-hint": "Alege una mai jos pentru a relua sau apasă Joacă pentru a începe de la zero."
}
1 change: 1 addition & 0 deletions frontend/src/locales/ru_RU/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "Выбрать цвет фона",
"select-save": "Выбрать сохранение",
"select-state": "Выбрать состояние",
"slot": "Слот",
"start-fresh-hint": "Выберите одно из ниже, чтобы продолжить, или нажмите «Играть», чтобы начать заново."
}
1 change: 1 addition & 0 deletions frontend/src/locales/tr_TR/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "Arka plan rengi seç",
"select-save": "Kayıt seç",
"select-state": "Durum kaydı seç",
"slot": "Slot",
"start-fresh-hint": "Devam etmek için aşağıdan birini seçin veya baştan başlamak için Oyna'ya basın."
}
1 change: 1 addition & 0 deletions frontend/src/locales/zh_CN/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "选择背景颜色",
"select-save": "选择存档",
"select-state": "选择状态",
"slot": "存档位",
"start-fresh-hint": "选择下方任一项继续,或点击开始从头开始。"
}
1 change: 1 addition & 0 deletions frontend/src/locales/zh_TW/play.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
"select-background-color": "選擇背景顏色",
"select-save": "選擇存檔",
"select-state": "選擇即時存檔",
"slot": "存檔槽",
"start-fresh-hint": "從下方選擇一項繼續遊玩,或按下 Play 重新開始。"
}
1 change: 1 addition & 0 deletions frontend/src/v2/components/Player/AssetCard.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function makeSave(overrides: Partial<SaveSchema> = {}): SaveSchema {
created_at: "2026-03-14T10:12:00Z",
updated_at: "2026-05-10T18:45:00Z",
emulator: "snes9x",
slot: "slot1",
screenshot: null,
...overrides,
} as SaveSchema;
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/v2/components/Player/AssetCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ const relativeText = computed(() => formatRelativeDate(props.asset.updated_at));
</div>

<div class="r-v2-asset-card__chips">
<RTag
v-if="'slot' in asset && asset.slot"
tone="brand"
size="x-small"
prepend-icon="mdi-bookmark-outline"
:label="t('play.slot')"
:text="asset.slot"
/>
<RTag
v-if="asset.emulator"
tone="warning"
Expand Down
1 change: 1 addition & 0 deletions frontend/src/v2/components/Player/AssetPreview.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ function makeSave(overrides: Partial<SaveSchema> = {}): SaveSchema {
created_at: "2026-03-14T10:12:00Z",
updated_at: "2026-05-23T18:45:00Z",
emulator: "snes9x",
slot: "main_quest",
screenshot: null,
...overrides,
} as SaveSchema;
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/v2/components/Player/AssetPreview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ const emptyText = computed(() =>
</RTooltip>
</p>
<div class="r-asset-preview__chips">
<RTag
v-if="'slot' in asset && asset.slot"
tone="brand"
size="x-small"
prepend-icon="mdi-bookmark-outline"
:label="t('play.slot')"
:text="asset.slot"
/>
<span class="r-asset-preview__chip">
<RIcon icon="mdi-clock-outline" size="12" />
{{ formatRelativeDate(asset.updated_at) }}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/v2/components/shared/AssetList.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ function makeSave(i: number, overrides: Partial<SaveSchema> = {}): SaveSchema {
created_at: new Date(now - (i + 2) * 86400 * 1000).toISOString(),
updated_at: new Date(now - (i + 1) * 4 * 3600 * 1000).toISOString(),
emulator: i % 2 === 0 ? "snes9x" : null,
slot: i % 3 === 0 ? null : slot, // Every third save is slot-less
screenshot: null,
...overrides,
} as SaveSchema;
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/v2/components/shared/AssetList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,14 @@ function ownerOf(asset: Asset): UserSaveSchema | UserStateSchema | null {
/>
<span>{{ ownerOf(asset)!.username }}</span>
</span>
<RTag
v-if="'slot' in asset && asset.slot"
tone="brand"
size="x-small"
prepend-icon="mdi-bookmark-outline"
:label="t('play.slot')"
:text="asset.slot"
/>
<RTag
v-if="asset.emulator"
tone="warning"
Expand Down
33 changes: 14 additions & 19 deletions frontend/src/v2/views/Player/EmulatorJS.vue
Original file line number Diff line number Diff line change
Expand Up @@ -302,10 +302,6 @@ async function onPlay() {

function selectSave(save: SaveSchema) {
selectedSave.value = save;
if (selectedState.value) {
selectedState.value = null;
localStorage.removeItem(`player:${rom.value?.platform_slug}:state_id`);
}
localStorage.setItem(
`player:${rom.value?.platform_slug}:save_id`,
save.id.toString(),
Expand All @@ -320,10 +316,6 @@ function unselectSave() {

function selectState(state: StateSchema) {
selectedState.value = state;
if (selectedSave.value) {
selectedSave.value = null;
localStorage.removeItem(`player:${rom.value?.platform_slug}:save_id`);
}
localStorage.setItem(
`player:${rom.value?.platform_slug}:state_id`,
state.id.toString(),
Expand Down Expand Up @@ -380,24 +372,27 @@ onMounted(async () => {
});
}

// Default tab + selection (mutually exclusive).
// Default selection — save and state are independent, so both can be
// armed at once. The bound save is the write-back target for "Save &
// Quit" (PUT in place), so we only auto-bind it when the choice is
// unambiguous: never silently pick a slot when a state is armed and
// there are multiple saves, since loading the state injects a different
// SRAM timeline that would overwrite an arbitrary save the user never
// picked. In that case the user must select the save slot explicitly.
const initiallyCompatibleStates = rom.value.user_states.filter(
(s) => !s.emulator || s.emulator === supportedCores.value[0],
);
const hasCompatibleState = initiallyCompatibleStates.length > 0;

if (initiallyCompatibleStates.length > 0) {
isSavesTabSelected.value = false;
if (hasCompatibleState) {
selectedState.value = initiallyCompatibleStates[0];
selectedSave.value = null;
} else if (rom.value.user_saves.length > 0) {
isSavesTabSelected.value = true;
}
const safeToBindSave =
rom.value.user_saves.length === 1 || !hasCompatibleState;
if (rom.value.user_saves.length > 0 && safeToBindSave) {
selectedSave.value = rom.value.user_saves[0];
selectedState.value = null;
} else {
isSavesTabSelected.value = true;
selectedSave.value = null;
selectedState.value = null;
}
isSavesTabSelected.value = !hasCompatibleState;

const storedDisc = localStorage.getItem(`player:${rom.value.id}:disc`);
if (storedDisc) {
Expand Down
Loading