chahinebrini 89e4e3481b feat(calls): Phase 0 — calls_enabled opt-out + canCall guard (mutual-follow); DM UI batch
Backend (voice-call groundwork, no call engine yet):
- Profile.callsEnabled (Boolean default true) + migration
- canCall(caller,callee): mutual-follow AND callee.callsEnabled — server-side hard guard
- POST /api/me/calls-enabled (opt-out toggle), GET /api/chat/can-call/:userId
- expose callsEnabled in /api/auth/me

Frontend:
- "Allow calls" toggle in Profile privacy section (default on, optimistic+rollback)
- Me.callsEnabled + i18n DE/EN/FR/AR

Bundled DM UI work from this session:
- image lightbox is now a swipeable carousel over all shared images (+ counter)
- keyboard stays open after sending (input ref refocus)
- voice notes: Instagram-style waveforms (own=white/mint, other=black/grey),
  removed the blue progress dot; lazy-load expo-media-library with clean fallback
- expo-linear-gradient + expo-media-library deps

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 21:14:31 +02:00

21 lines
693 B
TypeScript

/**
* GET /api/chat/can-call/:userId
*
* Darf der eingeloggte User den :userId anrufen? true nur bei gegenseitigem
* Follow UND wenn der Angerufene Anrufe nicht deaktiviert hat. Nutzt die
* Frontend-UI, um den Call-Button im DM-Header ein-/auszublenden.
*
* Response: { canCall: boolean }
*/
import { requireUser } from "../../../utils/auth";
import { canCall } from "../../../db/social";
export default defineEventHandler(async (event) => {
const user = await requireUser(event);
const userId = getRouterParam(event, "userId");
if (!userId) {
throw createError({ statusCode: 400, message: "MISSING_USER_ID" });
}
return { canCall: await canCall(user.id, userId) };
});