Implement Markers API
This commit is contained in:
parent
2b2499849f
commit
8e178338b7
|
@ -31,6 +31,7 @@ import { blocksController } from '@/controllers/api/blocks.ts';
|
||||||
import { bookmarksController } from '@/controllers/api/bookmarks.ts';
|
import { bookmarksController } from '@/controllers/api/bookmarks.ts';
|
||||||
import { emptyArrayController, emptyObjectController, notImplementedController } from '@/controllers/api/fallback.ts';
|
import { emptyArrayController, emptyObjectController, notImplementedController } from '@/controllers/api/fallback.ts';
|
||||||
import { instanceController } from '@/controllers/api/instance.ts';
|
import { instanceController } from '@/controllers/api/instance.ts';
|
||||||
|
import { markersController, updateMarkersController } from '@/controllers/api/markers.ts';
|
||||||
import { mediaController } from '@/controllers/api/media.ts';
|
import { mediaController } from '@/controllers/api/media.ts';
|
||||||
import { mutesController } from '@/controllers/api/mutes.ts';
|
import { mutesController } from '@/controllers/api/mutes.ts';
|
||||||
import { notificationsController } from '@/controllers/api/notifications.ts';
|
import { notificationsController } from '@/controllers/api/notifications.ts';
|
||||||
|
@ -191,6 +192,9 @@ app.get('/api/v1/bookmarks', requirePubkey, bookmarksController);
|
||||||
app.get('/api/v1/blocks', requirePubkey, blocksController);
|
app.get('/api/v1/blocks', requirePubkey, blocksController);
|
||||||
app.get('/api/v1/mutes', requirePubkey, mutesController);
|
app.get('/api/v1/mutes', requirePubkey, mutesController);
|
||||||
|
|
||||||
|
app.get('/api/v1/markers', requireProof(), markersController);
|
||||||
|
app.post('/api/v1/markers', requireProof(), updateMarkersController);
|
||||||
|
|
||||||
app.get('/api/v1/admin/accounts', requireRole('admin'), adminAccountsController);
|
app.get('/api/v1/admin/accounts', requireRole('admin'), adminAccountsController);
|
||||||
app.get('/api/v1/pleroma/admin/config', requireRole('admin'), configController);
|
app.get('/api/v1/pleroma/admin/config', requireRole('admin'), configController);
|
||||||
app.post('/api/v1/pleroma/admin/config', requireRole('admin'), updateConfigController);
|
app.post('/api/v1/pleroma/admin/config', requireRole('admin'), updateConfigController);
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { AppController } from '@/app.ts';
|
||||||
|
import { parseBody } from '@/utils/api.ts';
|
||||||
|
|
||||||
|
const kv = await Deno.openKv();
|
||||||
|
|
||||||
|
interface Marker {
|
||||||
|
last_read_id: string;
|
||||||
|
version: number;
|
||||||
|
updated_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const markersController: AppController = async (c) => {
|
||||||
|
const pubkey = c.get('pubkey')!;
|
||||||
|
const timelines = c.req.queries('timeline[]') ?? [];
|
||||||
|
|
||||||
|
const results = await kv.getMany<Marker[]>(
|
||||||
|
timelines.map((timeline) => ['markers', pubkey, timeline]),
|
||||||
|
);
|
||||||
|
|
||||||
|
const marker = results.reduce<Record<string, Marker>>((acc, { key, value }) => {
|
||||||
|
if (value) {
|
||||||
|
const timeline = key[key.length - 1] as string;
|
||||||
|
acc[timeline] = value;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return c.json(marker);
|
||||||
|
};
|
||||||
|
|
||||||
|
const markerDataSchema = z.object({
|
||||||
|
last_read_id: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const updateMarkersController: AppController = async (c) => {
|
||||||
|
const pubkey = c.get('pubkey')!;
|
||||||
|
const record = z.record(z.string(), markerDataSchema).parse(await parseBody(c.req.raw));
|
||||||
|
const timelines = Object.keys(record);
|
||||||
|
|
||||||
|
const markers: Record<string, Marker> = {};
|
||||||
|
|
||||||
|
const entries = await kv.getMany<Marker[]>(
|
||||||
|
timelines.map((timeline) => ['markers', pubkey, timeline]),
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const timeline of timelines) {
|
||||||
|
const last = entries.find(({ key }) => key[key.length - 1] === timeline);
|
||||||
|
|
||||||
|
const marker: Marker = {
|
||||||
|
last_read_id: record[timeline].last_read_id,
|
||||||
|
version: last?.value ? last.value.version + 1 : 1,
|
||||||
|
updated_at: new Date().toISOString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
await kv.set(['markers', pubkey, timeline], marker);
|
||||||
|
markers[timeline] = marker;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.json(markers);
|
||||||
|
};
|
Loading…
Reference in New Issue