Files
siftlode/frontend/src/features/video/stateNotice.ts
T

39 lines
1.6 KiB
TypeScript

import i18n from "../../i18n";
import { msg, notify, resolveVideo } from "../../lib/notifications";
import type { Video, VideoStatus } from "../../lib/api";
/** What a notice names the video by; any of it may be unknown to the surface that marked it. */
export type NoticeVideo = Pick<Video, "title" | "channel_id" | "channel_title">;
/** Say that a video's mark landed, once the server has it: "Hidden" / "Marked watched" with the
* Undo (`undo` puts it back to new) and the meta the Notification Center keeps it under, so the
* notice still finds the video after a reload. A mark back to new quietly resolves a hide or watch
* notice still standing for it, so it does not linger with a dead action. A claim of success:
* never called before the write is confirmed. One definition, because every list that marks a
* video must announce it the same way (the feed's cards, a related list). */
export function announceVideoState(
id: string,
status: VideoStatus,
video: NoticeVideo | undefined,
undo: () => void,
): void {
if (status === "new") {
resolveVideo(id);
return;
}
const hidden = status === "hidden";
notify({
message: video?.title
? msg(hidden ? "feed.hiddenNamed" : "feed.markedWatchedNamed", { title: video.title })
: msg(hidden ? "feed.hidden" : "feed.markedWatched"),
action: { label: i18n.t(hidden ? "feed.undo" : "feed.unwatch"), onClick: undo },
meta: {
kind: hidden ? "video-hidden" : "video-watched",
videoId: id,
title: video?.title ?? i18n.t("feed.thisVideo"),
channelId: video?.channel_id ?? "",
channelName: video?.channel_title ?? "",
},
});
}