63 lines
2.2 KiB
TypeScript
63 lines
2.2 KiB
TypeScript
import { useSyncExternalStore } from "react";
|
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
import { followUser, unfollowUser, buildCSRFHeaders } from "./ash_rpc";
|
|
|
|
// ── useIsDesktop ──────────────────────────────────────────────────────────────
|
|
// Returns true when viewport is wider than 960px. Reacts to resize.
|
|
|
|
const DESKTOP_MQ =
|
|
typeof window !== "undefined" ? window.matchMedia("(min-width: 961px)") : null;
|
|
|
|
function subscribe(cb: () => void) {
|
|
DESKTOP_MQ?.addEventListener("change", cb);
|
|
return () => DESKTOP_MQ?.removeEventListener("change", cb);
|
|
}
|
|
|
|
export function useIsDesktop(): boolean {
|
|
return useSyncExternalStore(
|
|
subscribe,
|
|
() => DESKTOP_MQ?.matches ?? true,
|
|
() => true,
|
|
);
|
|
}
|
|
|
|
// ── useFollowUser ─────────────────────────────────────────────────────────────
|
|
|
|
export function useFollowUser(targetUserId: string) {
|
|
const qc = useQueryClient();
|
|
|
|
const followMutation = useMutation({
|
|
mutationFn: async () => {
|
|
const res = await followUser({
|
|
input: { followingId: targetUserId },
|
|
headers: buildCSRFHeaders(),
|
|
});
|
|
if (!res.success) throw new Error((res.errors?.[0] as any)?.message ?? "Follow failed");
|
|
},
|
|
onSuccess: () => {
|
|
qc.invalidateQueries({ queryKey: ["users"] });
|
|
qc.invalidateQueries({ queryKey: ["user", targetUserId] });
|
|
},
|
|
});
|
|
|
|
const unfollowMutation = useMutation({
|
|
mutationFn: async () => {
|
|
const res = await unfollowUser({
|
|
input: { followingId: targetUserId },
|
|
headers: buildCSRFHeaders(),
|
|
});
|
|
if (!res.success) throw new Error((res.errors?.[0] as any)?.message ?? "Unfollow failed");
|
|
},
|
|
onSuccess: () => {
|
|
qc.invalidateQueries({ queryKey: ["users"] });
|
|
qc.invalidateQueries({ queryKey: ["user", targetUserId] });
|
|
},
|
|
});
|
|
|
|
return {
|
|
follow: () => followMutation.mutate(),
|
|
unfollow: () => unfollowMutation.mutate(),
|
|
isPending: followMutation.isPending || unfollowMutation.isPending,
|
|
};
|
|
}
|