115 lines
3.0 KiB
TypeScript
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",
|
|
},
|
|
},
|
|
});
|