feat: GIF search (Klipy), stickers, emoji picker, and bug fixes

- Add GIF search powered by Klipy API with correct response mapping
  (file.sm/hd tiers, not flat files structure)
- Add sticker system: packs, upload with auto-downscale, send in messages
- Add tabbed InputPopover with emoji, GIF, and sticker pickers
- Fix GIF API key migration race condition (column-add loop vs rename)
- Fix masked API key corruption on settings save (server + client guards)
- Fix sticker packs 403 (reversed isMember parameter order)
- Fix emoji picker not filling popover width (perLine 8→9, CSS 100%)
- Add error logging for Klipy API failures
This commit is contained in:
Jannis Braun
2026-03-15 02:04:37 +01:00
parent 7113f47b17
commit 3de6e4a668
26 changed files with 2160 additions and 50 deletions
+4
View File
@@ -23,6 +23,8 @@ import { instanceRoutes } from './routes/instance.js';
import { exploreRoutes } from './routes/explore.js';
import { searchRoutes } from './routes/search.js';
import { adminRoutes } from './routes/admin.js';
import { gifRoutes } from './routes/gif.js';
import { stickerRoutes } from './routes/stickers.js';
import { registerWebSocket } from './ws/handler.js';
import path from 'path';
import fs from 'fs';
@@ -91,6 +93,8 @@ async function main(): Promise<void> {
await app.register(exploreRoutes);
await app.register(searchRoutes);
await app.register(adminRoutes);
await app.register(gifRoutes);
await app.register(stickerRoutes);
await app.register(registerWebSocket);
app.get('/api/health', async () => {