forked from abner/for-legacy-web
Use tabWidth 4 without actual tabs.
This commit is contained in:
@@ -26,190 +26,190 @@ import ConversationStart from "./ConversationStart";
|
||||
import MessageEditor from "./MessageEditor";
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
state: RenderState;
|
||||
queue: QueuedMessage[];
|
||||
id: string;
|
||||
state: RenderState;
|
||||
queue: QueuedMessage[];
|
||||
}
|
||||
|
||||
const BlockedMessage = styled.div`
|
||||
font-size: 0.8em;
|
||||
margin-top: 6px;
|
||||
padding: 4px 64px;
|
||||
color: var(--tertiary-foreground);
|
||||
font-size: 0.8em;
|
||||
margin-top: 6px;
|
||||
padding: 4px 64px;
|
||||
color: var(--tertiary-foreground);
|
||||
|
||||
&:hover {
|
||||
background: var(--hover);
|
||||
}
|
||||
&:hover {
|
||||
background: var(--hover);
|
||||
}
|
||||
`;
|
||||
|
||||
function MessageRenderer({ id, state, queue }: Props) {
|
||||
if (state.type !== "RENDER") return null;
|
||||
if (state.type !== "RENDER") return null;
|
||||
|
||||
const client = useContext(AppContext);
|
||||
const userId = client.user!._id;
|
||||
const client = useContext(AppContext);
|
||||
const userId = client.user!._id;
|
||||
|
||||
const [editing, setEditing] = useState<string | undefined>(undefined);
|
||||
const stopEditing = () => {
|
||||
setEditing(undefined);
|
||||
internalEmit("TextArea", "focus", "message");
|
||||
};
|
||||
const [editing, setEditing] = useState<string | undefined>(undefined);
|
||||
const stopEditing = () => {
|
||||
setEditing(undefined);
|
||||
internalEmit("TextArea", "focus", "message");
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
function editLast() {
|
||||
if (state.type !== "RENDER") return;
|
||||
for (let i = state.messages.length - 1; i >= 0; i--) {
|
||||
if (state.messages[i].author === userId) {
|
||||
setEditing(state.messages[i]._id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
function editLast() {
|
||||
if (state.type !== "RENDER") return;
|
||||
for (let i = state.messages.length - 1; i >= 0; i--) {
|
||||
if (state.messages[i].author === userId) {
|
||||
setEditing(state.messages[i]._id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const subs = [
|
||||
internalSubscribe("MessageRenderer", "edit_last", editLast),
|
||||
internalSubscribe("MessageRenderer", "edit_message", setEditing),
|
||||
];
|
||||
const subs = [
|
||||
internalSubscribe("MessageRenderer", "edit_last", editLast),
|
||||
internalSubscribe("MessageRenderer", "edit_message", setEditing),
|
||||
];
|
||||
|
||||
return () => subs.forEach((unsub) => unsub());
|
||||
}, [state.messages]);
|
||||
return () => subs.forEach((unsub) => unsub());
|
||||
}, [state.messages]);
|
||||
|
||||
let render: Children[] = [],
|
||||
previous: MessageObject | undefined;
|
||||
let render: Children[] = [],
|
||||
previous: MessageObject | undefined;
|
||||
|
||||
if (state.atTop) {
|
||||
render.push(<ConversationStart id={id} />);
|
||||
} else {
|
||||
render.push(
|
||||
<RequiresOnline>
|
||||
<Preloader type="ring" />
|
||||
</RequiresOnline>,
|
||||
);
|
||||
}
|
||||
if (state.atTop) {
|
||||
render.push(<ConversationStart id={id} />);
|
||||
} else {
|
||||
render.push(
|
||||
<RequiresOnline>
|
||||
<Preloader type="ring" />
|
||||
</RequiresOnline>,
|
||||
);
|
||||
}
|
||||
|
||||
let head = true;
|
||||
function compare(
|
||||
current: string,
|
||||
curAuthor: string,
|
||||
previous: string,
|
||||
prevAuthor: string,
|
||||
) {
|
||||
const atime = decodeTime(current),
|
||||
adate = new Date(atime),
|
||||
btime = decodeTime(previous),
|
||||
bdate = new Date(btime);
|
||||
let head = true;
|
||||
function compare(
|
||||
current: string,
|
||||
curAuthor: string,
|
||||
previous: string,
|
||||
prevAuthor: string,
|
||||
) {
|
||||
const atime = decodeTime(current),
|
||||
adate = new Date(atime),
|
||||
btime = decodeTime(previous),
|
||||
bdate = new Date(btime);
|
||||
|
||||
if (
|
||||
adate.getFullYear() !== bdate.getFullYear() ||
|
||||
adate.getMonth() !== bdate.getMonth() ||
|
||||
adate.getDate() !== bdate.getDate()
|
||||
) {
|
||||
render.push(<DateDivider date={adate} />);
|
||||
head = true;
|
||||
}
|
||||
if (
|
||||
adate.getFullYear() !== bdate.getFullYear() ||
|
||||
adate.getMonth() !== bdate.getMonth() ||
|
||||
adate.getDate() !== bdate.getDate()
|
||||
) {
|
||||
render.push(<DateDivider date={adate} />);
|
||||
head = true;
|
||||
}
|
||||
|
||||
head = curAuthor !== prevAuthor || Math.abs(btime - atime) >= 420000;
|
||||
}
|
||||
head = curAuthor !== prevAuthor || Math.abs(btime - atime) >= 420000;
|
||||
}
|
||||
|
||||
let blocked = 0;
|
||||
function pushBlocked() {
|
||||
render.push(
|
||||
<BlockedMessage>
|
||||
<X size={16} /> {blocked} blocked messages
|
||||
</BlockedMessage>,
|
||||
);
|
||||
blocked = 0;
|
||||
}
|
||||
let blocked = 0;
|
||||
function pushBlocked() {
|
||||
render.push(
|
||||
<BlockedMessage>
|
||||
<X size={16} /> {blocked} blocked messages
|
||||
</BlockedMessage>,
|
||||
);
|
||||
blocked = 0;
|
||||
}
|
||||
|
||||
for (const message of state.messages) {
|
||||
if (previous) {
|
||||
compare(message._id, message.author, previous._id, previous.author);
|
||||
}
|
||||
for (const message of state.messages) {
|
||||
if (previous) {
|
||||
compare(message._id, message.author, previous._id, previous.author);
|
||||
}
|
||||
|
||||
if (message.author === "00000000000000000000000000") {
|
||||
render.push(
|
||||
<SystemMessage
|
||||
key={message._id}
|
||||
message={message}
|
||||
attachContext
|
||||
/>,
|
||||
);
|
||||
} else {
|
||||
// ! FIXME: temp solution
|
||||
if (
|
||||
client.users.get(message.author)?.relationship ===
|
||||
Users.Relationship.Blocked
|
||||
) {
|
||||
blocked++;
|
||||
} else {
|
||||
if (blocked > 0) pushBlocked();
|
||||
if (message.author === "00000000000000000000000000") {
|
||||
render.push(
|
||||
<SystemMessage
|
||||
key={message._id}
|
||||
message={message}
|
||||
attachContext
|
||||
/>,
|
||||
);
|
||||
} else {
|
||||
// ! FIXME: temp solution
|
||||
if (
|
||||
client.users.get(message.author)?.relationship ===
|
||||
Users.Relationship.Blocked
|
||||
) {
|
||||
blocked++;
|
||||
} else {
|
||||
if (blocked > 0) pushBlocked();
|
||||
|
||||
render.push(
|
||||
<Message
|
||||
message={message}
|
||||
key={message._id}
|
||||
head={head}
|
||||
content={
|
||||
editing === message._id ? (
|
||||
<MessageEditor
|
||||
message={message}
|
||||
finish={stopEditing}
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
attachContext
|
||||
/>,
|
||||
);
|
||||
}
|
||||
}
|
||||
render.push(
|
||||
<Message
|
||||
message={message}
|
||||
key={message._id}
|
||||
head={head}
|
||||
content={
|
||||
editing === message._id ? (
|
||||
<MessageEditor
|
||||
message={message}
|
||||
finish={stopEditing}
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
attachContext
|
||||
/>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
previous = message;
|
||||
}
|
||||
previous = message;
|
||||
}
|
||||
|
||||
if (blocked > 0) pushBlocked();
|
||||
if (blocked > 0) pushBlocked();
|
||||
|
||||
const nonces = state.messages.map((x) => x.nonce);
|
||||
if (state.atBottom) {
|
||||
for (const msg of queue) {
|
||||
if (msg.channel !== id) continue;
|
||||
if (nonces.includes(msg.id)) continue;
|
||||
const nonces = state.messages.map((x) => x.nonce);
|
||||
if (state.atBottom) {
|
||||
for (const msg of queue) {
|
||||
if (msg.channel !== id) continue;
|
||||
if (nonces.includes(msg.id)) continue;
|
||||
|
||||
if (previous) {
|
||||
compare(msg.id, userId!, previous._id, previous.author);
|
||||
if (previous) {
|
||||
compare(msg.id, userId!, previous._id, previous.author);
|
||||
|
||||
previous = {
|
||||
_id: msg.id,
|
||||
data: { author: userId! },
|
||||
} as any;
|
||||
}
|
||||
previous = {
|
||||
_id: msg.id,
|
||||
data: { author: userId! },
|
||||
} as any;
|
||||
}
|
||||
|
||||
render.push(
|
||||
<Message
|
||||
message={{
|
||||
...msg.data,
|
||||
replies: msg.data.replies.map((x) => x.id),
|
||||
}}
|
||||
key={msg.id}
|
||||
queued={msg}
|
||||
head={head}
|
||||
attachContext
|
||||
/>,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
render.push(
|
||||
<RequiresOnline>
|
||||
<Preloader type="ring" />
|
||||
</RequiresOnline>,
|
||||
);
|
||||
}
|
||||
render.push(
|
||||
<Message
|
||||
message={{
|
||||
...msg.data,
|
||||
replies: msg.data.replies.map((x) => x.id),
|
||||
}}
|
||||
key={msg.id}
|
||||
queued={msg}
|
||||
head={head}
|
||||
attachContext
|
||||
/>,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
render.push(
|
||||
<RequiresOnline>
|
||||
<Preloader type="ring" />
|
||||
</RequiresOnline>,
|
||||
);
|
||||
}
|
||||
|
||||
return <>{render}</>;
|
||||
return <>{render}</>;
|
||||
}
|
||||
|
||||
export default memo(
|
||||
connectState<Omit<Props, "queue">>(MessageRenderer, (state) => {
|
||||
return {
|
||||
queue: state.queue,
|
||||
};
|
||||
}),
|
||||
connectState<Omit<Props, "queue">>(MessageRenderer, (state) => {
|
||||
return {
|
||||
queue: state.queue,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user