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>
45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
import { getProfile } from "../../db/profile";
|
|
import { getPlanLimits } from "../../utils/plan-features";
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const user = await requireUser(event);
|
|
const dbProfile = await getProfile(user.id);
|
|
|
|
const plan = (dbProfile?.plan === "premium"
|
|
? "legend"
|
|
: dbProfile?.plan === "standard"
|
|
? "pro"
|
|
: dbProfile?.plan ?? "free") as "free" | "pro" | "legend";
|
|
|
|
const limits = getPlanLimits(plan);
|
|
|
|
return {
|
|
id: user.id,
|
|
email: user.email,
|
|
username: dbProfile?.username ?? "",
|
|
nickname: dbProfile?.nickname ?? null,
|
|
avatar: dbProfile?.avatar ?? null,
|
|
plan,
|
|
foundingMember: dbProfile?.foundingMember ?? false,
|
|
streak: dbProfile?.streak ?? 0,
|
|
lyraVoiceId: dbProfile?.lyraVoiceId ?? null,
|
|
onboardingStep: dbProfile?.onboardingStep ?? "welcome",
|
|
created_at: dbProfile?.createdAt?.toISOString() ?? user.created_at,
|
|
// Für useUserPlan im Frontend — Key-Subset der PlanLimits
|
|
planLimits: {
|
|
customDomains: limits.customDomains, // { web: number, mail: number }
|
|
domainRefill: limits.domainRefill,
|
|
mailAgents: limits.mailAgents === Infinity ? null : limits.mailAgents,
|
|
globalBlocklist: limits.globalBlocklist,
|
|
maxAppDevices: limits.maxAppDevices,
|
|
maxProtectedDevices: limits.maxProtectedDevices,
|
|
canCreateGroup: limits.canCreateGroup,
|
|
canAddToBlocklist: limits.canAddToBlocklist,
|
|
},
|
|
globalBlocklistGraceUntil:
|
|
dbProfile?.globalBlocklistGraceUntil?.toISOString() ?? null,
|
|
presenceVisible: dbProfile?.presenceVisible ?? true,
|
|
callsEnabled: dbProfile?.callsEnabled ?? true,
|
|
};
|
|
});
|