diff --git a/apps/amethyst/components/teal/TealShell.tsx b/apps/amethyst/components/teal/TealShell.tsx index c49df10..1195d31 100644 --- a/apps/amethyst/components/teal/TealShell.tsx +++ b/apps/amethyst/components/teal/TealShell.tsx @@ -101,21 +101,21 @@ function LeftRail() { const agent = useStore((state) => state.pdsAgent); const profiles = useStore((state) => state.profiles); const profile = agent?.did ? profiles[agent.did] : undefined; + const tealProfile = profile?.teal as + | { avatar?: string; displayName?: string; handle?: string } + | null + | undefined; const tealHandle = normalizeHandle( - (profile?.teal as { handle?: string } | null | undefined)?.handle, + tealProfile?.handle, ); - const bskyHandle = normalizeHandle(profile?.bsky?.handle); const displayName = - profile?.teal?.displayName || - profile?.bsky?.displayName || + tealProfile?.displayName || tealHandle || - bskyHandle || - "Your profile"; - const handle = tealHandle || bskyHandle; + "Your Teal profile"; const avatar = agent?.did ? getProfileImageUrl( agent.did, - profile?.teal?.avatar || profile?.bsky?.avatar, + tealProfile?.avatar, "avatar", ) : undefined; @@ -177,8 +177,8 @@ function LeftRail() { numberOfLines={1} > {status === "loggedIn" - ? handle - ? `@${handle}` + ? tealHandle + ? `@${tealHandle}` : "Manage your Teal identity" : "with ATProto"} diff --git a/apps/amethyst/stores/authenticationSlice.tsx b/apps/amethyst/stores/authenticationSlice.tsx index 0f22aa3..0507ec7 100644 --- a/apps/amethyst/stores/authenticationSlice.tsx +++ b/apps/amethyst/stores/authenticationSlice.tsx @@ -7,6 +7,7 @@ import type { ProfileView } from "@teal/lexicons/src/types/fm/teal/alpha/actor/d import createOAuthClient, { AquareumOAuthClient } from "../lib/atp/oauth"; import { pdsHostFromOAuthIssuer } from "../lib/atp/oauthIssuer"; +import { getProfile } from "../lib/teal/api"; import { StateCreator } from "./mainStore"; export interface AllProfileViews { @@ -200,22 +201,12 @@ export const createAuthenticationSlice: StateCreator = ( }); // get teal did try { - const tealDid = get().tealDid; - const tealProfile = await agent - .call( - "fm.teal.alpha.actor.getProfile", - { actor: agent?.did }, - {}, - { headers: { "atproto-proxy": tealDid + "#teal_fm_appview" } }, - ) - .then((profile) => { - console.log(profile); - const data = profile.data as { - actor?: ProfileView; - profile?: ProfileView; - }; - return data.profile || data.actor || null; - }); + // Aqua is the source of truth for Teal identity data. Fetching it + // directly avoids depending on the user's PDS proxy configuration, + // which can otherwise leave the shell showing stale Bluesky data. + const tealProfile = await getProfile(agent.did).then( + ({ profile }) => profile, + ); set({ profiles: { diff --git a/todo.md b/todo.md index 5f3b8d8..bbbce8a 100644 --- a/todo.md +++ b/todo.md @@ -32,6 +32,7 @@ Last synced with GitHub and Linear issues: 2026-06-14. - Manual album listening entry (2026-07-18): Amethyst now has a protected `/manual-listens` page in the desktop/mobile navigation, MusicBrainz release and track selection, duration-aware timestamp previews, atomic `applyWrites` submission, and a fresh-origin logged-out redirect. The hero copy is kept focused on the album action without the extra listening-record label, and timestamp choices explain their effect using plain language and local-time guidance. Cadet now persists failed play events in a Postgres retry queue with exponential backoff and dead-letter tracking. TypeScript, Amethyst tests, Biome, and the web export pass; authenticated preview QA remains. - Manual-listen review fixes (2026-08-11): Cadet retry jobs now collapse by logical record, preserve commit ordering, serialize replay with live record commits, reset attempts when newer revisions replace queued retries, recheck account activity, and conditionally complete stale jobs; duplicate-CID retries repair artist links and aggregates, and reverse timeline backfills use the preceding track duration. Focused Rust, TypeScript, Biome, and migration checks pass. - Cadet account/retry race fix (2026-08-11): account lifecycle state updates and purges now share a per-DID transaction advisory lock with the final play write, which rechecks account activity atomically before committing replayed data. Added an inactive-account replay regression test. +- Teal sidebar identity alignment (2026-08-12): the authenticated desktop sidebar now loads the logged-in Teal profile directly from Aqua and never falls back to Bluesky name/avatar metadata, keeping it consistent with Teal-authored feed cards. Verify with authenticated browser QA after the next preview rebuild. ## Local Open Work