From ce0871b0527a846460fe75b337c803506aba0aa0 Mon Sep 17 00:00:00 2001 From: dusk Date: Sat, 23 Nov 2024 04:28:16 +0300 Subject: [PATCH] feat: store 'bridged' posts in note data and display it --- src/lib/bluesky.ts | 13 +++++++++- src/lib/notes.ts | 9 +++++-- src/routes/log/+page.svelte | 16 ++++++++++-- src/routes/log/create/+server.ts | 43 ++++++++++++++++++-------------- 4 files changed, 57 insertions(+), 24 deletions(-) diff --git a/src/lib/bluesky.ts b/src/lib/bluesky.ts index ef17783..d8e3793 100644 --- a/src/lib/bluesky.ts +++ b/src/lib/bluesky.ts @@ -1,5 +1,5 @@ import { env } from '$env/dynamic/private' -import { Agent, CredentialSession } from '@atproto/api' +import { Agent, CredentialSession, RichText } from '@atproto/api' import { get, writable } from 'svelte/store' const bskyClient = writable(null) @@ -13,6 +13,17 @@ export const getBskyClient = async () => { return client } +export const postToBsky = async (text: string) => { + let client = await getBskyClient() + const rt = new RichText({ text }) + await rt.detectFacets(client) + const {uri} = await client.post({ + text: rt.text, + facets: rt.facets, + }) + return uri +} + const loginToBsky = async () => { const creds = new CredentialSession(new URL("https://bsky.social")) await creds.login({ identifier: 'gaze.systems', password: env.BSKY_PASSWORD ?? "" }) diff --git a/src/lib/notes.ts b/src/lib/notes.ts index 766549a..1f31ff4 100644 --- a/src/lib/notes.ts +++ b/src/lib/notes.ts @@ -2,9 +2,15 @@ import { existsSync, readFileSync, writeFileSync } from 'fs' import { nanoid } from 'nanoid' import { env } from '$env/dynamic/private' +export interface OutgoingLinkData { + name: string, + link: string, +} + export interface Note { content: string, published: number, + outgoingLinks?: OutgoingLinkData[], } type NoteId = string @@ -32,8 +38,7 @@ export const writeNote = (id: NoteId, note: Note) => { writeNotesList([id].concat(noteList)) } } -export const createNote = (note: Note) => { - const id = genNoteId() +export const createNote = (id: NoteId, note: Note) => { writeNote(id, note) return id } diff --git a/src/routes/log/+page.svelte b/src/routes/log/+page.svelte index 0429c82..0aa9a9a 100644 --- a/src/routes/log/+page.svelte +++ b/src/routes/log/+page.svelte @@ -15,6 +15,14 @@ } const highlightedNote = data.notes.get(data.highlightedNote ?? '') ?? null + + // this is ASS this should be a tailwind class + const getTextShadowStyle = (color: string) => { + return `text-shadow: 0 0 1px theme(colors.ralsei.black), 0 0 5px ${color};` + } + const outgoingLinkColors: Record = { + bsky: "rgb(0, 133, 255)", + } @@ -33,15 +41,19 @@ " >

-gazesystems   log.nu
+gazesystems   
 
-gazesystems log file $file.name +gazesystems

{#each data.notes as [noteId, note], index} {@const isHighlighted = noteId === data.highlightedNote}
   +{#each note.outgoingLinks ?? [] as {name, link}} +{@const color = outgoingLinkColors[name]} +{name} +{/each}
{#if index < data.notes.size - 1}
diff --git a/src/routes/log/create/+server.ts b/src/routes/log/create/+server.ts index ec89ce9..00954aa 100644 --- a/src/routes/log/create/+server.ts +++ b/src/routes/log/create/+server.ts @@ -1,9 +1,7 @@ import { env } from '$env/dynamic/private'; import { PUBLIC_BASE_URL } from '$env/static/public'; -import { getBskyClient } from '$lib/bluesky.ts'; -import { createNote } from '$lib/notes.js'; -import { RichText } from '@atproto/api'; -import { get } from 'svelte/store'; +import { postToBsky } from '$lib/bluesky'; +import { createNote, genNoteId, type Note } from '$lib/notes'; interface NoteData { content: string, @@ -15,26 +13,33 @@ export const POST = async ({ request }) => { if (token !== env.GAZEBOT_TOKEN) { return new Response("rizz failed", { status: 403 }) } + // get id + const noteId = genNoteId() // get note data const noteData: NoteData = await request.json() - console.log("want to create note with data: ", noteData) - // create note - const published = Date.now() - const noteId = createNote({ content: noteData.content, published }) + console.log(`want to create note #${noteId} with data: `, noteData) + // get a date before we start publishing to other platforms + let note: Note = { + content: noteData.content, + published: Date.now(), + outgoingLinks: [], + } + let errors: string[] = [] // bridge to bsky if want to bridge if (noteData.bskyPosse) { - let client = await getBskyClient() - const rt = new RichText({ - text: `${noteData.content} (${PUBLIC_BASE_URL}/log?id=${noteId})`, - }) - await rt.detectFacets(client) - await client.post({ - text: rt.text, - facets: rt.facets, - }) + const postContent = `${noteData.content} (${PUBLIC_BASE_URL}/log?id=${noteId})` + try { + const bskyUrl = await postToBsky(postContent) + note.outgoingLinks?.push({name: "bsky", link: bskyUrl}) + } catch(why) { + console.log(`failed to post note #${noteId} to bsky: `, why) + errors.push(`error while posting to bsky: ${why}`) + } } - // send back created note id - return new Response(JSON.stringify({ noteId }), { + // create note (this should never fail otherwise it would defeat the whole purpose lol) + createNote(noteId, note) + // send back created note id and any errors that occurred + return new Response(JSON.stringify({ noteId, errors }), { headers: { 'content-type': 'application/json', 'cache-control': 'no-store',