my-kaiqiuwang/src/components/FavButton.tsx
kyuuseiryuu 2774037012 feat(app): add push notification support and event management logic
- Introduce PermissionControlPanel in UserCenter for managing notification permissions.
- Update Service Worker (sw.ts) to handle background push notifications via Firebase Cloud Messaging.
- Implement EventSubscribeService logic to fetch active events, filter expired ones, and clean up subscriptions.
- Refactor KaiqiuService and parsing utilities to include eventId in event details.
- Remove deprecated ScheduleService and inline sendNotification logic.
- Update utility functions to support new types and notification checks.
- Add VAPI public key configuration and update Firebase exports.
2026-03-24 17:21:50 +09:00

66 lines
2.1 KiB
TypeScript

import { useCallback, useEffect, useState } from "react";
import { useFavPlayerStore, type FavPlayer } from "../store/useFavPlayerStore";
import styled from "styled-components";
import { useRequest } from "ahooks";
import { useLogto } from "@logto/react";
import { useAuthHeaders } from "../hooks/useAuthHeaders";
import { StarFilled, StarOutlined } from "@ant-design/icons";
interface Props {
user?: FavPlayer;
}
const StyledContainer = styled.div`
position: absolute;
top: 20px;
right: 20px;
`;
export function FavButton(props: Props) {
const { isAuthenticated } = useLogto();
const { fav, unFav, isFav } = useFavPlayerStore(store => store);
const headers = useAuthHeaders();
const favReq = useRequest(async () => {
if (!isAuthenticated) return;
await fetch(`/api/fav/${props.user?.uid}`, { method: 'PUT', headers });
}, { manual: true, refreshDeps: [isAuthenticated, headers] });
const unFavReq = useRequest(async () => {
if (!isAuthenticated) return;
await fetch(`/api/fav/${props.user?.uid}`, { method: 'DELETE', headers });
}, { manual: true, refreshDeps: [isAuthenticated, headers] });
const [value, setValue] = useState(isFav(props.user?.uid) ? 1 : 0);
useEffect(() => {
if (!props.user) return;
if (!isAuthenticated) return;
const id = setTimeout(async () => {
console.debug('Token', headers);
const res: { isFav: boolean } = await fetch(`/api/fav/${props.user?.uid}`, {
headers,
}).then(res => res.json());
setValue(res.isFav ? 1 : 0);
}, 300);
return () => clearTimeout(id);
}, [isAuthenticated, headers]);
const handleFavClick = useCallback((value: number) => {
if (!props.user) return;
setValue(value);
if (value) {
fav(props.user);
favReq.run();
setValue(1);
} else {
unFavReq.run();
unFav(props.user.uid);
setValue(0);
}
}, []);
return (
<StyledContainer>
{value ? (
<StarFilled style={{ color: 'yellow' }} onClick={() => handleFavClick(0)} />
) : (
<StarOutlined onClick={() => handleFavClick(1)} />
)}
</StyledContainer>
);
}