reactions, match sse, etc
This commit is contained in:
@@ -5,43 +5,27 @@ import {
|
||||
Tabs,
|
||||
} from "@mantine/core";
|
||||
import { useDisclosure } from "@mantine/hooks";
|
||||
import { useState, useRef } from "react";
|
||||
import { useState, useRef, useCallback } from "react";
|
||||
import Sheet from "@/components/sheet/sheet";
|
||||
import { PlayerInfo } from "@/features/players/types";
|
||||
import PlayerList from "@/features/players/components/player-list";
|
||||
import EmojiPicker from "./emoji-picker";
|
||||
|
||||
interface Reaction {
|
||||
emoji: string;
|
||||
count: number;
|
||||
players: PlayerInfo[];
|
||||
hasReacted: boolean;
|
||||
}
|
||||
import { useMatchReactions, useToggleMatchReaction } from "../queries";
|
||||
import { useAuth } from "@/contexts/auth-context";
|
||||
import { Reaction } from "@/features/matches/server";
|
||||
|
||||
interface EmojiBarProps {
|
||||
reactions?: Reaction[];
|
||||
matchId: string;
|
||||
onReactionPress?: (emoji: string) => void;
|
||||
}
|
||||
|
||||
const EXAMPLE_DATA: Reaction[] = [
|
||||
{
|
||||
emoji: "👍",
|
||||
count: 1,
|
||||
players: [{ id: "dasfasdf", first_name: "Kyle", last_name: "Yohler" }],
|
||||
hasReacted: true,
|
||||
},
|
||||
{
|
||||
emoji: "❤️",
|
||||
count: 1,
|
||||
players: [{ id: "f3234f", first_name: "Salah", last_name: "Atiyeh" }],
|
||||
hasReacted: false,
|
||||
},
|
||||
];
|
||||
|
||||
const EmojiBar = ({
|
||||
reactions = EXAMPLE_DATA,
|
||||
matchId,
|
||||
onReactionPress,
|
||||
}: EmojiBarProps) => {
|
||||
const { user } = useAuth();
|
||||
const { data: reactions } = useMatchReactions(matchId);
|
||||
const toggleReaction = useToggleMatchReaction(matchId);
|
||||
|
||||
const [opened, { open, close }] = useDisclosure(false);
|
||||
const [activeTab, setActiveTab] = useState<string | null>(null);
|
||||
const longPressTimeout = useRef<NodeJS.Timeout | null>(null);
|
||||
@@ -61,10 +45,20 @@ const EmojiBar = ({
|
||||
|
||||
const handleReactionClick = (emoji: string) => {
|
||||
handleLongPressEnd();
|
||||
onReactionPress?.(emoji);
|
||||
if (onReactionPress) {
|
||||
onReactionPress(emoji);
|
||||
} else {
|
||||
toggleReaction.mutate({ data: { matchId, emoji } });
|
||||
}
|
||||
};
|
||||
|
||||
if (!reactions.length) return null;
|
||||
const hasReacted = useCallback((reaction: Reaction) => {
|
||||
return reaction.players.map(p => p.id).includes(user?.id || "");
|
||||
}, []);
|
||||
|
||||
if (!reactions) return;
|
||||
|
||||
console.log(reactions)
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -73,8 +67,9 @@ const EmojiBar = ({
|
||||
{reactions.map((reaction) => (
|
||||
<Button
|
||||
key={reaction.emoji}
|
||||
variant={reaction.hasReacted ? "filled" : "light"}
|
||||
color={reaction.hasReacted ? "var(--mantine-primary-color-filled)" : "gray"}
|
||||
variant={hasReacted(reaction) ? "filled" : "light"}
|
||||
color="gray"
|
||||
bd={hasReacted(reaction) ? "1px solid var(--mantine-primary-color-filled)" : undefined}
|
||||
size="compact-xs"
|
||||
radius="xl"
|
||||
onMouseDown={() => handleLongPressStart(reaction.emoji)}
|
||||
@@ -90,18 +85,18 @@ const EmojiBar = ({
|
||||
msUserSelect: "none",
|
||||
}}
|
||||
>
|
||||
<Group gap={4} align="center">
|
||||
<Text size="10px" style={{ lineHeight: 1 }}>
|
||||
<Group gap={2} align="center">
|
||||
<Text size="xs" style={{ lineHeight: 1 }}>
|
||||
{reaction.emoji}
|
||||
</Text>
|
||||
<Text size="10px" fw={600}>
|
||||
<Text size="xs" fw={600}>
|
||||
{reaction.count}
|
||||
</Text>
|
||||
</Group>
|
||||
</Button>
|
||||
))}
|
||||
</Group>
|
||||
<EmojiPicker onSelect={onReactionPress || (() => {})} />
|
||||
<EmojiPicker onSelect={onReactionPress || ((emoji) => toggleReaction.mutate({ data: { matchId, emoji } }))} />
|
||||
</Group>
|
||||
|
||||
<Sheet title="Reactions" opened={opened} onChange={() => close()}>
|
||||
|
||||
34
src/features/reactions/queries.ts
Normal file
34
src/features/reactions/queries.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { useServerQuery, useServerMutation } from "@/lib/tanstack-query/hooks";
|
||||
import { getMatchReactions, toggleMatchReaction } from "@/features/matches/server";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { matchKeys } from "@/features/matches/queries";
|
||||
|
||||
export const reactionKeys = {
|
||||
match: (matchId: string) => ['reactions', 'match', matchId] as const,
|
||||
};
|
||||
|
||||
export const reactionQueries = {
|
||||
match: (matchId: string) => ({
|
||||
queryKey: reactionKeys.match(matchId),
|
||||
queryFn: () => getMatchReactions({ data: matchId }),
|
||||
}),
|
||||
};
|
||||
|
||||
export const useMatchReactions = (matchId: string) =>
|
||||
useServerQuery(reactionQueries.match(matchId));
|
||||
|
||||
export const useToggleMatchReaction = (matchId: string) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useServerMutation({
|
||||
mutationFn: toggleMatchReaction,
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: reactionKeys.match(matchId)
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: matchKeys.reactions(matchId)
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user