Files
desktop/app/providers/DialogStateProvider.tsx/DialogStateProvider.tsx
rosetta 83f38dc63f 'init'
2026-01-30 05:01:05 +02:00

122 lines
3.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useConsoleLogger } from "@/app/hooks/useConsoleLogger";
import React, { createContext, useEffect, useState } from "react";
export interface DialogStateContextValue {
muted: string[];
pinned: string[];
muteToggle: (dialogId: string) => void;
pinToggle: (dialogId: string) => void;
mentions: DialogMention[];
pushMention: (dialogMention : DialogMention) => void;
popMention: (DialogMention: DialogMention) => void;
isMentioned: (dialogId: string) => boolean;
getLastMention: (dialogId: string) => DialogMention;
}
export const DialogStateContext = createContext<DialogStateContextValue | null>(null);
export interface DialogStateProviderProps {
children: React.ReactNode;
}
export interface DialogMention {
dialog_id: string;
message_id: string;
}
/**
* Этот провайдер нужен для того, чтобы быстро определить состояние диалога,
* например, закреплен ли он или нет, или отключены ли в нем уведомления.
*
* ВАЖНО! При отключенных уведомлениях все равно
* будут доставляться сообщния с упоминаниями.
*/
export function DialogStateProvider(props : DialogStateProviderProps) {
const [muted, setMuted] = useState<string[]>([]);
const [pinned, setPinned] = useState<string[]>([]);
const [mentions, setDialogMentions] = useState<DialogMention[]>([]);
const {info} = useConsoleLogger('DialogStateProvider');
useEffect(() => {
let muted = localStorage.getItem("mutedDialogs");
let pinned = localStorage.getItem("pinnedDialogs");
let mentions = localStorage.getItem("dialogMentions");
if (mentions) {
setDialogMentions(JSON.parse(mentions));
}
if (muted) {
setMuted(JSON.parse(muted));
}
if (pinned) {
setPinned(JSON.parse(pinned));
}
info("Initial dialog states is loaded");
}, []);
useEffect(() => {
localStorage.setItem("mutedDialogs", JSON.stringify(muted));
}, [muted]);
useEffect(() => {
localStorage.setItem("pinnedDialogs", JSON.stringify(pinned));
}, [pinned]);
useEffect(() => {
localStorage.setItem("dialogMentions", JSON.stringify(mentions));
}, [mentions]);
const muteToggle = (dialogId: string) => {
setMuted(prev => {
if (prev.includes(dialogId)) {
return prev.filter(id => id !== dialogId);
} else {
return [...prev, dialogId];
}
});
}
const pinToggle = (dialogId: string) => {
setPinned(prev => {
if (prev.includes(dialogId)) {
return prev.filter(id => id !== dialogId);
} else {
return [...prev, dialogId];
}
});
}
const pushMention = (dialogMention: DialogMention) => {
setDialogMentions((prev) => [...prev, dialogMention]);
}
const popMention = (dialogMention: DialogMention) => {
setDialogMentions((prev) => prev.filter(m => !(m.dialog_id === dialogMention.dialog_id && m.message_id === dialogMention.message_id)));
}
const isMentioned = (dialogId: string) => {
return mentions.some(m => m.dialog_id === dialogId);
}
const getLastMention = (dialogId: string) : DialogMention => {
const dialogMentions = mentions.filter(m => m.dialog_id === dialogId);
return dialogMentions[dialogMentions.length - 1];
}
return (
<DialogStateContext.Provider value={{
muted,
pinned,
muteToggle,
pinToggle,
pushMention,
popMention,
mentions,
isMentioned,
getLastMention
}}>
{props.children}
</DialogStateContext.Provider>
)
}