stoat-for-desktop/components/app/interface/channels/text/DraftMessage.tsx

115 lines
3.0 KiB
TypeScript

import { For, Match, Switch } from "solid-js";
import { Trans } from "@lingui-solid/solid/macro";
import type { Channel } from "stoat.js";
import { styled } from "styled-system/jsx";
import { useClient, useUser } from "@revolt/client";
import { Markdown } from "@revolt/markdown";
import { userInformation } from "@revolt/markdown/users";
import { useState } from "@revolt/state";
import type { UnsentMessage } from "@revolt/state/stores/Draft";
import {
Avatar,
MessageContainer,
MessageReply,
SizedContent,
Text,
Username,
} from "@revolt/ui";
import { DraftMessageContextMenu } from "../../../menus/DraftMessageContextMenu";
interface Props {
draft: UnsentMessage;
channel: Channel;
tail?: boolean;
}
/**
* Unsent message preview
*/
export function DraftMessage(props: Props) {
const user = useUser();
const state = useState();
const client = useClient();
const userInfo = () => userInformation(user(), props.channel.server?.member);
return (
<MessageContainer
tail={
props.tail && (!props.draft.replies || props.draft.replies.length === 0)
}
avatar={<Avatar src={userInfo().avatar} size={36} />}
timestamp={
props.draft.status === "sending" ? (
<Trans>Sending...</Trans>
) : props.draft.status === "failed" ? (
<Trans>Failed to send</Trans>
) : (
<Trans>Unsent message</Trans>
)
}
sendStatus={props.draft.status === "sending" ? "sending" : "failed"}
username={<Username username={userInfo().username} />}
header={
<For each={props.draft.replies}>
{(reply) => (
<MessageReply
message={client().messages.get(reply.id)}
mention={reply.mention}
/>
)}
</For>
}
contextMenu={() => (
<DraftMessageContextMenu draft={props.draft} channel={props.channel} />
)}
compact={state.settings.getValue("appearance:compact_mode")}
>
<BreakText>
<Markdown content={props.draft.content!} />
</BreakText>
<For each={props.draft.files}>
{(id) => {
const file = state.draft.getFile(id);
return (
<>
<Text class="label">
Uploading file `{file.file.name}`...{" "}
{(file.uploadProgress[0]() * 100).toFixed()}%
</Text>
<Switch>
<Match when={file.dimensions}>
<SizedContent
width={file.dimensions![0]}
height={file.dimensions![1]}
>
<img src={file.dataUri} />
</SizedContent>
</Match>
</Switch>
</>
);
}}
</For>
</MessageContainer>
);
}
/**
* Break all text and prevent overflow from math blocks
*/
const BreakText = styled("div", {
base: {
wordBreak: "break-word",
"& .math": {
overflowX: "auto",
overflowY: "hidden",
maxHeight: "100vh",
},
},
});