mirror of
https://github.com/revoltchat/revite.git
synced 2024-12-24 22:52:09 -05:00
Add global event pipeline.
Add message editor back.
This commit is contained in:
parent
ef2848ee25
commit
5db0854b42
5 changed files with 121 additions and 20 deletions
|
@ -4,9 +4,9 @@ import styled, { css } from "styled-components";
|
||||||
const Base = styled.div<{ unread?: boolean }>`
|
const Base = styled.div<{ unread?: boolean }>`
|
||||||
height: 0;
|
height: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 14px 10px;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
margin: 17px 12px 5px;
|
||||||
border-top: thin solid var(--tertiary-foreground);
|
border-top: thin solid var(--tertiary-foreground);
|
||||||
|
|
||||||
time {
|
time {
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { useChannel, useChannelPermission, useForceUpdate, useServer, useServerP
|
||||||
import { Children } from "../types/Preact";
|
import { Children } from "../types/Preact";
|
||||||
import LineDivider from "../components/ui/LineDivider";
|
import LineDivider from "../components/ui/LineDivider";
|
||||||
import { connectState } from "../redux/connector";
|
import { connectState } from "../redux/connector";
|
||||||
|
import { internalEmit } from "./eventEmitter";
|
||||||
|
|
||||||
interface ContextMenuData {
|
interface ContextMenuData {
|
||||||
user?: string;
|
user?: string;
|
||||||
|
@ -162,7 +163,7 @@ function ContextMenus(props: WithDispatcher) {
|
||||||
|
|
||||||
case "edit_message":
|
case "edit_message":
|
||||||
{
|
{
|
||||||
// InternalEventEmitter.emit("edit_message", data.id);
|
internalEmit("MessageRenderer", "edit_message", data.id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
18
src/lib/eventEmitter.ts
Normal file
18
src/lib/eventEmitter.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import EventEmitter from "eventemitter3";
|
||||||
|
export const InternalEvent = new EventEmitter();
|
||||||
|
|
||||||
|
export function internalSubscribe(ns: string, event: string, fn: (...args: any[]) => void) {
|
||||||
|
InternalEvent.addListener(ns + '/' + event, fn);
|
||||||
|
return () => InternalEvent.removeListener(ns + '/' + event, fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function internalEmit(ns: string, event: string, ...args: any[]) {
|
||||||
|
InternalEvent.emit(ns + '/' + event, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event structure: namespace/event
|
||||||
|
|
||||||
|
/// Event List
|
||||||
|
// - MessageRenderer/edit_last
|
||||||
|
// - MessageRenderer/edit_message
|
||||||
|
// - MessageBox/focus
|
84
src/pages/channels/messaging/MessageEditor.tsx
Normal file
84
src/pages/channels/messaging/MessageEditor.tsx
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
import styled from "styled-components";
|
||||||
|
import { useContext, useState } from "preact/hooks";
|
||||||
|
import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
|
||||||
|
import { MessageObject } from "../../../context/revoltjs/util";
|
||||||
|
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||||
|
import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
|
||||||
|
|
||||||
|
const EditorBase = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
resize: none;
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 3px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
background: var(--secondary-header);
|
||||||
|
}
|
||||||
|
|
||||||
|
.caption {
|
||||||
|
padding: 2px;
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--tertiary-foreground);
|
||||||
|
|
||||||
|
a {
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
message: MessageObject
|
||||||
|
finish: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function MessageEditor({ message, finish }: Props) {
|
||||||
|
const [ content, setContent ] = useState(message.content as string ?? '');
|
||||||
|
const client = useContext(AppContext);
|
||||||
|
|
||||||
|
async function save() {
|
||||||
|
finish();
|
||||||
|
|
||||||
|
if (content.length === 0) {
|
||||||
|
// @ts-expect-error
|
||||||
|
openScreen({ id: 'special_prompt', type: 'delete_message', target: message });
|
||||||
|
} else if (content !== message.content) {
|
||||||
|
await client.channels.editMessage(
|
||||||
|
message.channel,
|
||||||
|
message._id,
|
||||||
|
{ content }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EditorBase>
|
||||||
|
<TextAreaAutoSize
|
||||||
|
maxRows={3}
|
||||||
|
padding={12}
|
||||||
|
value={content}
|
||||||
|
maxLength={2000}
|
||||||
|
onChange={ev => setContent(ev.currentTarget.value)}
|
||||||
|
onKeyDown={e => {
|
||||||
|
if (
|
||||||
|
!e.shiftKey &&
|
||||||
|
e.key === "Enter" &&
|
||||||
|
!isTouchscreenDevice
|
||||||
|
) {
|
||||||
|
e.preventDefault();
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
// forceFocus
|
||||||
|
/>
|
||||||
|
<span className="caption">
|
||||||
|
escape to <a onClick={finish}>cancel</a> ·
|
||||||
|
enter to <a onClick={save}>save</a>
|
||||||
|
</span>
|
||||||
|
</EditorBase>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
import { decodeTime } from "ulid";
|
import { decodeTime } from "ulid";
|
||||||
|
import MessageEditor from "./MessageEditor";
|
||||||
|
import { Children } from "../../../types/Preact";
|
||||||
import { useEffect, useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
import ConversationStart from "./ConversationStart";
|
import ConversationStart from "./ConversationStart";
|
||||||
import { connectState } from "../../../redux/connector";
|
import { connectState } from "../../../redux/connector";
|
||||||
|
@ -7,11 +9,11 @@ import { RenderState } from "../../../lib/renderer/types";
|
||||||
import DateDivider from "../../../components/ui/DateDivider";
|
import DateDivider from "../../../components/ui/DateDivider";
|
||||||
import { QueuedMessage } from "../../../redux/reducers/queue";
|
import { QueuedMessage } from "../../../redux/reducers/queue";
|
||||||
import { MessageObject } from "../../../context/revoltjs/util";
|
import { MessageObject } from "../../../context/revoltjs/util";
|
||||||
|
import Message from "../../../components/common/messaging/Message";
|
||||||
import RequiresOnline from "../../../context/revoltjs/RequiresOnline";
|
import RequiresOnline from "../../../context/revoltjs/RequiresOnline";
|
||||||
import { useForceUpdate, useUsers } from "../../../context/revoltjs/hooks";
|
import { useForceUpdate, useUsers } from "../../../context/revoltjs/hooks";
|
||||||
import { Children } from "../../../types/Preact";
|
import { internalSubscribe, internalEmit } from "../../../lib/eventEmitter";
|
||||||
import { SystemMessage } from "../../../components/common/messaging/SystemMessage";
|
import { SystemMessage } from "../../../components/common/messaging/SystemMessage";
|
||||||
import Message from "../../../components/common/messaging/Message";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -32,8 +34,9 @@ function MessageRenderer({ id, state, queue }: Props) {
|
||||||
const [editing, setEditing] = useState<string | undefined>(undefined);
|
const [editing, setEditing] = useState<string | undefined>(undefined);
|
||||||
const stopEditing = () => {
|
const stopEditing = () => {
|
||||||
setEditing(undefined);
|
setEditing(undefined);
|
||||||
// InternalEventEmitter.emit("focus_textarea", "message");
|
internalEmit("MessageBox", "focus");
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function editLast() {
|
function editLast() {
|
||||||
if (state.type !== 'RENDER') return;
|
if (state.type !== 'RENDER') return;
|
||||||
|
@ -45,13 +48,12 @@ function MessageRenderer({ id, state, queue }: Props) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// InternalEventEmitter.addListener("edit_last", editLast);
|
const subs = [
|
||||||
// InternalEventEmitter.addListener("edit_message", setEditing);
|
internalSubscribe("MessageRenderer", "edit_last", editLast),
|
||||||
|
internalSubscribe("MessageRenderer", "edit_message", setEditing)
|
||||||
|
]
|
||||||
|
|
||||||
return () => {
|
return () => subs.forEach(unsub => unsub());
|
||||||
// InternalEventEmitter.removeListener("edit_last", editLast);
|
|
||||||
// InternalEventEmitter.removeListener("edit_message", setEditing);
|
|
||||||
};
|
|
||||||
}, [state.messages]);
|
}, [state.messages]);
|
||||||
|
|
||||||
let render: Children[] = [],
|
let render: Children[] = [],
|
||||||
|
@ -107,17 +109,13 @@ function MessageRenderer({ id, state, queue }: Props) {
|
||||||
<Message message={message}
|
<Message message={message}
|
||||||
key={message._id}
|
key={message._id}
|
||||||
head={head}
|
head={head}
|
||||||
|
content={
|
||||||
|
editing === message._id ?
|
||||||
|
<MessageEditor message={message} finish={stopEditing} />
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
attachContext />
|
attachContext />
|
||||||
);
|
);
|
||||||
/*render.push(
|
|
||||||
<Message
|
|
||||||
editing={editing === message._id ? stopEditing : undefined}
|
|
||||||
user={users.find(x => x?._id === message.author)}
|
|
||||||
message={message}
|
|
||||||
key={message._id}
|
|
||||||
head={head}
|
|
||||||
/>
|
|
||||||
);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
previous = message;
|
previous = message;
|
||||||
|
|
Loading…
Reference in a new issue