feat(*): send images from website

This commit is contained in:
h
2026-01-23 02:16:46 +01:00
parent 9f4dd8313e
commit b9c4296ca3
30 changed files with 1917 additions and 98 deletions

View File

@@ -0,0 +1,109 @@
import { v } from 'convex/values';
import { mutation, query } from './_generated/server';
export const register = mutation({
args: {
chatId: v.id('chats'),
deviceId: v.string(),
hasCamera: v.boolean()
},
returns: v.id('devicePairings'),
handler: async (ctx, args) => {
const existing = await ctx.db
.query('devicePairings')
.withIndex('by_chat_id', (q) => q.eq('chatId', args.chatId))
.collect();
const device = existing.find((d) => d.deviceId === args.deviceId);
if (device) {
await ctx.db.patch(device._id, {
hasCamera: args.hasCamera,
lastSeen: Date.now()
});
return device._id;
}
return await ctx.db.insert('devicePairings', {
chatId: args.chatId,
deviceId: args.deviceId,
hasCamera: args.hasCamera,
lastSeen: Date.now()
});
}
});
export const heartbeat = mutation({
args: {
chatId: v.id('chats'),
deviceId: v.string()
},
returns: v.null(),
handler: async (ctx, args) => {
const devices = await ctx.db
.query('devicePairings')
.withIndex('by_chat_id', (q) => q.eq('chatId', args.chatId))
.collect();
const device = devices.find((d) => d.deviceId === args.deviceId);
if (device) {
await ctx.db.patch(device._id, { lastSeen: Date.now() });
}
return null;
}
});
export const getMyDevice = query({
args: { chatId: v.id('chats'), deviceId: v.string() },
returns: v.union(
v.object({
_id: v.id('devicePairings'),
_creationTime: v.number(),
chatId: v.id('chats'),
deviceId: v.string(),
hasCamera: v.boolean(),
pairedWithDeviceId: v.optional(v.string()),
lastSeen: v.number()
}),
v.null()
),
handler: async (ctx, args) => {
const devices = await ctx.db
.query('devicePairings')
.withIndex('by_chat_id', (q) => q.eq('chatId', args.chatId))
.collect();
return devices.find((d) => d.deviceId === args.deviceId) ?? null;
}
});
export const getPairedDevice = query({
args: { chatId: v.id('chats'), deviceId: v.string() },
returns: v.union(
v.object({
_id: v.id('devicePairings'),
_creationTime: v.number(),
chatId: v.id('chats'),
deviceId: v.string(),
hasCamera: v.boolean(),
pairedWithDeviceId: v.optional(v.string()),
lastSeen: v.number()
}),
v.null()
),
handler: async (ctx, args) => {
const devices = await ctx.db
.query('devicePairings')
.withIndex('by_chat_id', (q) => q.eq('chatId', args.chatId))
.collect();
const myDevice = devices.find((d) => d.deviceId === args.deviceId);
if (!myDevice?.pairedWithDeviceId) return null;
const thirtySecondsAgo = Date.now() - 30000;
const paired = devices.find(
(d) => d.deviceId === myDevice.pairedWithDeviceId && d.lastSeen > thirtySecondsAgo
);
return paired ?? null;
}
});