search for standard sites
pub-search.waow.tech
search
zig
blog
atproto
2.9 kB
63 lines
1// shared: bluesky-compatible client registry + preferred-client preference.
2// mirrors the shape used in ../@zzstoatzz.io/status and ../@chicago.at so
3// users get consistent behavior across these atproto experiments.
4//
5// stored in localStorage under `leaflet.preferredClient`. default = bsky.
6// `profileUrlFor(handle)` returns the resolved profile URL for the current
7// preference; unknown values fall back to the first registered client.
8
9(function() {
10 'use strict';
11
12 var STORAGE_KEY = 'leaflet.preferredClient';
13
14 var CLIENTS = [
15 { value: 'bsky', label: 'Bluesky', profileUrl: function(h) { return 'https://bsky.app/profile/' + h; }, iconUrl: 'https://web-cdn.bsky.app/static/apple-touch-icon.png' },
16 { value: 'blacksky', label: 'Blacksky', profileUrl: function(h) { return 'https://blacksky.community/profile/' + h; }, iconUrl: 'https://blacksky.community/static/apple-touch-icon.png' },
17 { value: 'witchsky', label: 'Witchsky', profileUrl: function(h) { return 'https://witchsky.app/profile/' + h; }, iconUrl: 'https://witchsky.app/favicon.ico' },
18 { value: 'reddwarf', label: 'Red Dwarf', profileUrl: function(h) { return 'https://reddwarf.app/profile/' + h; }, iconUrl: 'https://reddwarf.app/redstar.png' },
19 { value: 'pdsls', label: 'PDSls', profileUrl: function(h) { return 'https://pdsls.dev/at/' + h; }, iconUrl: 'https://pdsls.dev/favicon.ico' },
20 ];
21
22 function readPreferred() {
23 try { return localStorage.getItem(STORAGE_KEY); } catch (e) { return null; }
24 }
25
26 function writePreferred(value) {
27 try { localStorage.setItem(STORAGE_KEY, value); } catch (e) {}
28 }
29
30 function getPreferredClient() {
31 var v = readPreferred();
32 return CLIENTS.find(function(c) { return c.value === v; }) || CLIENTS[0];
33 }
34
35 function setPreferredClient(value) {
36 if (CLIENTS.some(function(c) { return c.value === value; })) {
37 writePreferred(value);
38 window.dispatchEvent(new CustomEvent('leaflet:preferred-client-changed', { detail: value }));
39 }
40 }
41
42 function profileUrlFor(handleOrDid) {
43 return getPreferredClient().profileUrl(handleOrDid);
44 }
45
46 // Profile links bake the preferred-client URL into their href at render time.
47 // Rather than make every page listen for changes (easy to forget on a new
48 // surface), keep them fresh here: any anchor tagged `data-profile-did` gets
49 // its href rewritten app-wide when the preference changes. Render sites just
50 // need the attribute — no per-page wiring.
51 window.addEventListener('leaflet:preferred-client-changed', function() {
52 document.querySelectorAll('a[data-profile-did]').forEach(function(a) {
53 a.href = profileUrlFor(a.getAttribute('data-profile-did'));
54 });
55 });
56
57 window.LeafletClients = {
58 CLIENTS: CLIENTS,
59 getPreferredClient: getPreferredClient,
60 setPreferredClient: setPreferredClient,
61 profileUrlFor: profileUrlFor,
62 };
63})();