mirror of
https://github.com/revoltchat/revite.git
synced 2024-11-21 22:50:59 -05:00
feat(messaging): quick action bar (#493)
Co-authored-by: Kuhn Chris <kuhnchris+github@kuhnchris.eu> Co-authored-by: Paul Makles <paulmakles@gmail.com>
This commit is contained in:
parent
fe382f9532
commit
f509acbe80
3 changed files with 130 additions and 2 deletions
|
@ -25,6 +25,7 @@ import MessageBase, {
|
|||
} from "./MessageBase";
|
||||
import Attachment from "./attachments/Attachment";
|
||||
import { MessageReply } from "./attachments/MessageReply";
|
||||
import { MessageOverlayBar } from "./bars/MessageOverlayBar";
|
||||
import Embed from "./embed/Embed";
|
||||
import InviteList from "./embed/EmbedInvite";
|
||||
|
||||
|
@ -86,7 +87,7 @@ const Message = observer(
|
|||
};
|
||||
|
||||
// ! FIXME(?): animate on hover
|
||||
const [animate, setAnimate] = useState(false);
|
||||
const [mouseHovering, setAnimate] = useState(false);
|
||||
|
||||
return (
|
||||
<div id={message._id}>
|
||||
|
@ -135,7 +136,7 @@ const Message = observer(
|
|||
size={36}
|
||||
onContextMenu={userContext}
|
||||
onClick={handleUserClick}
|
||||
animate={animate}
|
||||
animate={mouseHovering}
|
||||
showServerIdentity
|
||||
/>
|
||||
) : (
|
||||
|
@ -174,6 +175,12 @@ const Message = observer(
|
|||
{message.embeds?.map((embed, index) => (
|
||||
<Embed key={index} embed={embed} />
|
||||
))}
|
||||
{mouseHovering && !replacement && (
|
||||
<MessageOverlayBar
|
||||
message={message}
|
||||
queued={queued}
|
||||
/>
|
||||
)}
|
||||
</MessageContent>
|
||||
</MessageBase>
|
||||
</div>
|
||||
|
|
|
@ -195,6 +195,10 @@ export const MessageInfo = styled.div`
|
|||
`;
|
||||
|
||||
export const MessageContent = styled.div`
|
||||
// Position relatively so we can put
|
||||
// the overlay in the right place.
|
||||
position: relative;
|
||||
|
||||
min-width: 0;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
|
|
117
src/components/common/messaging/bars/MessageOverlayBar.tsx
Normal file
117
src/components/common/messaging/bars/MessageOverlayBar.tsx
Normal file
|
@ -0,0 +1,117 @@
|
|||
import {
|
||||
DotsHorizontalRounded,
|
||||
Edit,
|
||||
Reply,
|
||||
Trash,
|
||||
} from "@styled-icons/boxicons-regular";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { ChannelPermission } from "revolt.js";
|
||||
import { Message as MessageObject } from "revolt.js/dist/maps/Messages";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { openContextMenu } from "preact-context-menu";
|
||||
|
||||
import { internalEmit } from "../../../../lib/eventEmitter";
|
||||
|
||||
import { QueuedMessage } from "../../../../mobx/stores/MessageQueue";
|
||||
|
||||
import {
|
||||
Screen,
|
||||
useIntermediate,
|
||||
} from "../../../../context/intermediate/Intermediate";
|
||||
import { useClient } from "../../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import IconButton from "../../../ui/IconButton";
|
||||
|
||||
interface Props {
|
||||
message: MessageObject;
|
||||
queued?: QueuedMessage;
|
||||
}
|
||||
|
||||
const OverlayBar = styled.div`
|
||||
display: inline-flex;
|
||||
position: absolute;
|
||||
justify-self: end;
|
||||
align-self: end;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
|
||||
right: 0;
|
||||
top: -18px;
|
||||
z-index: 0;
|
||||
overflow: hidden;
|
||||
|
||||
border-radius: 5px;
|
||||
background: var(--primary-header);
|
||||
border: 1px sold var(--background);
|
||||
`;
|
||||
|
||||
const Entry = styled.div`
|
||||
padding: 4px;
|
||||
flex-shrink: 0;
|
||||
cursor: pointer;
|
||||
transition: 0.2s ease background-color;
|
||||
|
||||
&:hover {
|
||||
background: var(--secondary-header);
|
||||
}
|
||||
`;
|
||||
|
||||
export const MessageOverlayBar = observer(({ message, queued }: Props) => {
|
||||
const client = useClient();
|
||||
const { openScreen } = useIntermediate();
|
||||
const isAuthor = message.author_id === client.user!._id;
|
||||
|
||||
return (
|
||||
<OverlayBar>
|
||||
<Entry onClick={() => internalEmit("ReplyBar", "add", message)}>
|
||||
<IconButton>
|
||||
<Reply size={24} />
|
||||
</IconButton>
|
||||
</Entry>
|
||||
{isAuthor && (
|
||||
<Entry
|
||||
onClick={() =>
|
||||
internalEmit(
|
||||
"MessageRenderer",
|
||||
"edit_message",
|
||||
message._id,
|
||||
)
|
||||
}>
|
||||
<IconButton>
|
||||
<Edit size={24} />
|
||||
</IconButton>
|
||||
</Entry>
|
||||
)}
|
||||
{isAuthor ||
|
||||
(message.channel &&
|
||||
message.channel.permission &
|
||||
ChannelPermission.ManageMessages) ? (
|
||||
<Entry
|
||||
onClick={() =>
|
||||
openScreen({
|
||||
id: "special_prompt",
|
||||
type: "delete_message",
|
||||
target: message,
|
||||
} as unknown as Screen)
|
||||
}>
|
||||
<IconButton>
|
||||
<Trash size={24} />
|
||||
</IconButton>
|
||||
</Entry>
|
||||
) : undefined}
|
||||
<Entry
|
||||
onClick={() =>
|
||||
openContextMenu("Menu", {
|
||||
message,
|
||||
contextualChannel: message.channel_id,
|
||||
queued,
|
||||
})
|
||||
}>
|
||||
<IconButton>
|
||||
<DotsHorizontalRounded size={24} />
|
||||
</IconButton>
|
||||
</Entry>
|
||||
</OverlayBar>
|
||||
);
|
||||
});
|
Loading…
Reference in a new issue