diff --git a/crates/lanspread-tauri-deno-ts/src/components/calltoplay/CallToPlayOverlay.tsx b/crates/lanspread-tauri-deno-ts/src/components/calltoplay/CallToPlayOverlay.tsx
index 4af3c06..14b0693 100644
--- a/crates/lanspread-tauri-deno-ts/src/components/calltoplay/CallToPlayOverlay.tsx
+++ b/crates/lanspread-tauri-deno-ts/src/components/calltoplay/CallToPlayOverlay.tsx
@@ -81,8 +81,7 @@ export const CallToPlayOverlay = ({
)}
{sorted.map(nomination => {
- const game = gameById.get(nomination.gameId);
- if (!game) return null;
+ const game = gameById.get(nomination.gameId) ?? null;
return (
diff --git a/crates/lanspread-tauri-deno-ts/src/components/calltoplay/CallToPlayTicker.tsx b/crates/lanspread-tauri-deno-ts/src/components/calltoplay/CallToPlayTicker.tsx
index 288817d..65a4df5 100644
--- a/crates/lanspread-tauri-deno-ts/src/components/calltoplay/CallToPlayTicker.tsx
+++ b/crates/lanspread-tauri-deno-ts/src/components/calltoplay/CallToPlayTicker.tsx
@@ -75,7 +75,6 @@ export const CallToPlayTicker = ({ nominations, games, accent, onOpen }: Props)
{active.map(nomination => {
const game = gameById.get(nomination.gameId);
- if (!game) return null;
const status = statusOf(nomination, now);
if (status === 'started') return null;
const ready = readyCountOf(nomination, now);
@@ -102,7 +101,10 @@ export const CallToPlayTicker = ({ nominations, games, accent, onOpen }: Props)
>
{LABEL[status]}
-
{game.name}
+
{game?.name ?? 'Game unavailable here'}
by {nomination.creator}
{count}
{time}
diff --git a/crates/lanspread-tauri-deno-ts/src/components/calltoplay/NominationCard.tsx b/crates/lanspread-tauri-deno-ts/src/components/calltoplay/NominationCard.tsx
index ec890b9..20da08f 100644
--- a/crates/lanspread-tauri-deno-ts/src/components/calltoplay/NominationCard.tsx
+++ b/crates/lanspread-tauri-deno-ts/src/components/calltoplay/NominationCard.tsx
@@ -20,7 +20,7 @@ import { CallToPlayParticipant, Game, Nomination } from '../../lib/types';
interface Props {
nomination: Nomination;
- game: Game;
+ game: Game | null;
actorId: string | null;
actions: CallToPlayActions;
focused: boolean;
@@ -94,7 +94,9 @@ export const NominationCard = ({
Math.min(100, (remaining / Math.max(1, nomination.deadline - windowStart)) * 100),
);
const urgency = percentage < 20 ? 'high' : percentage < 50 ? 'mid' : 'low';
- const installedCount = (game.installed_peer_count ?? game.peer_count) + (game.installed ? 1 : 0);
+ const installedCount = game === null
+ ? 0
+ : (game.installed_peer_count ?? game.peer_count) + (game.installed ? 1 : 0);
const lanCount = Math.max(totalPeerCount + 1, installedCount);
const timer = isStarted
@@ -130,15 +132,19 @@ export const NominationCard = ({
>
-
{game.name}
+
{game?.name ?? 'Game unavailable here'}
{nomination.scheduledFor === null ? 'Called' : 'Scheduled'} by{' '}
{nomination.creator}
{nomination.scheduledFor !== null && ` · starts at ${formatClock(nomination.scheduledFor)}`}
- {` · ${installedCount}/${lanCount} peers have it installed`}
+ {game
+ ? ` · ${installedCount}/${lanCount} peers have it installed`
+ : ` · this game is not in your current library (ID: ${nomination.gameId})`}
{timer}
@@ -229,7 +235,7 @@ export const NominationCard = ({
interface CardActionsProps {
nomination: Nomination;
- game: Game;
+ game: Game | null;
actorId: string | null;
actions: CallToPlayActions;
onLaunch: (game: Game) => void;
@@ -274,7 +280,11 @@ const CardActions = ({
const readyCount = readyCountOf(nomination, now);
if (isStarted) {
- return
Launching {game.name}…
;
+ return (
+
+ {game ? `Launching ${game.name}…` : 'The match is starting.'}
+
+ );
}
if (scheduled) {
if (isCreator) {
@@ -310,9 +320,9 @@ const CardActions = ({
void actions.startNow(nomination.id).then(accepted => {
- if (accepted) onLaunch(game);
+ if (accepted && game) onLaunch(game);
})}
- >Start now
+ >
{game ? 'Start now' : 'Mark as started'}
actions.addTime(nomination.id)}>
Add 5 more minutes
diff --git a/crates/lanspread-tauri-deno-ts/src/styles/launcher.css b/crates/lanspread-tauri-deno-ts/src/styles/launcher.css
index 6093935..45f84ab 100644
--- a/crates/lanspread-tauri-deno-ts/src/styles/launcher.css
+++ b/crates/lanspread-tauri-deno-ts/src/styles/launcher.css
@@ -1933,6 +1933,14 @@
border-radius: 8px;
overflow: hidden;
}
+.ctp-card-cover-missing {
+ width: 100%; height: 100%;
+ display: grid; place-items: center;
+ color: var(--t-3);
+ background: color-mix(in srgb, var(--bd-2) 55%, transparent);
+ border: 1px dashed var(--bd-2);
+}
+.ctp-card-cover-missing svg { width: 22px; height: 22px; }
.ctp-card-info { flex: 1; min-width: 0; }
.ctp-card-title { font-size: 14.5px; font-weight: 700; color: var(--t-1); }
.ctp-card-sub { margin-top: 3px; font-size: 11.5px; color: var(--t-3); }