Files
Ferrous-Solitaire/solitaire_data
funman300 42d90b199c feat(data,engine): persist replay share URL alongside the replay
The v0.18.0 share-link affordance lived in an in-memory
LastSharedReplayUrl resource that was wiped on quit; the player had
to re-open Stats and re-share within the same session of the win.
The Stats overlay's Prev/Next selector also surfaced older replays
that had no share link at all even when those wins had been
uploaded successfully.

This bundles the URL with the replay it belongs to:

- Replay (solitaire_data) gains share_url: Option<String> with
  #[serde(default)]. No REPLAY_SCHEMA_VERSION bump — older
  replays.json files load unchanged with share_url == None on
  every entry. Replay::new() defaults the field to None.
- poll_replay_upload_result (sync_plugin) writes the resolved URL
  into ReplayHistoryResource::0.replays[0].share_url and persists
  the updated history via save_replay_history_to. The
  cancel-on-replace contract in push_replay_on_win guarantees
  replays[0] is the win whose URL the task is carrying — at most
  one upload is ever in flight, and it's always the most recent
  win.
- handle_copy_share_link_button (stats_plugin) reads from
  history.0.replays[selected.0].share_url instead of
  LastSharedReplayUrl, so the Prev/Next selector's currently-
  displayed replay drives the clipboard contents. Each historical
  win keeps its own URL.
- LastSharedReplayUrl resource removed entirely — its only role
  was bridging the upload-poll system to the Copy button, and
  that channel is now the share_url field on the replay record.

Tests:

- solitaire_data: replay_loads_when_share_url_field_is_absent
  pins backwards-compat — a pre-v0.19.0 Replay JSON without the
  field deserialises with share_url == None.
- solitaire_engine sync_plugin: upload_result_writes_share_url_into_replay_and_persists
  drives a pre-resolved AsyncComputeTaskPool task into
  PendingReplayUpload, pumps update() until the poll system
  resolves it, and asserts both the in-memory replays[0]
  carries the URL and a fresh load_replay_history_from(path)
  picks it up.

Workspace: 1170 passing tests / 0 failing, was 1168 (+2 net).
cargo clippy --workspace --all-targets -- -D warnings clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 18:10:16 -07:00
..