feat: add Discord reminder and timezone settings

This commit is contained in:
syntaxbullet
2026-09-08 08:23:27 +02:00
parent 3487488f7b
commit 5dbec04b04
12 changed files with 324 additions and 28 deletions

View File

@@ -4,7 +4,7 @@ import { fixture } from '../habits/test-fixture';
import { users } from '../db/schema';
import { createDiscordRoutes } from './routes';
import type { Interaction } from './types';
export function discordFixture() {
export function discordFixture(remindersAvailable = false) {
const f = fixture();
const { publicKey, privateKey } = generateKeyPairSync('ed25519');
const key = publicKey.export({ format: 'der', type: 'spki' }).subarray(-32).toString('hex');
@@ -13,7 +13,7 @@ export function discordFixture() {
f.db.update(users).set({ discordId: alice }).where(eq(users.id, 'alice')).run();
f.db.update(users).set({ discordId: bob }).where(eq(users.id, 'bob')).run();
const changed: string[] = [];
let app = createDiscordRoutes(f.db, { publicKey: key, applicationId, origin: f.origin }, () => time, id => changed.push(id));
let app = createDiscordRoutes(f.db, { publicKey: key, applicationId, origin: f.origin, remindersAvailable }, () => time, id => changed.push(id));
function payload(data: Partial<Interaction>, guild = false, user = alice): Interaction {
const profile = { id: user, username: user === alice ? 'alice' : 'bob' };
return { id: String(++sequence), application_id: applicationId, type: 2, ...(guild ? { guild_id: '444444444444444444', member: { user: profile } } : { user: profile }), ...data };
@@ -23,7 +23,7 @@ export function discordFixture() {
return app.request('http://localhost/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Signature-Timestamp': timestamp, 'X-Signature-Ed25519': sign(null, Buffer.from(timestamp + body), privateKey).toString('hex'), ...headers }, body });
}
async function run(data: Partial<Interaction>, guild = false, user = alice): Promise<any> { return (await request(payload(data, guild, user))).json(); }
return { ...f, alice, bob, changed, payload, requestDiscord: request, run, restart: () => { app = createDiscordRoutes(f.db, { publicKey: key, applicationId, origin: f.origin }, () => time, id => changed.push(id)); }, setDiscordTime: (value: string) => { time = Date.parse(value); f.setTime(value); } };
return { ...f, alice, bob, changed, payload, requestDiscord: request, run, restart: () => { app = createDiscordRoutes(f.db, { publicKey: key, applicationId, origin: f.origin, remindersAvailable }, () => time, id => changed.push(id)); }, setDiscordTime: (value: string) => { time = Date.parse(value); f.setTime(value); } };
}
export function control(reply: any, label: string): string {
const item = reply.data.components.flatMap((r: any) => r.components ?? []).find((c: any) => c.label === label || c.placeholder === label);