feat(gif): favourites and category shortcuts
CI / Build & test (Node 20) (push) Canceled after 0s
CI / Build & test (Node 24) (push) Canceled after 0s
CI / Build & test (push) Canceled after 0s
CodeQL / Analyze (javascript-typescript) (push) Canceled after 0s
Security / Secret scan (gitleaks) (push) Canceled after 0s
Security / Dependency scan (OSV-Scanner) (push) Canceled after 0s
Security / IaC/config scan (Trivy) (push) Canceled after 0s
Security / License compliance scan (Trivy) (push) Canceled after 0s
OpenSSF Scorecard / Scorecard analysis (push) Canceled after 0s
CI / Build & test (Node 20) (push) Canceled after 0s
CI / Build & test (Node 24) (push) Canceled after 0s
CI / Build & test (push) Canceled after 0s
CodeQL / Analyze (javascript-typescript) (push) Canceled after 0s
Security / Secret scan (gitleaks) (push) Canceled after 0s
Security / Dependency scan (OSV-Scanner) (push) Canceled after 0s
Security / IaC/config scan (Trivy) (push) Canceled after 0s
Security / License compliance scan (Trivy) (push) Canceled after 0s
OpenSSF Scorecard / Scorecard analysis (push) Canceled after 0s
Favourites are stored server-side per user, so one made on the phone is there on the desktop — the point of favouriting. The whole result is stored rather than an id: the provider offers no lookup by id, so an id-only favourite could not be rendered without re-finding it through search. Category chips translate their label but not their query, which goes to a provider that indexes in English. The star sits beside the tile button rather than inside it: a button within a button is invalid and swallows the click. Toggling is optimistic and reverts on failure, and favourites skip both the loading skeleton and the infinite scroll, which belong to provider-backed browsing only. Server caps favourites per user and rejects non-http(s) URLs, which become <img src> in everyone's picker.
This commit is contained in:
@@ -280,6 +280,9 @@ export class BackspaceApiClient {
|
||||
trending: (limit?: number, pos?: string) => Promise<{ results: GifResult[]; next: string }>;
|
||||
search: (q: string, limit?: number, pos?: string) => Promise<{ results: GifResult[]; next: string }>;
|
||||
enabled: () => Promise<{ enabled: boolean }>;
|
||||
favorites: () => Promise<{ results: GifResult[] }>;
|
||||
addFavorite: (gif: GifResult) => Promise<void>;
|
||||
removeFavorite: (id: string) => Promise<void>;
|
||||
};
|
||||
|
||||
readonly spotify: {
|
||||
@@ -710,6 +713,9 @@ export class BackspaceApiClient {
|
||||
if (pos) params.set('pos', pos);
|
||||
return request<{ results: GifResult[]; next: string }>('GET', `/gif/trending?${params}`);
|
||||
},
|
||||
favorites: () => request<{ results: GifResult[] }>('GET', '/gif/favorites'),
|
||||
addFavorite: (gif: GifResult) => request<void>('POST', '/gif/favorites', gif),
|
||||
removeFavorite: (id: string) => request<void>('DELETE', `/gif/favorites/${encodeURIComponent(id)}`),
|
||||
search: (q: string, limit = 30, pos?: string) => {
|
||||
const params = new URLSearchParams();
|
||||
params.set('q', q);
|
||||
|
||||
Reference in New Issue
Block a user