diff --git a/README.md b/README.md index 19050c6..eeb72da 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Checkpoint is a save game backup tool for local games. Create timestamped backup - **100% Private** - Your data stays on your device. We have zero access to your saves or Google Drive - **Smart Protection** - Automatically backs up current save before restoring - **Process Detection** - Prevents restore while game is running -- **Cross-Platform** - Windows and Linux support +- **Cross-Platform** - Windows, macOS, and Linux support ## Your Data, Your Control @@ -29,6 +29,9 @@ Checkpoint is built with privacy as the foundation: ### Windows - Download the `.exe` installer +### macOS +- Download the `.dmg` installer or `.app.tar.gz` archive + ### Linux - **Ubuntu/Debian**: `checkpoint_0.1.0_amd64.deb` - **Fedora**: `checkpoint-0.1.0-1.x86_64.rpm` @@ -72,6 +75,7 @@ Checkpoint is built with privacy as the foundation: ## System Requirements - **Windows**: Windows 10 or later +- **macOS**: macOS 10.15 Catalina or later - **Linux**: Any modern distro with GTK3 ## Support diff --git a/src/App.css b/src/App.css index 1f88b97..1db03b8 100644 --- a/src/App.css +++ b/src/App.css @@ -631,6 +631,24 @@ html { color: var(--text-primary); } +.cloud-backup-modal-title { + display: flex; + align-items: center; + gap: 0.5rem; +} + +.cloud-backup-modal-title-icon { + flex-shrink: 0; + display: block; +} + +.cloud-backup-modal-heading { + font-size: 1rem; + font-weight: 700; + line-height: 1; + color: var(--text-primary); +} + .modal-close { background: var(--bg-tertiary); border: none; diff --git a/src/components/CloudBackupListModal.tsx b/src/components/CloudBackupListModal.tsx index bbbe967..0230a0d 100644 --- a/src/components/CloudBackupListModal.tsx +++ b/src/components/CloudBackupListModal.tsx @@ -5,6 +5,7 @@ import { useProfile } from '../lib/profileContext'; import { useToast } from '../lib/toastContext'; import { ConfirmModal } from './ConfirmModal'; import { listAllCloudSnapshots, downloadSnapshot, deleteCloudSnapshot, type CloudBackupItem } from '../lib/googleDrive'; +import { listGames } from '../lib/api'; interface CloudBackupListModalProps { isOpen: boolean; @@ -36,8 +37,19 @@ export function CloudBackupListModal({ isOpen, onClose, onDownload }: CloudBacku throw new Error(t('errors.notAuthenticated')); } - const allBackups = await listAllCloudSnapshots(token); - setBackups(allBackups); + const [allBackups, games] = await Promise.all([ + listAllCloudSnapshots(token), + listGames() + ]); + + const gamesMap = new Map(games.map(g => [g.id, g.name])); + + const backupsWithNames = allBackups.map(b => ({ + ...b, + gameName: b.gameName || (b.gameId ? gamesMap.get(b.gameId) : undefined) + })); + + setBackups(backupsWithNames); } catch (err) { const errorMsg = err instanceof Error ? err.message : t('cloud.failedLoadCloudBackups'); addToast(errorMsg, 'error'); @@ -161,9 +173,9 @@ export function CloudBackupListModal({ isOpen, onClose, onDownload }: CloudBacku >