feat(status): make the set-status menu work
feat(user): optimise get() function for react qol(todos): update todos
This commit is contained in:
parent
dbb407606b
commit
1c90a0c859
30 changed files with 572 additions and 324 deletions
|
|
@ -24,7 +24,7 @@ import {
|
|||
} from "lucide-react";
|
||||
import { useState, useMemo, useEffect, useRef, type WheelEvent } from "react";
|
||||
import MediaSaveButton from "./mediaSaveButton";
|
||||
import { type User, useUser } from "@tensamin/user/context";
|
||||
import { useUserFields } from "@tensamin/user/context";
|
||||
|
||||
const zoomLevels = [1, 1.5, 2, 3];
|
||||
|
||||
|
|
@ -46,12 +46,7 @@ export default function Media({
|
|||
const wheelDelta = useRef(0);
|
||||
const hostname = useMemo(() => new URL(link).hostname, [link]);
|
||||
|
||||
// Get user's
|
||||
const { get } = useUser();
|
||||
const [user, setUser] = useState<undefined | User>(undefined);
|
||||
useEffect(() => {
|
||||
get(senderId).then(setUser);
|
||||
}, [senderId, get]);
|
||||
const { data: user } = useUserFields(senderId, ["Avatar", "Display"]);
|
||||
const avatar = user?.Avatar
|
||||
? `data:image/webp;base64,${user.Avatar}`
|
||||
: undefined;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { RawMessage } from "../values";
|
||||
import { AlertTriangle, Check, CheckLine, RefreshCw } from "lucide-react";
|
||||
import { memo, useCallback, useEffect, useRef, useState } from "react";
|
||||
import type { User } from "@tensamin/user/context";
|
||||
import { type SelectedUser, useUserFields } from "@tensamin/user/context";
|
||||
|
||||
import {
|
||||
Avatar,
|
||||
|
|
@ -21,7 +21,6 @@ import { decryptChatText, encryptChatText } from "@tensamin/crypto/chatSecret";
|
|||
import { log, toast } from "@tensamin/shared/log";
|
||||
import { Emoji, Input, normalizeShortcode, Text } from "@methanium/ui/markdown";
|
||||
import { useRecordEmojiUse } from "./emojiRanks";
|
||||
import { useUser } from "@tensamin/user/context";
|
||||
import ReplyBox from "./replyBox";
|
||||
import { useHotkey } from "@tensamin/hotkeys";
|
||||
import { cancelMessageEditHotkey } from "../hotkeys";
|
||||
|
|
@ -40,7 +39,7 @@ function MessageComponent({
|
|||
decryptionFailed?: boolean;
|
||||
};
|
||||
onSetEditing: (editing: boolean) => void;
|
||||
user: User | null;
|
||||
user: SelectedUser<readonly ["UserId", "Avatar", "Display"]> | null;
|
||||
}) {
|
||||
const actuallyFailed =
|
||||
(message.failed && message.MessageState === "awaiting") ||
|
||||
|
|
@ -150,13 +149,14 @@ function MessageComponent({
|
|||
removeReaction,
|
||||
replyTo,
|
||||
} = useChat();
|
||||
const { get: getUser } = useUser();
|
||||
const [replyMessage, setReplyMessage] = useState<RawMessage | null>(null);
|
||||
const [replyUser, setReplyUser] = useState<User | null>(null);
|
||||
const { data: replyUser } = useUserFields(replyMessage?.SenderId ?? null, [
|
||||
"Avatar",
|
||||
"Display",
|
||||
]);
|
||||
useEffect(() => {
|
||||
if (!message.ReplyId || !ownId || !chatSecret) {
|
||||
setReplyMessage(null);
|
||||
setReplyUser(null);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -168,25 +168,20 @@ function MessageComponent({
|
|||
send,
|
||||
})
|
||||
.then(async (reply) => {
|
||||
const [Content, author] = await Promise.all([
|
||||
decryptChatText(chatSecret, reply.Content),
|
||||
getUser(reply.SenderId),
|
||||
]);
|
||||
const Content = await decryptChatText(chatSecret, reply.Content);
|
||||
if (!active) return;
|
||||
setReplyMessage({ ...reply, Content });
|
||||
setReplyUser(author);
|
||||
})
|
||||
.catch((err) => {
|
||||
if (!active) return;
|
||||
setReplyMessage(null);
|
||||
setReplyUser(null);
|
||||
log(1, "chat", "red", "Failed to get replied-to message", err);
|
||||
});
|
||||
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, [chatSecret, getUser, message.ReplyId, ownId, send, userId]);
|
||||
}, [chatSecret, message.ReplyId, ownId, send, userId]);
|
||||
const recordUse = useRecordEmojiUse();
|
||||
const editingRef = useRef(editing);
|
||||
const onSetEditingRef = useRef(onSetEditing);
|
||||
|
|
|
|||
|
|
@ -7,11 +7,13 @@ import {
|
|||
Skeleton,
|
||||
} from "@methanium/ui";
|
||||
import { Text } from "@methanium/ui/markdown";
|
||||
import type { User } from "@tensamin/user/context";
|
||||
import type { SelectedUser } from "@tensamin/user/context";
|
||||
import Wrapper from "@tensamin/user/wrapper";
|
||||
import { Forward, X } from "lucide-react";
|
||||
|
||||
function ReplyUser({ user }: { user: User }) {
|
||||
type ReplyUserData = SelectedUser<readonly ["Avatar", "Display"]>;
|
||||
|
||||
function ReplyUser({ user }: { user: ReplyUserData }) {
|
||||
return (
|
||||
<div className="flex gap-1 items-center">
|
||||
<Avatar className="h-5 w-5 shrink-0">
|
||||
|
|
@ -40,7 +42,7 @@ export default function ReplyBox({
|
|||
content?: string;
|
||||
loading?: boolean;
|
||||
onDismiss?: () => void;
|
||||
user?: User;
|
||||
user?: ReplyUserData;
|
||||
userId?: number;
|
||||
variant: "composer" | "message";
|
||||
}) {
|
||||
|
|
@ -71,6 +73,7 @@ export default function ReplyBox({
|
|||
) : userId ? (
|
||||
<Wrapper
|
||||
userId={userId}
|
||||
fields={["Avatar", "Display"]}
|
||||
loading={<Skeleton className="h-5 w-5 rounded-full" />}
|
||||
component={(resolvedUser) => <ReplyUser user={resolvedUser} />}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -458,7 +458,7 @@ export default function Provider({ children }: { children: ReactNode }) {
|
|||
secretId,
|
||||
version: CHAT_SECRET_VERSION,
|
||||
});
|
||||
const peerUser = await getUser(userIdValue);
|
||||
const peerUser = await getUser(userIdValue, ["PublicKey"]);
|
||||
const peerWrapped = await wrapChatSecret({
|
||||
chatSecret: rawSecret,
|
||||
recipientKemPublicKey: kemPublicKeyFromPublicKeyBundle(
|
||||
|
|
|
|||
|
|
@ -598,6 +598,7 @@ export default function Screen() {
|
|||
<Wrapper
|
||||
key={getMessageRenderKey(message)}
|
||||
userId={message.SenderId}
|
||||
fields={["UserId", "Avatar", "Display"]}
|
||||
loading={null}
|
||||
component={(user) => (
|
||||
<>
|
||||
|
|
|
|||
Loading…
Reference in a new issue