self-pr review

This commit is contained in:
Igor Loskutov
2025-09-12 18:34:56 -04:00
parent 1f41448e1c
commit 5d53c53db2
14 changed files with 486 additions and 886 deletions

View File

@@ -102,7 +102,7 @@ export function useTranscriptGet(transcriptId: string | null) {
{
params: {
path: {
transcript_id: transcriptId || "",
transcript_id: transcriptId!,
},
},
},
@@ -120,7 +120,7 @@ export function useRoomGet(roomId: string | null) {
"/v1/rooms/{room_id}",
{
params: {
path: { room_id: roomId || "" },
path: { room_id: roomId! },
},
},
{
@@ -327,7 +327,7 @@ export function useTranscriptTopics(transcriptId: string | null) {
"/v1/transcripts/{transcript_id}/topics",
{
params: {
path: { transcript_id: transcriptId || "" },
path: { transcript_id: transcriptId! },
},
},
{
@@ -344,7 +344,7 @@ export function useTranscriptTopicsWithWords(transcriptId: string | null) {
"/v1/transcripts/{transcript_id}/topics/with-words",
{
params: {
path: { transcript_id: transcriptId || "" },
path: { transcript_id: transcriptId! },
},
},
{
@@ -365,8 +365,8 @@ export function useTranscriptTopicsWithWordsPerSpeaker(
{
params: {
path: {
transcript_id: transcriptId || "",
topic_id: topicId || "",
transcript_id: transcriptId!,
topic_id: topicId!,
},
},
},
@@ -384,7 +384,7 @@ export function useTranscriptParticipants(transcriptId: string | null) {
"/v1/transcripts/{transcript_id}/participants",
{
params: {
path: { transcript_id: transcriptId || "" },
path: { transcript_id: transcriptId! },
},
},
{
@@ -569,23 +569,18 @@ export function useMeetingDeactivate() {
const { setError } = useError();
const queryClient = useQueryClient();
return $api.useMutation("patch", "/v1/meetings/{meeting_id}/deactivate", {
return $api.useMutation("patch", `/v1/meetings/{meeting_id}/deactivate`, {
onError: (error) => {
setError(error as Error, "Failed to end meeting");
},
onSuccess: () => {
// Invalidate all meeting-related queries to refresh the UI
queryClient.invalidateQueries({
predicate: (query) => {
const key = query.queryKey;
return (
Array.isArray(key) &&
key.some(
(k) =>
typeof k === "string" &&
(k.includes("/meetings/active") ||
k.includes("/meetings/upcoming")),
)
return key.some(
(k) =>
typeof k === "string" &&
!!MEETING_LIST_PATH_PARTIALS.find((e) => k.includes(e)),
);
},
});
@@ -646,7 +641,7 @@ export function useRoomGetByName(roomName: string | null) {
"/v1/rooms/name/{room_name}",
{
params: {
path: { room_name: roomName || "" },
path: { room_name: roomName! },
},
},
{
@@ -660,10 +655,10 @@ export function useRoomUpcomingMeetings(roomName: string | null) {
return $api.useQuery(
"get",
"/v1/rooms/{room_name}/meetings/upcoming",
"/v1/rooms/{room_name}/meetings/upcoming" satisfies `/v1/rooms/{room_name}/${typeof MEETINGS_UPCOMING_PATH_PARTIAL}`,
{
params: {
path: { room_name: roomName || "" },
path: { room_name: roomName! },
},
},
{
@@ -672,15 +667,24 @@ export function useRoomUpcomingMeetings(roomName: string | null) {
);
}
const MEETINGS_PATH_PARTIAL = "meetings" as const;
const MEETINGS_ACTIVE_PATH_PARTIAL = `${MEETINGS_PATH_PARTIAL}/active` as const;
const MEETINGS_UPCOMING_PATH_PARTIAL =
`${MEETINGS_PATH_PARTIAL}/upcoming` as const;
const MEETING_LIST_PATH_PARTIALS = [
MEETINGS_ACTIVE_PATH_PARTIAL,
MEETINGS_UPCOMING_PATH_PARTIAL,
];
export function useRoomActiveMeetings(roomName: string | null) {
const { isAuthenticated } = useAuthReady();
return $api.useQuery(
"get",
"/v1/rooms/{room_name}/meetings/active",
"/v1/rooms/{room_name}/meetings/active" satisfies `/v1/rooms/{room_name}/${typeof MEETINGS_ACTIVE_PATH_PARTIAL}`,
{
params: {
path: { room_name: roomName || "" },
path: { room_name: roomName! },
},
},
{
@@ -721,7 +725,7 @@ export function useRoomIcsStatus(roomName: string | null) {
"/v1/rooms/{room_name}/ics/status",
{
params: {
path: { room_name: roomName || "" },
path: { room_name: roomName! },
},
},
{
@@ -738,7 +742,7 @@ export function useRoomCalendarEvents(roomName: string | null) {
"/v1/rooms/{room_name}/meetings",
{
params: {
path: { room_name: roomName || "" },
path: { room_name: roomName! },
},
},
{

View File

@@ -1,5 +1,4 @@
export const formatDateTime = (date: string | Date): string => {
const d = new Date(date);
export const formatDateTime = (d: Date): string => {
return d.toLocaleString("en-US", {
month: "short",
day: "numeric",
@@ -8,26 +7,11 @@ export const formatDateTime = (date: string | Date): string => {
});
};
export const formatCountdown = (startTime: string | Date): string => {
const now = new Date();
const start = new Date(startTime);
const diff = start.getTime() - now.getTime();
if (diff <= 0) return "Starting now";
const minutes = Math.floor(diff / 60000);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
if (days > 0) return `Starts in ${days}d ${hours % 24}h ${minutes % 60}m`;
if (hours > 0) return `Starts in ${hours}h ${minutes % 60}m`;
return `Starts in ${minutes} minutes`;
};
export const formatStartedAgo = (startTime: string | Date): string => {
const now = new Date();
const start = new Date(startTime);
const diff = now.getTime() - start.getTime();
export const formatStartedAgo = (
startTime: Date,
now: Date = new Date(),
): string => {
const diff = now.getTime() - startTime.getTime();
if (diff <= 0) return "Starting now";

View File

@@ -0,0 +1,15 @@
import { useEffect, useState } from "react";
export const useWhereby = () => {
const [wherebyLoaded, setWherebyLoaded] = useState(false);
useEffect(() => {
if (typeof window !== "undefined") {
import("@whereby.com/browser-sdk/embed")
.then(() => {
setWherebyLoaded(true);
})
.catch(console.error.bind(console));
}
}, []);
return wherebyLoaded;
};