diff --git a/plan/achievements.md b/plan/achievements.md index 33f743d..75c2097 100644 --- a/plan/achievements.md +++ b/plan/achievements.md @@ -65,6 +65,13 @@ resolve. What is left is `goat lex publish`. - [ ] Settle the tier vocabulary and its colours in the definition schema, so an unearned tier can be drawn faded without the renderer knowing the game. +- [ ] **A rank, earned rather than rated.** What a player is called comes from + what they have been awarded, not from a rating - which is what makes it + this epic's and not [leaderboard](leaderboard.md)'s. It lands in three + places at once when it does: the title of a player's link preview, the + card that link unfurls with, and the page itself. All three say only the + handle today ([player-profile](player-profile.md)), because a rank that + nothing has earned is a card telling a stranger something untrue. ## Later waves, no schema change expected diff --git a/plan/player-profile.md b/plan/player-profile.md index 210ff55..005bf18 100644 --- a/plan/player-profile.md +++ b/plan/player-profile.md @@ -106,6 +106,15 @@ now, mounted beside the account's and waiting on nothing. unconfirmed handle is dropped rather than shown, because a handle is rented and the account that used to hold one is not the account that holds it now. +- [x] **The preview says the handle and what the site is, and nothing else.** + The title is the handle alone - the card above it already draws the + name, so the title's job is to be the text-only version for a reader + whose images did not load - and the description is the site's own + tagline, the same line a match report's card carries. The two things + that would say something about the player are a rank and a bio, and + neither has a source: a rank is [achievements](achievements.md)'s and + will be earned rather than rated, at which point it goes in the title + and on the card together. - [x] **The address is the handle, with its @ and nothing escaped.** `/players/@alice.example` is an address somebody can read out; `/players/did%3Aplc%3Ah7k...` is one nobody can. Both forms answer, and diff --git a/services/api/src/share.rs b/services/api/src/share.rs index 681babf..9eb17ab 100644 --- a/services/api/src/share.rs +++ b/services/api/src/share.rs @@ -391,7 +391,7 @@ fn verdict_line(summary: &Summary, perspective: Option<&Perspective>) -> String /// The line beside the way in, for a reader who arrived from a shared post /// and has never heard of any of this. -const TAGLINE: &str = "Tactical combat on the Atmosphere."; +pub(crate) const TAGLINE: &str = "Tactical combat on the Atmosphere."; /// Which of MegaMek's own default silhouettes a machine falls back to. /// diff --git a/services/api/src/unfurl.rs b/services/api/src/unfurl.rs index b8de60c..a3d2b00 100644 --- a/services/api/src/unfurl.rs +++ b/services/api/src/unfurl.rs @@ -22,7 +22,7 @@ use axum::response::{Html, IntoResponse, Response}; use crate::card; use crate::routes::AppState; -use crate::share::escape; +use crate::share::{TAGLINE, escape}; /// How long a preview is allowed to stand. /// @@ -38,13 +38,6 @@ use crate::share::escape; /// somebody else's timeline to update it. const CACHING: &str = "public, max-age=60"; -/// The line under the name on the card and in the preview. -/// -/// Placeholder, and easy to find: this is the sentence a reader who has never -/// heard of the site sees under somebody's handle, and it is a human's to -/// write. See plan/site-copy.md. -const BLURB: &str = "Quockerwodger gongoozler, absquatulate nudiustertian."; - /// What the card and the tags both need. struct Player { /// "@handle", or the DID where no handle resolves back to it. What the @@ -246,6 +239,17 @@ fn headers(content_type: &'static str, caching: &'static str) -> HeaderMap { /// The document itself: the tags, and one line for whoever is not a fetcher. fn document(player: &Player, here: &str, image: &str) -> String { let name = escape(&player.name); + // The description is the site's own line, the same one a match report's + // card carries. A reader seeing a player's card in a feed has usually + // never heard of lance.blue, and what the site is is more use to them + // than a second reading of the handle printed above it. + // + // It says nothing about the player on purpose: the two things that would + // - a rank and a bio - have no source yet, and a card that invented + // either would be telling a stranger something untrue. Ranks are coming + // and will be earned rather than rated (plan/achievements.md), and they + // go in the title and on the card itself when they do. + let blurb = escape(TAGLINE); format!( "\n\n
\n\ \n\ @@ -265,7 +269,7 @@ fn document(player: &Player, here: &str, image: &str) -> String { \n\ \n\n", name = name, - blurb = escape(BLURB), + blurb = blurb, here = escape(here), image = escape(image), ) @@ -332,6 +336,25 @@ mod tests { ); } + /// The description is the site's line, and it is the one thing on the + /// card that must not become filler again: it is under every player's + /// handle in somebody else's timeline. + #[test] + fn the_description_says_what_the_site_is() { + let player = player(); + let html = document( + &player, + "https://lance.blue/players/a.example", + "https://x/c.png", + ); + assert!(html.contains(&format!( + "" + ))); + // Nothing about the player: a rank and a bio are what would go here + // and neither has a source yet. + assert!(!TAGLINE.contains("a.example")); + } + /// A handle is a domain somebody else chose, and it reaches this document /// from a DID document written by whoever holds it. #[test]