mirror of
https://github.com/spacebarchat/client.git
synced 2024-11-25 11:42:30 +01:00
Message Sending
This commit is contained in:
parent
f95dfe4264
commit
78191305cd
@ -1,6 +1,9 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import Channel from "../stores/objects/Channel";
|
||||
import Snowflake from "../utils/Snowflake";
|
||||
import { useAppStore } from "../stores/AppStore";
|
||||
import User from "../stores/objects/User";
|
||||
|
||||
const Container = styled.div`
|
||||
margin-top: -8px;
|
||||
@ -33,8 +36,10 @@ interface Props {
|
||||
}
|
||||
|
||||
function MessageInput(props: Props) {
|
||||
const app = useAppStore();
|
||||
const wrapperRef = React.useRef<HTMLDivElement>(null);
|
||||
const placeholderRef = React.useRef<HTMLDivElement>(null);
|
||||
const inputRef = React.useRef<HTMLDivElement>(null);
|
||||
const [content, setContent] = React.useState("");
|
||||
|
||||
React.useEffect(() => {
|
||||
@ -48,6 +53,22 @@ function MessageInput(props: Props) {
|
||||
if (!content.length)
|
||||
placeholderRef.current!.style.setProperty("display", "block");
|
||||
else placeholderRef.current!.style.setProperty("display", "none");
|
||||
|
||||
// update the input content
|
||||
if (inputRef.current) {
|
||||
// handle empty input
|
||||
if (!content.length) {
|
||||
inputRef.current.innerHTML = "";
|
||||
return;
|
||||
} else {
|
||||
const selection = window.getSelection();
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(inputRef.current);
|
||||
range.collapse(false);
|
||||
selection?.removeAllRanges();
|
||||
selection?.addRange(range);
|
||||
}
|
||||
}
|
||||
}, [content]);
|
||||
|
||||
// this function makes the input element grow as the user types
|
||||
@ -59,6 +80,11 @@ function MessageInput(props: Props) {
|
||||
wrapperRef.current.scrollHeight + "px";
|
||||
}
|
||||
|
||||
function resetInput() {
|
||||
setContent("");
|
||||
adjustInputHeight();
|
||||
}
|
||||
|
||||
function onChange(e: React.FormEvent<HTMLDivElement>) {
|
||||
const target = e.target as HTMLDivElement;
|
||||
const text = target.innerText;
|
||||
@ -67,6 +93,35 @@ function MessageInput(props: Props) {
|
||||
adjustInputHeight();
|
||||
}
|
||||
|
||||
function onKeyDown(e: React.KeyboardEvent<HTMLDivElement>) {
|
||||
if (!props.channel) {
|
||||
console.warn("No channel selected, cannot send message");
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.key === "Enter") {
|
||||
e.preventDefault();
|
||||
// TODO: experiments
|
||||
// TODO: check if we can actually message this channel
|
||||
|
||||
if (!props.channel.canSendMessage(content)) return;
|
||||
|
||||
const nonce = Snowflake.generate();
|
||||
app.queue.add({
|
||||
id: nonce,
|
||||
author: app.account! as unknown as User,
|
||||
content,
|
||||
channel: props.channel.id,
|
||||
});
|
||||
|
||||
props.channel.sendMessage({ content, nonce }).catch((error) => {
|
||||
app.queue.error(nonce, error as string);
|
||||
});
|
||||
|
||||
resetInput();
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<InnerContainer>
|
||||
@ -118,6 +173,8 @@ function MessageInput(props: Props) {
|
||||
autoCorrect="off"
|
||||
contentEditable="true"
|
||||
onInput={onChange}
|
||||
onKeyDown={onKeyDown}
|
||||
ref={inputRef}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,6 +17,7 @@ import { ChannelType, Routes } from "@spacebarchat/spacebar-api-types/v9";
|
||||
import { action, makeObservable, observable } from "mobx";
|
||||
import AppStore from "../AppStore";
|
||||
import MessageStore from "../MessageStore";
|
||||
import { APIError } from "../../utils/interfaces/api";
|
||||
|
||||
export default class Channel {
|
||||
private readonly app: AppStore;
|
||||
@ -170,19 +171,25 @@ export default class Channel {
|
||||
|
||||
this.hasFetchedMessages = true;
|
||||
console.log(`Fetching messags for ${this.id}`);
|
||||
// TODO: catch errors
|
||||
const messages = await app.rest.get<RESTGetAPIChannelMessagesResult>(
|
||||
app.rest.get<RESTGetAPIChannelMessagesResult | APIError>(
|
||||
Routes.channelMessages(this.id),
|
||||
opts,
|
||||
);
|
||||
this.messages.addAll(
|
||||
messages.filter((x) => !this.messages.has(x.id)).reverse(),
|
||||
// .sort((a, b) => {
|
||||
// const aTimestamp = new Date(a.timestamp as unknown as string);
|
||||
// const bTimestamp = new Date(b.timestamp as unknown as string);
|
||||
// return aTimestamp.getTime() - bTimestamp.getTime();
|
||||
// })
|
||||
);
|
||||
).then((res) => {
|
||||
if("code" in res) {
|
||||
console.error(res);
|
||||
return;
|
||||
}
|
||||
this.messages.addAll(
|
||||
res.filter((x) => !this.messages.has(x.id)).reverse(),
|
||||
// .sort((a, b) => {
|
||||
// const aTimestamp = new Date(a.timestamp as unknown as string);
|
||||
// const bTimestamp = new Date(b.timestamp as unknown as string);
|
||||
// return aTimestamp.getTime() - bTimestamp.getTime();
|
||||
// })
|
||||
);
|
||||
}).catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
@ -110,4 +110,17 @@ export enum APIErrorCodes {
|
||||
ACCOUNT_DISABLED = 20013,
|
||||
}
|
||||
|
||||
export interface APIError {
|
||||
code: APIErrorCodes;
|
||||
message: string;
|
||||
errors?: {
|
||||
[key: string]: {
|
||||
_errors: {
|
||||
code: string;
|
||||
message: string;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// export type RESTAPIPostInviteResponse = {} | IAPIError;
|
||||
|
Loading…
Reference in New Issue
Block a user