gubes mirror. how does this work
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

uooguh

leah 0618bb1c 0bd5738a

+270 -203
+4
core/parser.ts
··· 144 144 // return value; 145 145 // } 146 146 147 + static get_id(tags: Record<string, string | null>) { 148 + return tags["msgid"] ?? tags["time"] ?? new Date(Date.now()).toISOString(); 149 + } 150 + 147 151 toString(recipient: "client" | "server" = "client"): string { 148 152 let result = []; 149 153
+2 -2
neo/src/buffer/view.tsx
··· 2 2 import { Signal, useSignal } from "@preact/signals"; 3 3 import { execute_command } from "@src/chat/commands"; 4 4 import ReadMarkers, { ReadMarker } from "@src/chat/read"; 5 - import { store_message } from "@src/storage"; 6 5 import { message_style } from "@src/support"; 7 6 import { FunctionalComponent, RefObject, createContext } from "preact"; 8 7 import { useEffect, useRef } from "preact/hooks"; ··· 13 12 import { HTMLProps } from "preact/compat"; 14 13 import Trangle from "~icons/ph/triangle-fill"; 15 14 import { squish_messages } from "./squisher"; 15 + import Storage from "@src/chat/storage"; 16 16 17 17 async function load_msgs(buffer: ChatBuffer, limit = 100): Promise<IrcMessage[]> { 18 18 let count = 0; ··· 94 94 } 95 95 96 96 const msg = buffer.privmsg(text); 97 - store_message(buffer.conn, msg); 97 + Storage.store_message(msg, buffer.conn); 98 98 msgs.value = [...msgs.value, msg]; 99 99 }} 100 100 />
+2
neo/src/chat/colours.ts
··· 6 6 "weezer", 7 7 "aubergine", 8 8 "bubblegum", 9 + "denim", 10 + "olive", 9 11 ] 10 12 11 13 export const pick_colour = (string: string): string => {
+2 -2
neo/src/chat/commands.ts
··· 1 - import { store_message } from "@src/storage"; 2 1 import { ChatBuffer, IrcChannel } from "tubes_core/channel"; 2 + import Storage from "./storage"; 3 3 4 4 export interface TubesCommand { 5 5 description: string, ··· 31 31 description: "", 32 32 activate: async (text, buffer) => { 33 33 const msg = buffer.privmsg(`\x01ACTION ${text}\x01`) 34 - store_message(buffer.conn, msg); 34 + Storage.store_message(msg, buffer.conn); 35 35 }, 36 36 }, 37 37 "topic": {
+4 -8
neo/src/chat/conns.ts
··· 1 + import { computed, signal, type Signal } from "@preact/signals"; 1 2 import type { Connection } from "tubes_core"; 3 + import { ChatBuffer } from "tubes_core/channel"; 4 + import type { ConnectionConfig } from "tubes_core/connection"; 2 5 import { Connection as WsConnection } from "tubes_core/ws"; 3 - import { computed, signal, type Signal } from "@preact/signals"; 4 - import type { ConnectionConfig } from "tubes_core/connection"; 5 - import tubes_history from "./history"; 6 - import { store_message } from "@src/storage"; 7 - import { ChatBuffer } from "tubes_core/channel"; 8 6 import { adapters } from "./adapters"; 9 7 import Config from "./config"; 10 8 import tubes_handler from "./handler"; 9 + import tubes_history from "./history"; 11 10 12 11 const local_connections: Signal<Connection[]> = signal([]); 13 12 export const connections: Signal<Connection[]> = computed(() => [ ··· 32 31 const conn: WsConnection = new WsConnection(config, { 33 32 history_fetcher: tubes_history, 34 33 handler: tubes_handler, 35 - on_connect(conn) { 36 - conn.queue.subscribe("tubes storage", (msg) => store_message(conn, msg)); 37 - }, 38 34 }); 39 35 40 36 return conn;
+11
neo/src/chat/handler.ts
··· 1 1 import { default_handler, MessageHandler } from "tubes_core/handler"; 2 2 import ReadMarkers from "./read"; 3 + import Storage from "./storage"; 3 4 4 5 const tubes_handler: MessageHandler = async (msg, conn) => { 6 + if ( 7 + msg.command == "PRIVMSG" || 8 + msg.command == "NOTICE" || 9 + msg.command == "TOPIC" || 10 + msg.command == "PART" || 11 + msg.command == "JOIN" 12 + ) { 13 + Storage.store_message(msg, conn); 14 + } 15 + 5 16 switch (msg.command) { 6 17 case "PRIVMSG": { 7 18 const target = msg.params?.[0];
+24 -33
neo/src/chat/history.ts
··· 1 - import { db } from "@src/storage"; 2 1 import { Connection } from "tubes_core"; 3 2 import { FetchHistoryParams } from "tubes_core/history"; 4 3 import { IrcMessage } from "tubes_core/parser"; 5 4 import History from "tubes_core/history"; 5 + import Storage, { StoredMessage } from "./storage"; 6 6 7 7 const fuzz = 1; 8 8 ··· 10 10 conn: Connection, 11 11 ...[target, range, limit]: FetchHistoryParams 12 12 ): Promise<IrcMessage[]> { 13 + let res: StoredMessage[] = []; 13 14 14 - const res = await db.messages 15 - .where({ adapter_id: conn.adapter_id ?? "*", connection_id: conn.id, target }) 16 - .filter(x => { 17 - // todo: make unslow 18 - if (range == "latest") { 19 - return true; 20 - } 15 + if (typeof range == "object" && "before" in range) { 16 + res = await Storage.before(range.before); 17 + } 21 18 22 - if ("before" in range) { 23 - const res = x.timestamp.getTime() - range.before.getTime(); 24 - return res >= fuzz 25 - } 19 + if (typeof range == "object" && "after" in range) { 20 + res = await Storage.before(range.after); 21 + } 26 22 27 - if ("after" in range) { 28 - const res = range.after.getTime() - x.timestamp.getTime(); 29 - return res >= fuzz; 30 - } 23 + if (range == "latest") { 24 + res = await Storage.before(new Date(Date.now())); 25 + } 31 26 32 - return false; 33 - }) 34 - .limit(limit) 35 - .sortBy('timestamp'); 36 27 37 - 38 - const msgs = res.map(x => x.message).toReversed(); 28 + // if (res.length == 0) { 29 + // await History.chathistory(conn, target, range, limit); 30 + // } 39 31 40 - if (msgs.length == 0) { 41 - await History.chathistory(conn, target, range, limit); 42 - return [] 43 - } 32 + // if (msgs.length < limit) { 33 + // const last = msgs[msgs.length - 1]; 34 + // const range = { before: last.timestamp ?? new Date(Date.now()) }; 35 + // const fetched = await History.chathistory(conn, target, range, limit); 44 36 45 - if (msgs.length < limit) { 46 - const last = msgs[msgs.length - 1]; 47 - const range = { before: last.timestamp ?? new Date(Date.now()) }; 48 - const fetched = await History.chathistory(conn, target, range, limit); 37 + // for (const msg of fetched) { 38 + // store_message(conn, msg); 39 + // } 49 40 50 - return msgs.concat(fetched) 51 - } 41 + // return fetched.concat(msgs) 42 + // } 52 43 53 - return msgs; 44 + return res; 54 45 }
+74
neo/src/chat/storage.ts
··· 1 + import * as idb from 'idb'; 2 + import { Connection } from 'tubes_core'; 3 + import { IrcMessage } from 'tubes_core/parser'; 4 + 5 + const db_name = "neotubes"; 6 + const version = 1; 7 + 8 + export class StoredMessage extends IrcMessage { 9 + id: string; 10 + target: string; 11 + connection_id: string; 12 + adapter_id: string; 13 + 14 + constructor(msg: IrcMessage, target: string, connection: Connection) { 15 + super(msg); 16 + this.id = IrcMessage.get_id(msg.tags ?? {}); 17 + this.target = target; 18 + this.connection_id = connection.id; 19 + this.adapter_id = connection.adapter_id ?? ""; 20 + } 21 + } 22 + 23 + class CoolDatabase { 24 + private constructor(public db: idb.IDBPDatabase<unknown>) { } 25 + 26 + static async init() { 27 + const db = await idb.openDB(db_name, version, { 28 + upgrade(db, old) { 29 + switch (old) { 30 + case 0: { 31 + const msgs = db.createObjectStore("messages", { 32 + keyPath: ["id", "target", "connection_id", "adapter_id"], 33 + }); 34 + msgs.createIndex("timestamps", "timestamp"); 35 + } 36 + } 37 + } 38 + }); 39 + 40 + return new CoolDatabase(db); 41 + } 42 + 43 + async store_message(msg: IrcMessage, conn: Connection) { 44 + // todo: the target is sometimes in a different parameter 45 + const target = msg.params?.[0] ?? ""; 46 + const stored = new StoredMessage(msg, target, conn); 47 + const trans = this.db.transaction("messages", "readwrite"); 48 + 49 + const store = trans.objectStore("messages"); 50 + const key = await store.add(stored); 51 + 52 + trans.commit(); 53 + 54 + return key; 55 + } 56 + 57 + async before(id: Date | string) { 58 + const trans = this.db.transaction("messages", "readwrite"); 59 + 60 + const store = trans.objectStore("messages"); 61 + 62 + console.log(id instanceof Date); 63 + 64 + if (id instanceof Date) { 65 + const timestamps = store.index("timestamps"); 66 + const msgs = await timestamps.getAll(IDBKeyRange.upperBound(id)) as StoredMessage[]; 67 + return msgs; 68 + } else { 69 + return []; 70 + } 71 + } 72 + } 73 + 74 + export default await CoolDatabase.init();
+121 -99
neo/src/css/main.css
··· 1 1 :root { 2 - --colour-ectoplasm-100: rgba(224, 247, 217, 1); 3 - --colour-ectoplasm-200: rgba(200, 242, 192, 1); 4 - --colour-ectoplasm-300: rgba(179, 241, 165, 1); 5 - --colour-ectoplasm-400: rgba(141, 219, 125, 1); 6 - --colour-ectoplasm-500: rgba(112, 202, 98, 1); 7 - --colour-ectoplasm-600: rgba(84, 180, 71, 1); 8 - --colour-ectoplasm-700: rgba(60, 126, 54, 1); 9 - --colour-ectoplasm-800: rgba(43, 92, 47, 1); 10 - --colour-ectoplasm-900: rgba(32, 74, 32, 1); 11 - --colour-ectoplasm-950: rgba(21, 53, 21, 1); 12 - --colour-ectoplasm-50: rgba(246, 253, 244, 1); 13 - --colour-aubergine-100: rgba(238, 229, 250, 1); 14 - --colour-aubergine-200: rgba(224, 207, 246, 1); 15 - --colour-aubergine-300: rgba(196, 158, 244, 1); 16 - --colour-aubergine-400: rgba(157, 97, 232, 1); 17 - --colour-aubergine-500: rgba(127, 48, 225, 1); 18 - --colour-aubergine-600: rgba(110, 42, 197, 1); 19 - --colour-aubergine-700: rgba(85, 30, 154, 1); 20 - --colour-aubergine-800: rgba(62, 22, 113, 1); 21 - --colour-aubergine-900: rgba(48, 13, 93, 1); 22 - --colour-aubergine-950: rgba(28, 4, 56, 1); 23 - --colour-aubergine-50: rgba(248, 244, 253, 1); 24 - --colour-weezer-100: rgba(216, 237, 245, 1); 25 - --colour-weezer-200: rgba(192, 226, 240, 1); 26 - --colour-weezer-300: rgba(153, 206, 227, 1); 27 - --colour-weezer-400: rgba(107, 186, 221, 1); 28 - --colour-weezer-500: rgba(75, 164, 212, 1); 29 - --colour-weezer-600: rgba(65, 146, 191, 1); 30 - --colour-weezer-700: rgba(51, 117, 160, 1); 31 - --colour-weezer-800: rgba(36, 84, 119, 1); 32 - --colour-weezer-900: rgba(25, 62, 86, 1); 33 - --colour-weezer-950: rgba(13, 39, 54, 1); 34 - --colour-weezer-50: rgba(244, 250, 253, 1); 35 - --colour-yellow-100: rgba(251, 244, 200, 1); 36 - --colour-yellow-200: rgba(247, 234, 156, 1); 37 - --colour-yellow-300: rgba(244, 227, 126, 1); 38 - --colour-yellow-400: rgba(241, 218, 91, 1); 39 - --colour-yellow-500: rgba(239, 202, 54, 1); 40 - --colour-yellow-600: rgba(225, 175, 15, 1); 41 - --colour-yellow-700: rgba(192, 139, 16, 1); 42 - --colour-yellow-800: rgba(128, 90, 34, 1); 43 - --colour-yellow-900: rgba(86, 63, 24, 1); 44 - --colour-yellow-950: rgba(58, 39, 9, 1); 45 - --colour-yellow-50: rgba(254, 252, 240, 1); 46 - --colour-orange-100: rgba(248, 225, 214, 1); 47 - --colour-orange-200: rgba(245, 207, 192, 1); 48 - --colour-orange-300: rgba(238, 175, 152, 1); 49 - --colour-orange-400: rgba(233, 144, 112, 1); 50 - --colour-orange-500: rgba(233, 124, 87, 1); 51 - --colour-orange-600: rgba(225, 87, 46, 1); 52 - --colour-orange-700: rgba(198, 69, 30, 1); 53 - --colour-orange-800: rgba(127, 49, 25, 1); 54 - --colour-orange-900: rgba(97, 36, 17, 1); 55 - --colour-orange-950: rgba(55, 20, 7, 1); 56 - --colour-orange-50: rgba(252, 244, 239, 1); 57 - --colour-red-100: rgba(244, 217, 220, 1); 58 - --colour-red-200: rgba(240, 187, 196, 1); 59 - --colour-red-300: rgba(237, 163, 171, 1); 60 - --colour-red-400: rgba(231, 136, 145, 1); 61 - --colour-red-500: rgba(218, 85, 96, 1); 62 - --colour-red-600: rgba(217, 57, 64, 1); 63 - --colour-red-700: rgba(189, 43, 46, 1); 64 - --colour-red-800: rgba(159, 36, 39, 1); 65 - --colour-red-900: rgba(123, 26, 29, 1); 66 - --colour-red-950: rgba(62, 10, 14, 1); 67 - --colour-red-50: rgba(251, 240, 241, 1); 68 - --colour-bubblegum-100: rgba(247, 219, 235, 1); 69 - --colour-bubblegum-200: rgba(238, 187, 216, 1); 70 - --colour-bubblegum-300: rgba(236, 163, 205, 1); 71 - --colour-bubblegum-400: rgba(234, 143, 196, 1); 72 - --colour-bubblegum-500: rgba(228, 108, 175, 1); 73 - --colour-bubblegum-600: rgba(223, 72, 153, 1); 74 - --colour-bubblegum-700: rgba(176, 46, 113, 1); 75 - --colour-bubblegum-800: rgba(131, 35, 87, 1); 76 - --colour-bubblegum-900: rgba(93, 20, 58, 1); 77 - --colour-bubblegum-950: rgba(56, 9, 35, 1); 78 - --colour-bubblegum-50: rgba(252, 239, 247, 1); 79 - --colour-grey-100: rgba(238, 238, 238, 1); 80 - --colour-grey-200: rgba(218, 218, 218, 1); 81 - --colour-grey-300: rgba(199, 198, 200, 1); 82 - --colour-grey-400: rgba(153, 148, 154, 1); 83 - --colour-grey-500: rgba(128, 124, 128, 1); 84 - --colour-grey-600: rgba(105, 101, 106, 1); 85 - --colour-grey-700: rgba(70, 67, 71, 1); 86 - --colour-grey-800: rgba(49, 46, 50, 1); 87 - --colour-grey-900: rgba(31, 29, 32, 1); 88 - --colour-grey-950: rgba(23, 21, 23, 1); 89 - --colour-grey-50: rgba(248, 248, 248, 1); 90 - --colour-brown-50: rgba(253, 248, 238, 1); 91 - --colour-brown-100: rgba(247, 238, 222, 1); 92 - --colour-brown-200: rgba(239, 210, 173, 1); 93 - --colour-brown-300: rgba(218, 169, 124, 1); 94 - --colour-brown-400: rgba(199, 142, 92, 1); 95 - --colour-brown-500: rgba(177, 111, 61, 1); 96 - --colour-brown-600: rgba(144, 86, 43, 1); 97 - --colour-brown-700: rgba(116, 69, 34, 1); 98 - --colour-brown-800: rgba(84, 47, 20, 1); 99 - --colour-brown-900: rgba(64, 36, 12, 1); 100 - --colour-brown-950: rgba(42, 24, 5, 1); 2 + --colour-ectoplasm-100: rgba(224,247,217,1); 3 + --colour-ectoplasm-200: rgba(200,242,192,1); 4 + --colour-ectoplasm-300: rgba(179,241,165,1); 5 + --colour-ectoplasm-400: rgba(141,219,125,1); 6 + --colour-ectoplasm-500: rgba(112,202,98,1); 7 + --colour-ectoplasm-600: rgba(84,180,71,1); 8 + --colour-ectoplasm-700: rgba(60,126,54,1); 9 + --colour-ectoplasm-800: rgba(43,92,47,1); 10 + --colour-ectoplasm-900: rgba(32,74,32,1); 11 + --colour-ectoplasm-950: rgba(21,53,21,1); 12 + --colour-ectoplasm-50: rgba(246,253,244,1); 13 + --colour-aubergine-100: rgba(238,229,250,1); 14 + --colour-aubergine-200: rgba(224,207,246,1); 15 + --colour-aubergine-300: rgba(196,158,244,1); 16 + --colour-aubergine-400: rgba(157,97,232,1); 17 + --colour-aubergine-500: rgba(127,48,225,1); 18 + --colour-aubergine-600: rgba(110,42,197,1); 19 + --colour-aubergine-700: rgba(85,30,154,1); 20 + --colour-aubergine-800: rgba(62,22,113,1); 21 + --colour-aubergine-900: rgba(48,13,93,1); 22 + --colour-aubergine-950: rgba(28,4,56,1); 23 + --colour-aubergine-50: rgba(248,244,253,1); 24 + --colour-weezer-100: rgba(216,237,245,1); 25 + --colour-weezer-200: rgba(192,226,240,1); 26 + --colour-weezer-300: rgba(153,206,227,1); 27 + --colour-weezer-400: rgba(107,186,221,1); 28 + --colour-weezer-500: rgba(75,164,212,1); 29 + --colour-weezer-600: rgba(65,146,191,1); 30 + --colour-weezer-700: rgba(51,117,160,1); 31 + --colour-weezer-800: rgba(36,84,119,1); 32 + --colour-weezer-900: rgba(25,62,86,1); 33 + --colour-weezer-950: rgba(13,39,54,1); 34 + --colour-weezer-50: rgba(244,250,253,1); 35 + --colour-yellow-100: rgba(251,244,200,1); 36 + --colour-yellow-200: rgba(247,234,156,1); 37 + --colour-yellow-300: rgba(244,227,126,1); 38 + --colour-yellow-400: rgba(241,218,91,1); 39 + --colour-yellow-500: rgba(239,202,54,1); 40 + --colour-yellow-600: rgba(225,175,15,1); 41 + --colour-yellow-700: rgba(192,139,16,1); 42 + --colour-yellow-800: rgba(128,90,34,1); 43 + --colour-yellow-900: rgba(86,63,24,1); 44 + --colour-yellow-950: rgba(58,39,9,1); 45 + --colour-yellow-50: rgba(254,252,240,1); 46 + --colour-orange-100: rgba(248,225,214,1); 47 + --colour-orange-200: rgba(245,207,192,1); 48 + --colour-orange-300: rgba(238,175,152,1); 49 + --colour-orange-400: rgba(233,144,112,1); 50 + --colour-orange-500: rgba(233,124,87,1); 51 + --colour-orange-600: rgba(225,87,46,1); 52 + --colour-orange-700: rgba(198,69,30,1); 53 + --colour-orange-800: rgba(127,49,25,1); 54 + --colour-orange-900: rgba(97,36,17,1); 55 + --colour-orange-950: rgba(55,20,7,1); 56 + --colour-orange-50: rgba(252,244,239,1); 57 + --colour-red-100: rgba(244,217,220,1); 58 + --colour-red-200: rgba(240,187,196,1); 59 + --colour-red-300: rgba(237,163,171,1); 60 + --colour-red-400: rgba(231,136,145,1); 61 + --colour-red-500: rgba(218,85,96,1); 62 + --colour-red-600: rgba(217,57,64,1); 63 + --colour-red-700: rgba(189,43,46,1); 64 + --colour-red-800: rgba(159,36,39,1); 65 + --colour-red-900: rgba(123,26,29,1); 66 + --colour-red-950: rgba(62,10,14,1); 67 + --colour-red-50: rgba(251,240,241,1); 68 + --colour-bubblegum-100: rgba(254,229,243,1); 69 + --colour-bubblegum-200: rgba(250,206,231,1); 70 + --colour-bubblegum-300: rgba(241,170,211,1); 71 + --colour-bubblegum-400: rgba(229,131,188,1); 72 + --colour-bubblegum-500: rgba(228,108,175,1); 73 + --colour-bubblegum-600: rgba(223,72,153,1); 74 + --colour-bubblegum-700: rgba(176,46,113,1); 75 + --colour-bubblegum-800: rgba(131,35,87,1); 76 + --colour-bubblegum-900: rgba(93,20,58,1); 77 + --colour-bubblegum-950: rgba(56,9,35,1); 78 + --colour-bubblegum-50: rgba(255,245,251,1); 79 + --colour-grey-100: rgba(238,238,238,1); 80 + --colour-grey-200: rgba(218,218,218,1); 81 + --colour-grey-300: rgba(199,198,200,1); 82 + --colour-grey-400: rgba(153,148,154,1); 83 + --colour-grey-500: rgba(128,124,128,1); 84 + --colour-grey-600: rgba(105,101,106,1); 85 + --colour-grey-700: rgba(70,67,71,1); 86 + --colour-grey-800: rgba(49,46,50,1); 87 + --colour-grey-900: rgba(31,29,32,1); 88 + --colour-grey-950: rgba(23,21,23,1); 89 + --colour-grey-50: rgba(248,248,248,1); 90 + --colour-brown-50: rgba(253,248,238,1); 91 + --colour-brown-100: rgba(247,238,222,1); 92 + --colour-brown-200: rgba(239,210,173,1); 93 + --colour-brown-300: rgba(218,169,124,1); 94 + --colour-brown-400: rgba(199,142,92,1); 95 + --colour-brown-500: rgba(177,111,61,1); 96 + --colour-brown-600: rgba(144,86,43,1); 97 + --colour-brown-700: rgba(116,69,34,1); 98 + --colour-brown-800: rgba(84,47,20,1); 99 + --colour-brown-900: rgba(64,36,12,1); 100 + --colour-brown-950: rgba(42,24,5,1); 101 + --colour-olive-50: rgba(248,253,231,1); 102 + --colour-olive-100: rgba(238,249,201,1); 103 + --colour-olive-200: rgba(223,238,158,1); 104 + --colour-olive-300: rgba(221,234,122,1); 105 + --colour-olive-400: rgba(202,212,89,1); 106 + --colour-olive-500: rgba(175,185,69,1); 107 + --colour-olive-600: rgba(153,157,54,1); 108 + --colour-olive-700: rgba(114,118,27,1); 109 + --colour-olive-800: rgba(91,95,22,1); 110 + --colour-olive-900: rgba(57,60,12,1); 111 + --colour-olive-950: rgba(35,37,9,1); 112 + --colour-denim-50: rgba(239,240,255,1); 113 + --colour-denim-100: rgba(227,229,252,1); 114 + --colour-denim-200: rgba(205,209,255,1); 115 + --colour-denim-300: rgba(156,164,253,1); 116 + --colour-denim-400: rgba(96,108,243,1); 117 + --colour-denim-500: rgba(65,80,249,1); 118 + --colour-denim-600: rgba(49,64,238,1); 119 + --colour-denim-700: rgba(27,42,205,1); 120 + --colour-denim-800: rgba(25,35,157,1); 121 + --colour-denim-900: rgba(15,23,112,1); 122 + --colour-denim-950: rgba(7,11,56,1); 101 123 102 124 --easing-subtle-out: cubic-bezier(0.165, 0.84, 0.44, 1); 103 125
+11 -9
neo/src/settings/index.tsx
··· 82 82 class="colour-select" 83 83 > 84 84 <legend>favourite colour</legend> 85 - <PickerItem colour="aubergine"></PickerItem> 86 - <PickerItem colour="yellow"></PickerItem> 87 - <PickerItem colour="bubblegum"></PickerItem> 88 - <PickerItem colour="weezer"></PickerItem> 89 - <PickerItem colour="ectoplasm"></PickerItem> 90 - <PickerItem colour="orange"></PickerItem> 91 - <PickerItem colour="red"></PickerItem> 92 - <PickerItem colour="brown"></PickerItem> 85 + <PickerItem colour="aubergine" /> 86 + <PickerItem colour="yellow" /> 87 + <PickerItem colour="bubblegum" /> 88 + <PickerItem colour="denim" /> 89 + <PickerItem colour="weezer" /> 90 + <PickerItem colour="ectoplasm" /> 91 + <PickerItem colour="orange" /> 92 + <PickerItem colour="red" /> 93 + <PickerItem colour="brown" /> 94 + <PickerItem colour="olive" /> 93 95 </FieldSetRadioButtonEventGroupThing> 94 96 95 97 <FieldSetRadioButtonEventGroupThing class="comfy-compact-dichotomy" onChange={(e) => { ··· 160 162 <b>Tubes {Meta.version}</b> 161 163 <p> 162 164 Tubes is developed in front of a live studio audience by&nbsp; 163 - <a href="https://leah.pronounmail.com" target="_blank"> 165 + <a href="https://codeberg.org/leahc" target="_blank"> 164 166 Leah Clark 165 167 </a>. 166 168 </p>
-46
neo/src/storage.ts
··· 1 - import Dexie, { type EntityTable } from "dexie"; 2 - import { Connection } from "tubes_core"; 3 - import { IrcMessage } from "tubes_core/parser"; 4 - 5 - export interface StoredMessage { 6 - adapter_id: "*" | string & {}, 7 - connection_id: string, 8 - target: string, 9 - id: string, 10 - message: IrcMessage, 11 - timestamp: Date, 12 - } 13 - 14 - export const db = new Dexie('Tubes') as Dexie & { 15 - messages: EntityTable<StoredMessage>; 16 - }; 17 - 18 - db.version(1).stores({ 19 - messages: "id, [adapter_id+connection_id+target], adapter_id, connection_id, target, message, timestamp", 20 - }); 21 - 22 - export async function store_message(conn: Connection, message: IrcMessage) { 23 - const id = message.tags?.['msgid'] ?? crypto.randomUUID(); 24 - const timestamp = new Date(message.tags?.['time'] ?? Date.now()); 25 - 26 - switch (message.command) { 27 - case "PRIVMSG": 28 - case "NOTICE": { 29 - const target = message.params![0]; 30 - console.log(conn.id, conn.adapter_id, target, id, message, timestamp) 31 - await db.messages.add({ 32 - connection_id: conn.id, 33 - adapter_id: conn.adapter_id ?? "*", 34 - target, 35 - id, 36 - message, 37 - timestamp, 38 - }).catch(e => console.error(e)) ; 39 - console.log(`stored msg ${id}`, message) 40 - break; 41 - } 42 - 43 - default: return; 44 - } 45 - } 46 -
+8 -1
package-lock.json
··· 12 12 "core" 13 13 ], 14 14 "dependencies": { 15 - "@preact/signals": "1.3.0" 15 + "@preact/signals": "1.3.0", 16 + "idb": "^8.0.0" 16 17 } 17 18 }, 18 19 "core": { ··· 2282 2283 "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", 2283 2284 "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==", 2284 2285 "license": "MIT" 2286 + }, 2287 + "node_modules/idb": { 2288 + "version": "8.0.0", 2289 + "resolved": "https://registry.npmjs.org/idb/-/idb-8.0.0.tgz", 2290 + "integrity": "sha512-l//qvlAKGmQO31Qn7xdzagVPPaHTxXx199MhrAFuVBTPqydcPYBWjkrbv4Y0ktB+GmWOiwHl237UUOrLmQxLvw==", 2291 + "license": "ISC" 2285 2292 }, 2286 2293 "node_modules/import-fresh": { 2287 2294 "version": "3.3.0",
+7 -3
package.json
··· 3 3 "description": "an irc client", 4 4 "authors": "leah", 5 5 "version": "0.0.1", 6 - "workspaces": ["neo", "core"], 6 + "workspaces": [ 7 + "neo", 8 + "core" 9 + ], 7 10 "dependencies": { 8 - "@preact/signals": "1.3.0" 11 + "@preact/signals": "1.3.0", 12 + "idb": "^8.0.0" 9 13 }, 10 14 "scripts": { 11 15 "dev": "cd neo && npm run dev", 12 16 "build": "cd neo && npm run build", 13 17 "preview": "cd neo && npm run preview" 14 18 } 15 - } 19 + }