From dbe2f418b5793a2a289bed4394e43f110d8f9194 Mon Sep 17 00:00:00 2001
From: Florian <45694132+flo-bit@users.noreply.github.com>
Date: Tue, 20 Jan 2026 01:51:30 +0100
Subject: [PATCH 1/2] oauth fixes? cleanup add photo gallery (hidden for now)
add robots.txt
---
docs/Autofill.md | 1 +
docs/CardIdeas.md | 9 +-
package.json | 1 +
pnpm-lock.yaml | 82 ++++++
.../PhotoGalleryCard/PhotoGalleryCard.svelte | 67 +++++
src/lib/cards/PhotoGalleryCard/index.ts | 58 ++++
src/lib/cards/index.ts | 4 +-
src/lib/oauth/auth.svelte.ts | 9 +-
src/lib/website/Account.svelte | 39 +++
src/lib/website/EditBar.svelte | 278 ++++++++++++++++++
src/lib/website/EditableWebsite.svelte | 277 ++---------------
src/lib/website/Profile.svelte | 3 +-
src/lib/website/Settings.svelte | 2 +-
static/robots.txt | 3 +
14 files changed, 573 insertions(+), 260 deletions(-)
create mode 100644 src/lib/cards/PhotoGalleryCard/PhotoGalleryCard.svelte
create mode 100644 src/lib/cards/PhotoGalleryCard/index.ts
create mode 100644 src/lib/website/Account.svelte
create mode 100644 src/lib/website/EditBar.svelte
create mode 100644 static/robots.txt
diff --git a/docs/Autofill.md b/docs/Autofill.md
index bdb63c3..9a480b3 100644
--- a/docs/Autofill.md
+++ b/docs/Autofill.md
@@ -9,4 +9,5 @@
- com.germnetwork.declaration
- pub.leaflet.document
- blue.flashes.actor.portfolio
+ - social.grain.gallery
- add bluesky profile card
diff --git a/docs/CardIdeas.md b/docs/CardIdeas.md
index 940655d..7e979e3 100644
--- a/docs/CardIdeas.md
+++ b/docs/CardIdeas.md
@@ -21,11 +21,12 @@
- bluesky account card (showing follow button, follower count, avatar, name, cover image)
- youtube channel card (showing channel name, latest videos, follow button?)
- bluesky posts workcloud
+- steam game
## bluesky
- bluesky feed
-- bluesky post (fixed or latest)
+- bluesky post (pinned, latest or fixed)
- social accounts card (multiple)
## social
@@ -36,11 +37,12 @@
- leaflet
- skywatched
-- teal.fm
+- teal.fm
+ - [x] last played songs
- tangled.sh
- popfeed.social
- reading goal
- - latest ratings
+ - [x] latest ratings
- lists
- smokesignal.events (https://pdsls.dev/at://did:plc:xbtmt2zjwlrfegqvch7fboei/events.smokesignal.calendar.event/3ltn2qrxf3626)
- statusphere.xyz
@@ -48,6 +50,7 @@
- flashes.blue (https://pdsls.dev/at://did:plc:aytgljyikzbtgrnac2u4ccft/blue.flashes.actor.portfolio, https://app.flashes.blue/profile/j4ck.xyz)
- room: flo-bit.dev/room
- plyr.fm
+- grain.social
## programming
diff --git a/package.json b/package.json
index 8e63a54..8598d8d 100644
--- a/package.json
+++ b/package.json
@@ -49,6 +49,7 @@
"@foxui/core": "^0.4.7",
"@foxui/social": "^0.4.7",
"@foxui/time": "^0.4.7",
+ "@foxui/visual": "^0.4.7",
"@tailwindcss/typography": "^0.5.16",
"@tiptap/core": "^2.12.0",
"@tiptap/extension-document": "^2.12.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d7dba8e..30bfcbd 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -38,6 +38,9 @@ importers:
'@foxui/time':
specifier: ^0.4.7
version: 0.4.7(svelte@5.46.4)(tailwindcss@4.1.5)
+ '@foxui/visual':
+ specifier: ^0.4.7
+ version: 0.4.7(svelte@5.46.4)(tailwindcss@4.1.5)
'@tailwindcss/typography':
specifier: ^0.5.16
version: 0.5.16(tailwindcss@4.1.5)
@@ -672,6 +675,12 @@ packages:
svelte: '>=5'
tailwindcss: '>=3'
+ '@foxui/visual@0.4.7':
+ resolution: {integrity: sha512-POcVBvmeHD5Z3UFBANIawn6mBZLB5XEy/jqkFp1NV1OnHSdE4vNjWYSva3GU1C/OVVPxjfNFB0SisZlHWmk5FA==, tarball: https://registry.npmjs.org/@foxui/visual/-/visual-0.4.7.tgz}
+ peerDependencies:
+ svelte: '>=5'
+ tailwindcss: '>=3'
+
'@humanfs/core@0.19.1':
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==, tarball: https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz}
engines: {node: '>=18.18.0'}
@@ -1502,6 +1511,9 @@ packages:
camelize@1.0.1:
resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==, tarball: https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz}
+ canvas-confetti@1.9.4:
+ resolution: {integrity: sha512-yxQbJkAVrFXWNbTUjPqjF7G+g6pDotOUHGbkZq2NELZUMDpiJ85rIEazVb8GTaAptNW2miJAXbs1BtioA251Pw==, tarball: https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.4.tgz}
+
chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, tarball: https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz}
engines: {node: '>=10'}
@@ -1513,6 +1525,10 @@ packages:
resolution: {integrity: sha512-bQwNaDIBKID5ts/DsdhxrjqFXYfLw4ste+wMKqWA8DyKcS4qwsPP4Bk8ZNaTJjvpiX/qW3BT4sU7d6Bh5i+dag==, tarball: https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.11.tgz}
engines: {node: '>= 6'}
+ cheerio@1.1.2:
+ resolution: {integrity: sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==, tarball: https://registry.npmjs.org/cheerio/-/cheerio-1.1.2.tgz}
+ engines: {node: '>=20.18.1'}
+
chokidar@4.0.3:
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==, tarball: https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz}
engines: {node: '>= 14.16.0'}
@@ -1674,6 +1690,9 @@ packages:
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==, tarball: https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz}
engines: {node: '>= 0.8'}
+ encoding-sniffer@0.2.1:
+ resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==, tarball: https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz}
+
enhanced-resolve@5.18.1:
resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==, tarball: https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz}
engines: {node: '>=10.13.0'}
@@ -1950,6 +1969,9 @@ packages:
hls.js@1.6.15:
resolution: {integrity: sha512-E3a5VwgXimGHwpRGV+WxRTKeSp2DW5DI5MWv34ulL3t5UNmyJWCQ1KmLEHbYzcfThfXG8amBL+fCYPneGHC4VA==, tarball: https://registry.npmjs.org/hls.js/-/hls.js-1.6.15.tgz}
+ htmlparser2@10.0.0:
+ resolution: {integrity: sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==, tarball: https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz}
+
htmlparser2@8.0.2:
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==, tarball: https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz}
@@ -2304,6 +2326,9 @@ packages:
parse5-htmlparser2-tree-adapter@7.1.0:
resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==, tarball: https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz}
+ parse5-parser-stream@7.1.2:
+ resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==, tarball: https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz}
+
parse5@7.3.0:
resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==, tarball: https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz}
@@ -2939,6 +2964,15 @@ packages:
w3c-keyname@2.2.8:
resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==, tarball: https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz}
+ whatwg-encoding@3.1.1:
+ resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==, tarball: https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz}
+ engines: {node: '>=18'}
+ deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation
+
+ whatwg-mimetype@4.0.0:
+ resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==, tarball: https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz}
+ engines: {node: '>=18'}
+
which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, tarball: https://registry.npmjs.org/which/-/which-2.0.2.tgz}
engines: {node: '>= 8'}
@@ -3424,6 +3458,16 @@ snapshots:
svelte: 5.46.4
tailwindcss: 4.1.5
+ '@foxui/visual@0.4.7(svelte@5.46.4)(tailwindcss@4.1.5)':
+ dependencies:
+ '@foxui/colors': 0.4.7(svelte@5.46.4)(tailwindcss@4.1.5)
+ '@foxui/core': 0.4.7(svelte@5.46.4)(tailwindcss@4.1.5)
+ bits-ui: 1.8.0(svelte@5.46.4)
+ canvas-confetti: 1.9.4
+ cheerio: 1.1.2
+ svelte: 5.46.4
+ tailwindcss: 4.1.5
+
'@humanfs/core@0.19.1': {}
'@humanfs/node@0.16.6':
@@ -4211,6 +4255,8 @@ snapshots:
camelize@1.0.1: {}
+ canvas-confetti@1.9.4: {}
+
chalk@4.1.2:
dependencies:
ansi-styles: 4.3.0
@@ -4236,6 +4282,20 @@ snapshots:
parse5-htmlparser2-tree-adapter: 7.1.0
tslib: 2.8.1
+ cheerio@1.1.2:
+ dependencies:
+ cheerio-select: 2.1.0
+ dom-serializer: 2.0.0
+ domhandler: 5.0.3
+ domutils: 3.2.2
+ encoding-sniffer: 0.2.1
+ htmlparser2: 10.0.0
+ parse5: 7.3.0
+ parse5-htmlparser2-tree-adapter: 7.1.0
+ parse5-parser-stream: 7.1.2
+ undici: 7.14.0
+ whatwg-mimetype: 4.0.0
+
chokidar@4.0.3:
dependencies:
readdirp: 4.1.2
@@ -4369,6 +4429,11 @@ snapshots:
encodeurl@2.0.0: {}
+ encoding-sniffer@0.2.1:
+ dependencies:
+ iconv-lite: 0.6.3
+ whatwg-encoding: 3.1.1
+
enhanced-resolve@5.18.1:
dependencies:
graceful-fs: 4.2.11
@@ -4729,6 +4794,13 @@ snapshots:
hls.js@1.6.15: {}
+ htmlparser2@10.0.0:
+ dependencies:
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ domutils: 3.2.2
+ entities: 6.0.1
+
htmlparser2@8.0.2:
dependencies:
domelementtype: 2.3.0
@@ -5044,6 +5116,10 @@ snapshots:
domhandler: 5.0.3
parse5: 7.3.0
+ parse5-parser-stream@7.1.2:
+ dependencies:
+ parse5: 7.3.0
+
parse5@7.3.0:
dependencies:
entities: 6.0.1
@@ -5687,6 +5763,12 @@ snapshots:
w3c-keyname@2.2.8: {}
+ whatwg-encoding@3.1.1:
+ dependencies:
+ iconv-lite: 0.6.3
+
+ whatwg-mimetype@4.0.0: {}
+
which@2.0.2:
dependencies:
isexe: 2.0.0
diff --git a/src/lib/cards/PhotoGalleryCard/PhotoGalleryCard.svelte b/src/lib/cards/PhotoGalleryCard/PhotoGalleryCard.svelte
new file mode 100644
index 0000000..815267d
--- /dev/null
+++ b/src/lib/cards/PhotoGalleryCard/PhotoGalleryCard.svelte
@@ -0,0 +1,67 @@
+
+
+
+ {#each (feed ?? []).slice(0, 20) as photo}{/each}
+
+ 4 ? 3 : 2}
+ />
+
diff --git a/src/lib/cards/PhotoGalleryCard/index.ts b/src/lib/cards/PhotoGalleryCard/index.ts
new file mode 100644
index 0000000..e50992b
--- /dev/null
+++ b/src/lib/cards/PhotoGalleryCard/index.ts
@@ -0,0 +1,58 @@
+import type { CardDefinition } from '../types';
+import { getRecord, listRecords } from '$lib/oauth/atproto';
+import PhotoGalleryCard from './PhotoGalleryCard.svelte';
+import { parseUri } from '$lib/oauth/utils';
+import type { Record as ListRecord } from '@atproto/api/dist/client/types/com/atproto/repo/listRecords';
+
+export const PhotoGalleryCardDefinition = {
+ type: 'photoGallery',
+ contentComponent: PhotoGalleryCard,
+ createNew: (card) => {
+ // random grain.social url for testing
+ card.cardData.galleryUri =
+ 'at://did:plc:tas6hj2xjrqben5653v5kohk/social.grain.gallery/3mclhsljs6h2w';
+
+ card.w = 4;
+ card.mobileW = 8;
+ card.h = 3;
+ card.mobileH = 6;
+ },
+ loadData: async (items) => {
+ const itemsData: Record = {};
+
+ const galleryItems: Record = {
+ 'social.grain.gallery.item': undefined
+ };
+
+ for (const item of items) {
+ if (!item.cardData.galleryUri) continue;
+
+ const { did, collection } = parseUri(item.cardData.galleryUri);
+
+ if (collection === 'social.grain.gallery') {
+ const itemCollection = 'social.grain.gallery.item';
+
+ if (!galleryItems[itemCollection]) {
+ galleryItems[itemCollection] = await listRecords({
+ did,
+ collection: itemCollection
+ });
+ }
+
+ const images = galleryItems['social.grain.gallery.item']
+ ?.filter((i) => i.value.gallery === item.cardData.galleryUri)
+ .map(async (i) => {
+ const itemData = parseUri(i.value.item as string);
+ const record = await getRecord(itemData);
+ return { ...record, value: { ...record.value, ...i.value } };
+ });
+
+ itemsData[item.cardData.galleryUri] = await Promise.all(images);
+ }
+ }
+
+ return itemsData;
+ },
+ minW: 4
+ //sidebarButtonText: 'Photo Gallery'
+} as CardDefinition & { type: 'photoGallery' };
diff --git a/src/lib/cards/index.ts b/src/lib/cards/index.ts
index 439ea53..b6f38a8 100644
--- a/src/lib/cards/index.ts
+++ b/src/lib/cards/index.ts
@@ -20,6 +20,7 @@ import { BlueskyProfileCardDefinition } from './BlueskyProfileCard';
import { GithubProfileCardDefitition } from './GitHubProfileCard';
import { PopfeedReviewsCardDefinition } from './PopfeedReviews';
import { TealFMPlaysCardDefinition } from './TealFMPlaysCard';
+import { PhotoGalleryCardDefinition } from './PhotoGalleryCard';
export const AllCardDefinitions = [
ImageCardDefinition,
@@ -42,7 +43,8 @@ export const AllCardDefinitions = [
GithubProfileCardDefitition,
TetrisCardDefinition,
PopfeedReviewsCardDefinition,
- TealFMPlaysCardDefinition
+ TealFMPlaysCardDefinition,
+ PhotoGalleryCardDefinition
] as const;
export const CardDefinitionsByType = AllCardDefinitions.reduce(
diff --git a/src/lib/oauth/auth.svelte.ts b/src/lib/oauth/auth.svelte.ts
index ea595e7..9c8f995 100644
--- a/src/lib/oauth/auth.svelte.ts
+++ b/src/lib/oauth/auth.svelte.ts
@@ -54,6 +54,7 @@ export async function initClient() {
if (params.size > 0) {
await finalizeLogin(params, did);
} else if (did) {
+ console.log('resuming session');
await resumeSession(did);
}
@@ -118,7 +119,12 @@ async function finalizeLogin(params: URLSearchParams, did?: string) {
async function resumeSession(did: string) {
try {
- const session = await getSession(did as `did:${string}`, { allowStale: true });
+ const session = await getSession(did as `did:${string}:${string}`, { allowStale: true });
+ console.log('got session', session);
+
+ if (session.token.expires_at && session.token.expires_at < Date.now()) {
+ throw Error('session expired');
+ }
client.session = session;
setAgentAndXRPC(session);
@@ -128,6 +134,7 @@ async function resumeSession(did: string) {
client.isLoggedIn = true;
} catch (error) {
console.error('error resuming session', error);
+ logout();
}
}
diff --git a/src/lib/website/Account.svelte b/src/lib/website/Account.svelte
new file mode 100644
index 0000000..3538bb2
--- /dev/null
+++ b/src/lib/website/Account.svelte
@@ -0,0 +1,39 @@
+
+
+{#if client.isLoggedIn && client.profile}
+
+
+ {#snippet child({ props })}
+
+ {/snippet}
+
+
+
+
+{:else}
+
+ Login to edit your page
+
+
+
+{/if}
diff --git a/src/lib/website/EditBar.svelte b/src/lib/website/EditBar.svelte
new file mode 100644
index 0000000..9768157
--- /dev/null
+++ b/src/lib/website/EditBar.svelte
@@ -0,0 +1,278 @@
+
+
+
+
+
+
+{#if client.isLoggedIn && client.profile?.did === data.did}
+
+
+
+
+
+
+
+ {#snippet child({ props })}
+
+ {/snippet}
+ {
+ if (event.code === 'Enter') {
+ addLink(linkValue);
+ event.preventDefault();
+ }
+ }}
+ placeholder="Enter link"
+ />
+
+
+
+
+
+ {#if dev}
+
+ {/if}
+
+
+
+
+
+
+
+
+
+
+
+{/if}
diff --git a/src/lib/website/EditableWebsite.svelte b/src/lib/website/EditableWebsite.svelte
index 4e966d4..4eda88a 100644
--- a/src/lib/website/EditableWebsite.svelte
+++ b/src/lib/website/EditableWebsite.svelte
@@ -32,6 +32,8 @@
import Settings from './Settings.svelte';
import Head from './Head.svelte';
import { compressImage } from '../helper';
+ import Account from './Account.svelte';
+ import EditBar from './EditBar.svelte';
let {
data
@@ -39,8 +41,6 @@
data: WebsiteData;
} = $props();
- let imageInputRef: HTMLInputElement | undefined = $state();
- let videoInputRef: HTMLInputElement | undefined = $state();
let imageDragOver = $state(false);
let imageDragPosition: { x: number; y: number } | null = $state(null);
@@ -136,9 +136,15 @@
async function save() {
isSaving = true;
- await savePage(data, items, publication);
+ try {
+ await savePage(data, items, publication);
- publication = JSON.stringify(data.publication);
+ publication = JSON.stringify(data.publication);
+ } catch (error) {
+ toast.error('Error saving page!');
+ } finally {
+ isSaving = false;
+ }
}
const sidebarItems = AllCardDefinitions.filter(
@@ -528,24 +534,9 @@
-
-
-
+
+
{#if !dev}
-
-
{#each sidebarItems as cardDef}
@@ -766,236 +755,18 @@
- {#if dev || (!client.isLoggedIn && !client.isInitializing) || client.profile?.did === data.did}
-
-
-
-
-
-
-
- {#snippet child({ props })}
-
- {/snippet}
- {
- if (event.code === 'Enter') {
- addLink(linkValue);
- event.preventDefault();
- }
- }}
- placeholder="Enter link"
- />
-
-
-
-
-
- {#if dev}
-
- {/if}
-
-
-
-
-
-
-
-
- {#if client.isLoggedIn}
-
- {:else}
-
{
- await login(handle);
- return true;
- }}
- />
- {/if}
-
-
- {/if}
+
diff --git a/src/lib/website/Profile.svelte b/src/lib/website/Profile.svelte
index c7f8108..4fd8c34 100644
--- a/src/lib/website/Profile.svelte
+++ b/src/lib/website/Profile.svelte
@@ -6,6 +6,7 @@
import { env } from '$env/dynamic/public';
import type { WebsiteData } from '$lib/types';
import { getDescription, getName } from '$lib/helper';
+ import { page } from '$app/state';
let {
data,
@@ -51,7 +52,7 @@
{#if showEditButton && client.isLoggedIn && client.profile?.did === data.did}
-
diff --git a/static/robots.txt b/static/robots.txt
new file mode 100644
index 0000000..b6dd667
--- /dev/null
+++ b/static/robots.txt
@@ -0,0 +1,3 @@
+# allow crawling everything by default
+User-agent: *
+Disallow:
--
2.51.2
From f4e2e6c7fd41bc6d3c8dfc4c964aa8ff98f72e91 Mon Sep 17 00:00:00 2001
From: Florian <45694132+flo-bit@users.noreply.github.com>
Date: Tue, 20 Jan 2026 05:57:01 +0100
Subject: [PATCH 2/2] add standard site document list, small fixes
---
.../BlogEntry.svelte | 32 +++++++++++++++
.../DateTime.svelte | 11 +++++
.../StandardSiteDocumentListCard.svelte | 41 +++++++++++++++++++
.../StandardSiteDocumentListCard/index.ts | 41 +++++++++++++++++++
.../TealFMPlaysCard/TealFMPlaysCard.svelte | 23 +++++------
src/lib/cards/index.ts | 4 +-
src/lib/website/Account.svelte | 2 +-
src/lib/website/EditBar.svelte | 2 +-
src/lib/website/load.ts | 7 ++++
9 files changed, 147 insertions(+), 16 deletions(-)
create mode 100644 src/lib/cards/StandardSiteDocumentListCard/BlogEntry.svelte
create mode 100644 src/lib/cards/StandardSiteDocumentListCard/DateTime.svelte
create mode 100644 src/lib/cards/StandardSiteDocumentListCard/StandardSiteDocumentListCard.svelte
create mode 100644 src/lib/cards/StandardSiteDocumentListCard/index.ts
diff --git a/src/lib/cards/StandardSiteDocumentListCard/BlogEntry.svelte b/src/lib/cards/StandardSiteDocumentListCard/BlogEntry.svelte
new file mode 100644
index 0000000..b1c30b3
--- /dev/null
+++ b/src/lib/cards/StandardSiteDocumentListCard/BlogEntry.svelte
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
diff --git a/src/lib/cards/StandardSiteDocumentListCard/DateTime.svelte b/src/lib/cards/StandardSiteDocumentListCard/DateTime.svelte
new file mode 100644
index 0000000..2d36c3b
--- /dev/null
+++ b/src/lib/cards/StandardSiteDocumentListCard/DateTime.svelte
@@ -0,0 +1,11 @@
+
+
+
diff --git a/src/lib/cards/StandardSiteDocumentListCard/StandardSiteDocumentListCard.svelte b/src/lib/cards/StandardSiteDocumentListCard/StandardSiteDocumentListCard.svelte
new file mode 100644
index 0000000..8ecebca
--- /dev/null
+++ b/src/lib/cards/StandardSiteDocumentListCard/StandardSiteDocumentListCard.svelte
@@ -0,0 +1,41 @@
+
+
+
+ {#each feed ?? [] as document}
+
+ {/each}
+
diff --git a/src/lib/cards/StandardSiteDocumentListCard/index.ts b/src/lib/cards/StandardSiteDocumentListCard/index.ts
new file mode 100644
index 0000000..67456a2
--- /dev/null
+++ b/src/lib/cards/StandardSiteDocumentListCard/index.ts
@@ -0,0 +1,41 @@
+import { getRecord, listRecords } from '$lib/oauth/atproto';
+import { parseUri } from '$lib/oauth/utils';
+import type { CardDefinition } from '../types';
+import StandardSiteDocumentListCard from './StandardSiteDocumentListCard.svelte';
+
+export const StandardSiteDocumentListCardDefinition = {
+ type: 'publicationList',
+ contentComponent: StandardSiteDocumentListCard,
+ createNew: (card) => {
+ card.w = 4;
+ card.mobileW = 8;
+ card.mobileH = 6;
+ },
+
+ loadData: async (items, { did }) => {
+ const records = await listRecords({ did, collection: 'site.standard.document' });
+
+ const publications: Record = {};
+ for (const record of records) {
+ const site = record.value.site as string;
+
+ if (site.startsWith('at://')) {
+ if (!publications[site]) {
+ const siteParts = parseUri(site);
+
+ const publicationRecord = await getRecord(siteParts);
+
+ publications[site] = publicationRecord.value.url as string;
+ }
+
+ record.value.href = publications[site] + record.value.path;
+ } else {
+ record.value.href = site + record.value.path;
+ }
+ }
+
+ return records;
+ },
+
+ sidebarButtonText: 'site.standard.document list'
+} as CardDefinition & { type: 'site.standard.document list' };
diff --git a/src/lib/cards/TealFMPlaysCard/TealFMPlaysCard.svelte b/src/lib/cards/TealFMPlaysCard/TealFMPlaysCard.svelte
index b26f0b1..9f3b0ff 100644
--- a/src/lib/cards/TealFMPlaysCard/TealFMPlaysCard.svelte
+++ b/src/lib/cards/TealFMPlaysCard/TealFMPlaysCard.svelte
@@ -16,25 +16,22 @@
let handle = getHandleContext();
onMount(async () => {
- console.log(feed);
- if (!feed) {
- feed = (await CardDefinitionsByType[item.cardType]?.loadData?.([], {
- did,
- handle
- })) as any;
+ if (feed) return;
- console.log(feed);
+ feed = (await CardDefinitionsByType[item.cardType]?.loadData?.([], {
+ did,
+ handle
+ })) as any;
- data[item.cardType] = feed;
- }
+ data[item.cardType] = feed;
});
function isNumeric(str: string) {
- if (typeof str != 'string') return false; // we only process strings!
+ if (typeof str != 'string') return false;
return (
- !isNaN(str) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...
+ !isNaN(str) &&
!isNaN(parseFloat(str))
- ); // ...and ensure strings of whitespace fail
+ );
}
@@ -74,7 +71,7 @@
{/snippet}
-{:else}
+{:else if !client.isInitializing}
diff --git a/src/lib/website/EditBar.svelte b/src/lib/website/EditBar.svelte
index 9768157..a192e32 100644
--- a/src/lib/website/EditBar.svelte
+++ b/src/lib/website/EditBar.svelte
@@ -60,7 +60,7 @@
bind:this={videoInputRef}
/>
-{#if client.isLoggedIn && client.profile?.did === data.did}
+{#if dev || (client.isLoggedIn && client.profile?.did === data.did)}
ONE_DAY) {
+ console.log('skipping cache because of age');
+ return;
+ }
+
result.page = 'blento.' + page;
result.publication = (result.publications as ListRecord[]).find(
--
2.51.2