native polish 2: two-robots fix, guest offline-host UX, Guest###### name, silent+fast native boot, minSdk 29 #275

Merged
developer merged 5 commits from feature/native-polish-2 into development 2026-07-15 00:26:28 +00:00
Showing only changes of commit aa803260a1 - Show all commits
+11 -1
View File
@@ -10,6 +10,7 @@
import Rack from './Rack.svelte'; import Rack from './Rack.svelte';
import { gateway } from '../lib/gateway'; import { gateway } from '../lib/gateway';
import { gameSource, localSource, isLocalGameId } from '../lib/gamesource'; import { gameSource, localSource, isLocalGameId } from '../lib/gamesource';
import { localGuestId } from '../lib/localguest';
import { notePreviewLocal, notePreviewNetwork } from '../lib/localeval-metrics'; import { notePreviewLocal, notePreviewNetwork } from '../lib/localeval-metrics';
import { navigate } from '../lib/router.svelte'; import { navigate } from '../lib/router.svelte';
import { app, handleError, showToast, markChatRead, seedChatUnread } from '../lib/app.svelte'; import { app, handleError, showToast, markChatRead, seedChatUnread } from '../lib/app.svelte';
@@ -1442,9 +1443,18 @@
// seatName renders a seat's name: "you" for the viewer, the localized "searching for // seatName renders a seat's name: "you" for the viewer, the localized "searching for
// opponent" placeholder for an open game's still-empty seat (no account), otherwise the // opponent" placeholder for an open game's still-empty seat (no account), otherwise the
// display name. // display name.
// isMe reports whether a seat belongs to the viewer — matched against the server account id OR
// the device-local guest id, the same rule the lobby uses for "my games". A device-local game
// (vs_ai / hotseat) is seated under the local guest id when created offline, and its human seat
// must still read "You" after a merge switches the active account to a durable id; without the
// local-guest arm the seat matched neither and a vs_ai game showed BOTH seats as robots.
function isMe(accountId: string | undefined): boolean {
return !!accountId && (accountId === app.session?.userId || accountId === localGuestId());
}
function seatName(s: { accountId: string; displayName: string } | undefined): string { function seatName(s: { accountId: string; displayName: string } | undefined): string {
if (!s) return ''; if (!s) return '';
if (s.accountId === app.session?.userId) return t('common.you'); if (isMe(s.accountId)) return t('common.you');
// An honest-AI game shows the robot opponent as 🤖, never its (pooled human-like) name. // An honest-AI game shows the robot opponent as 🤖, never its (pooled human-like) name.
if (view?.game.vsAi) return '🤖'; if (view?.game.vsAi) return '🤖';
if (!s.accountId) return t('game.searchingForOpponent'); if (!s.accountId) return t('game.searchingForOpponent');