TTP -> MTP, A lot of other stuff #21
3 changed files with 109 additions and 9 deletions
commit
c11589079b
|
|
@ -143,7 +143,7 @@ function MessageComponent({
|
||||||
}, [message.Content]);
|
}, [message.Content]);
|
||||||
|
|
||||||
// Message editing
|
// Message editing
|
||||||
const { chatSecret, editMessage, userId } = useChat();
|
const { chatSecret, editMessage, userId, deleteMessage } = useChat();
|
||||||
const [editing, setEditing] = useState(false);
|
const [editing, setEditing] = useState(false);
|
||||||
const [editDraft, setEditDraft] = useState(message.Content);
|
const [editDraft, setEditDraft] = useState(message.Content);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -283,14 +283,46 @@ function MessageComponent({
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{editing ? (
|
{editing ? (
|
||||||
<Input
|
<div className="flex flex-col">
|
||||||
setValue={setEditDraft}
|
<Input
|
||||||
value={editDraft}
|
styled
|
||||||
onSubmit={() => {
|
setValue={setEditDraft}
|
||||||
submitEditMessage(editDraft);
|
value={editDraft}
|
||||||
setEditing(false);
|
onSubmit={() => {
|
||||||
}}
|
submitEditMessage(editDraft);
|
||||||
/>
|
setEditing(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="flex">
|
||||||
|
<Button
|
||||||
|
size="xs"
|
||||||
|
variant="link"
|
||||||
|
className="text-primary-foreground-alt"
|
||||||
|
onClick={() => {
|
||||||
|
if (editDraft === message.Content) {
|
||||||
|
deleteMessage(message.SendTime);
|
||||||
|
} else {
|
||||||
|
submitEditMessage(editDraft);
|
||||||
|
}
|
||||||
|
setEditDraft(message.Content);
|
||||||
|
setEditing(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="xs"
|
||||||
|
variant="link"
|
||||||
|
className="text-muted-foreground"
|
||||||
|
onClick={() => {
|
||||||
|
setEditDraft(message.Content);
|
||||||
|
setEditing(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
) : isValidURL ? (
|
) : isValidURL ? (
|
||||||
<Media link={message.Content} />
|
<Media link={message.Content} />
|
||||||
) : (
|
) : (
|
||||||
|
|
|
||||||
|
|
@ -436,6 +436,65 @@ export default function Provider({ children }: { children: ReactNode }) {
|
||||||
[currentChatSecret, userIdValue],
|
[currentChatSecret, userIdValue],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const deleteMessage = useCallback(
|
||||||
|
async (sendTime: number) => {
|
||||||
|
try {
|
||||||
|
const response = await send("MessageDelete", {
|
||||||
|
ChatPartnerId: userIdValue,
|
||||||
|
SendTime: sendTime,
|
||||||
|
});
|
||||||
|
|
||||||
|
assertProtocolSuccess("MessageDelete", response);
|
||||||
|
|
||||||
|
setLiveMessagesState((prev) =>
|
||||||
|
prev.filter((message) => message.SendTime !== sendTime),
|
||||||
|
);
|
||||||
|
|
||||||
|
const queryKey = [
|
||||||
|
"chat-messages",
|
||||||
|
String(userIdValue),
|
||||||
|
currentChatSecret !== null,
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
queryClient.setQueryData<InfiniteData<RawMessages>>(
|
||||||
|
queryKey,
|
||||||
|
(current) => {
|
||||||
|
if (!current) {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
let updated = false;
|
||||||
|
|
||||||
|
const pages = current.pages.map((page) => {
|
||||||
|
const nextPage = page.filter((message) => {
|
||||||
|
const keep = message.SendTime !== sendTime;
|
||||||
|
if (!keep) {
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
return keep;
|
||||||
|
});
|
||||||
|
|
||||||
|
return nextPage;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updated) {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...current,
|
||||||
|
pages,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
log(1, "chat", "red", "Failed to delete message", err);
|
||||||
|
toast("error", "Failed to delete message", String(err));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[currentChatSecret, send, userIdValue],
|
||||||
|
);
|
||||||
|
|
||||||
const addLiveMessage = useCallback(
|
const addLiveMessage = useCallback(
|
||||||
(message: RawMessage) => {
|
(message: RawMessage) => {
|
||||||
const localId =
|
const localId =
|
||||||
|
|
@ -578,6 +637,7 @@ export default function Provider({ children }: { children: ReactNode }) {
|
||||||
liveMessages: () => liveMessagesState,
|
liveMessages: () => liveMessagesState,
|
||||||
addLiveMessage,
|
addLiveMessage,
|
||||||
editMessage,
|
editMessage,
|
||||||
|
deleteMessage,
|
||||||
clearLiveMessages,
|
clearLiveMessages,
|
||||||
chatSecret: currentChatSecret,
|
chatSecret: currentChatSecret,
|
||||||
userId: userIdValue,
|
userId: userIdValue,
|
||||||
|
|
@ -602,6 +662,7 @@ type contextType = {
|
||||||
setFailed: (failed: boolean) => void;
|
setFailed: (failed: boolean) => void;
|
||||||
};
|
};
|
||||||
editMessage: (sendTime: number, edit: MessageEdit) => void;
|
editMessage: (sendTime: number, edit: MessageEdit) => void;
|
||||||
|
deleteMessage: (sendTime: number) => void;
|
||||||
clearLiveMessages: () => void;
|
clearLiveMessages: () => void;
|
||||||
chatSecret: Uint8Array | null;
|
chatSecret: Uint8Array | null;
|
||||||
userId: number;
|
userId: number;
|
||||||
|
|
|
||||||
|
|
@ -202,6 +202,13 @@ export const mtp = {
|
||||||
PingIota: z.number(),
|
PingIota: z.number(),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
MessageDelete: {
|
||||||
|
request: z.object({
|
||||||
|
ChatPartnerId: z.number(),
|
||||||
|
SendTime: z.number(),
|
||||||
|
}),
|
||||||
|
response: z.object({}),
|
||||||
|
},
|
||||||
MessageEditLive: {
|
MessageEditLive: {
|
||||||
request: z.object({}),
|
request: z.object({}),
|
||||||
response: z.object({
|
response: z.object({
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue