feat: store 'bridged' posts in note data and display it
All checks were successful
create archive with lfs / tag (push) Successful in 12s

This commit is contained in:
dusk 2024-11-23 04:28:16 +03:00
parent 22c773c38e
commit ce0871b052
Signed by: dusk
SSH Key Fingerprint: SHA256:Abmvag+juovVufZTxyWY8KcVgrznxvBjQpJesv071Aw
4 changed files with 57 additions and 24 deletions

View File

@ -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 | Agent>(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 ?? "" })

View File

@ -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
}

View File

@ -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<string, string> = {
bsky: "rgb(0, 133, 255)",
}
</script>
<svelte:head>
@ -33,15 +41,19 @@
"
>
<pre class="language-bash"><code class="language-bash"><nobr>
<Token v="[" punct/>gazesystems <Token v="/log/" keywd/><Token v="]$" punct/> <Token v="source" funct/> log.nu
<Token v="[" punct/>gazesystems <Token v="/" keywd/><Token v="]$" punct/> <Token v="source" funct/> <Token v="scripts/log.nu" />
<br>
<Token v="[" punct/>gazesystems <Token v="/log/" keywd/><Token v="]$" punct/> <Token v="ls" funct/> log <Token v="|" punct/> <Token v="each" funct/> <Token v="&#123;" punct/><Token v="|" punct/>file<Token v="|" punct/> <Token v="render" funct/> <Token v="(" punct/><Token v="open" funct/> $file.name<Token v=")" punct/><Token v="&#125;" punct/>
<Token v="[" punct/>gazesystems <Token v="/" keywd/><Token v="]$" punct/> <Token v="ls" funct/> <Token v="log" /> <Token v="|" punct/> <Token v="each" funct/> <Token v="&#123;" punct/><Token v="|" punct/><Token v="file"/><Token v="|" punct/> <Token v="render" funct/> <Token v="(" punct/><Token v="open" funct/> <Token v="$file.name" /><Token v=")" punct/><Token v="&#125;" punct/>
<br>
<br>
{#each data.notes as [noteId, note], index}
{@const isHighlighted = noteId === data.highlightedNote}
<div class="text-wrap break-words max-w-[70ch] leading-none">
<Token v={renderDate(note.published)} small={!isHighlighted}/> <Token v={noteId} keywd small={!isHighlighted}/><Token v="#" punct/>&nbsp;&nbsp;<Token v={note.content} str/>
{#each note.outgoingLinks ?? [] as {name, link}}
{@const color = outgoingLinkColors[name]}
<span class="text-sm"><Token v="(" punct/><a style="color: {color};{getTextShadowStyle(color)}" href={link}>{name}</a><Token v=")" punct/></span>
{/each}
</div>
{#if index < data.notes.size - 1}
<div class="mt-3"/>

View File

@ -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',