format and use more aggressive tabstop widths
This commit is contained in:
parent
7d4953fea6
commit
56feab2ea1
7 changed files with 366 additions and 344 deletions
|
@ -90,15 +90,6 @@ const App = ({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// if (!username) {
|
|
||||||
// var newName = prompt(home.userNamePrompt) as string;
|
|
||||||
// while (!validateName(newName)) {
|
|
||||||
// console.log(newName);
|
|
||||||
|
|
||||||
// prompt("Username invalid! Please enter again.") as string;
|
|
||||||
// }
|
|
||||||
// setUsername(newName);
|
|
||||||
// }
|
|
||||||
if (!login) {
|
if (!login) {
|
||||||
return <></>;
|
return <></>;
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import React, {
|
import React, {
|
||||||
ReactElement,
|
ReactElement,
|
||||||
useContext,
|
useContext,
|
||||||
useEffect,
|
useEffect,
|
||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { MessageDisplay } from "../MessageDisplay/MessageDisplay";
|
import { MessageDisplay } from "../MessageDisplay/MessageDisplay";
|
||||||
import { Client } from "@stomp/stompjs";
|
import { Client } from "@stomp/stompjs";
|
||||||
|
@ -13,117 +13,128 @@ import strings from "../Intl/strings.json";
|
||||||
import { LangContext } from "../context";
|
import { LangContext } from "../context";
|
||||||
import { connectionAddress, endpoints } from "../consts";
|
import { connectionAddress, endpoints } from "../consts";
|
||||||
const Chat = ({ user }: { user: string }): React.ReactElement => {
|
const Chat = ({ user }: { user: string }): React.ReactElement => {
|
||||||
const lang = useContext(LangContext);
|
const lang = useContext(LangContext);
|
||||||
const chatPage = strings[lang].chat;
|
const chatPage = strings[lang].chat;
|
||||||
const [messages, setMessages] = useState<ReactElement[]>([]);
|
const [messages, setMessages] = useState<ReactElement[]>([]);
|
||||||
let stompClientRef = useRef(
|
let stompClientRef = useRef(
|
||||||
new Client({
|
new Client({
|
||||||
brokerURL: connectionAddress,
|
brokerURL: connectionAddress,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
// TODO solve issue with non-static markup
|
// TODO solve issue with non-static markup
|
||||||
stompClientRef.current.onConnect = (frame) => {
|
stompClientRef.current.onConnect = (frame) => {
|
||||||
stompClientRef.current.subscribe(endpoints.subscription, (message) => {
|
stompClientRef.current.subscribe(
|
||||||
console.log(`Collected new message: ${message.body}`);
|
endpoints.subscription,
|
||||||
const messageBody = JSON.parse(message.body) as Message;
|
(message) => {
|
||||||
console.log(messageBody);
|
console.log(
|
||||||
setMessages((message) => {
|
`Collected new message: ${message.body}`
|
||||||
return message.concat([
|
);
|
||||||
<MessageDisplay
|
const messageBody = JSON.parse(
|
||||||
key={`${messageBody.type}@${messageBody.timeMillis}`}
|
message.body
|
||||||
{...messageBody}
|
) as Message;
|
||||||
/>,
|
console.log(messageBody);
|
||||||
]);
|
setMessages((message) => {
|
||||||
});
|
return message.concat([
|
||||||
});
|
<MessageDisplay
|
||||||
stompClientRef.current.publish({
|
key={`${messageBody.type}@${messageBody.timeMillis}`}
|
||||||
body: JSON.stringify({
|
{...messageBody}
|
||||||
type: MessageType.HELLO,
|
/>,
|
||||||
fromUserId: user,
|
]);
|
||||||
toUserId: "everyone",
|
});
|
||||||
content: `${user} has joined the server!`,
|
}
|
||||||
timeMillis: Date.now(),
|
);
|
||||||
}),
|
stompClientRef.current.publish({
|
||||||
destination: endpoints.destination,
|
body: JSON.stringify({
|
||||||
});
|
type: MessageType.HELLO,
|
||||||
};
|
fromUserId: user,
|
||||||
|
toUserId: "everyone",
|
||||||
|
content: `${user} has joined the server!`,
|
||||||
|
timeMillis: Date.now(),
|
||||||
|
}),
|
||||||
|
destination: endpoints.destination,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// Generic error handlers
|
||||||
|
stompClientRef.current.onWebSocketError = (error) => {
|
||||||
|
console.error("Error with websocket", error);
|
||||||
|
};
|
||||||
|
|
||||||
// Generic error handlers
|
stompClientRef.current.onStompError = (frame) => {
|
||||||
stompClientRef.current.onWebSocketError = (error) => {
|
console.error(
|
||||||
console.error("Error with websocket", error);
|
"Broker reported error: " + frame.headers["message"]
|
||||||
};
|
);
|
||||||
|
console.error("Additional details: " + frame.body);
|
||||||
|
};
|
||||||
|
|
||||||
stompClientRef.current.onStompError = (frame) => {
|
// Button press event handler.
|
||||||
console.error("Broker reported error: " + frame.headers["message"]);
|
const sendData = () => {
|
||||||
console.error("Additional details: " + frame.body);
|
const entryElement: HTMLInputElement = document.getElementById(
|
||||||
};
|
"data-entry"
|
||||||
|
) as HTMLInputElement;
|
||||||
// Button press event handler.
|
if (entryElement.value === "") {
|
||||||
const sendData = () => {
|
return;
|
||||||
const entryElement: HTMLInputElement = document.getElementById(
|
}
|
||||||
"data-entry"
|
const messageData: Message = {
|
||||||
) as HTMLInputElement;
|
type: MessageType.MESSAGE,
|
||||||
if (entryElement.value === "") {
|
fromUserId: user,
|
||||||
return;
|
toUserId: "everyone",
|
||||||
}
|
content: entryElement.value,
|
||||||
const messageData: Message = {
|
timeMillis: Date.now(),
|
||||||
type: MessageType.MESSAGE,
|
};
|
||||||
fromUserId: user,
|
console.log(
|
||||||
toUserId: "everyone",
|
`STOMP connection status: ${stompClientRef.current.connected}`
|
||||||
content: entryElement.value,
|
);
|
||||||
timeMillis: Date.now(),
|
stompClientRef.current.publish({
|
||||||
};
|
body: JSON.stringify(messageData),
|
||||||
console.log(
|
destination: endpoints.destination,
|
||||||
`STOMP connection status: ${stompClientRef.current.connected}`
|
headers: {
|
||||||
);
|
"Content-Type":
|
||||||
stompClientRef.current.publish({
|
"application/json; charset=utf-8",
|
||||||
body: JSON.stringify(messageData),
|
},
|
||||||
destination: endpoints.destination,
|
});
|
||||||
headers: {
|
entryElement.value = "";
|
||||||
"Content-Type": "application/json; charset=utf-8",
|
};
|
||||||
},
|
useEffect(() => {
|
||||||
});
|
// Stomp client is disconnected after each re-render
|
||||||
entryElement.value = "";
|
// This should be actively avoided
|
||||||
};
|
stompClientRef.current.activate();
|
||||||
useEffect(() => {
|
return () => {
|
||||||
// Stomp client is disconnected after each re-render
|
stompClientRef.current.deactivate();
|
||||||
// This should be actively avoided
|
};
|
||||||
stompClientRef.current.activate();
|
}, []);
|
||||||
return () => {
|
// https://www.w3schools.com/jsref/obj_keyboardevent.asp
|
||||||
stompClientRef.current.deactivate();
|
document.addEventListener("keydown", (ev: KeyboardEvent) => {
|
||||||
};
|
if (ev.key === "Enter") {
|
||||||
}, []);
|
sendData();
|
||||||
// https://www.w3schools.com/jsref/obj_keyboardevent.asp
|
}
|
||||||
document.addEventListener("keydown", (ev: KeyboardEvent) => {
|
});
|
||||||
if (ev.key === "Enter") {
|
useEffect(() => {
|
||||||
sendData();
|
try {
|
||||||
}
|
const elem = document.querySelector(
|
||||||
});
|
".chat-inner-wrapper"
|
||||||
useEffect(() => {
|
);
|
||||||
try {
|
if (elem) {
|
||||||
const elem = document.querySelector(".chat-inner-wrapper");
|
elem.scrollTop = elem.scrollHeight;
|
||||||
if (elem) {
|
} else {
|
||||||
elem.scrollTop = elem.scrollHeight;
|
}
|
||||||
} else {
|
} catch (err) {
|
||||||
}
|
console.log("error encountered");
|
||||||
} catch (err) {
|
}
|
||||||
console.log("error encountered");
|
return () => {};
|
||||||
}
|
}, [messages]);
|
||||||
return () => {};
|
return (
|
||||||
}, [messages]);
|
<fieldset className="chat">
|
||||||
return (
|
<legend>
|
||||||
<fieldset className="chat">
|
Logged in as <b>{user}</b>
|
||||||
<legend>
|
</legend>
|
||||||
Logged in as <b>{user}</b>
|
<div className="chat-inner-wrapper">{messages}</div>
|
||||||
</legend>
|
<span className="entry-box">
|
||||||
<div className="chat-inner-wrapper">{messages}</div>
|
<input id="data-entry"></input>
|
||||||
<span className="entry-box">
|
<button onClick={() => sendData()}>
|
||||||
<input id="data-entry"></input>
|
{chatPage.sendButtonPrompt}
|
||||||
<button onClick={() => sendData()}>
|
</button>
|
||||||
{chatPage.sendButtonPrompt}
|
</span>
|
||||||
</button>
|
</fieldset>
|
||||||
</span>
|
);
|
||||||
</fieldset>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
export default Chat;
|
export default Chat;
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
.uname-error-text {
|
.uname-error-text {
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,138 +4,156 @@ import { LoginType } from "../context";
|
||||||
import { User } from "../type/userTypes";
|
import { User } from "../type/userTypes";
|
||||||
import "./Login.css";
|
import "./Login.css";
|
||||||
const encrypt = (rawPasswordString: string) => {
|
const encrypt = (rawPasswordString: string) => {
|
||||||
// TODO Encryption method stub
|
// TODO Encryption method stub
|
||||||
return rawPasswordString;
|
return rawPasswordString;
|
||||||
};
|
};
|
||||||
export const Login = ({
|
export const Login = ({
|
||||||
setLogin,
|
setLogin,
|
||||||
}: {
|
}: {
|
||||||
setLogin: (newLogin: LoginType | undefined) => void;
|
setLogin: (newLogin: LoginType | undefined) => void;
|
||||||
}): React.ReactElement => {
|
}): React.ReactElement => {
|
||||||
const [valid, setValid] = useState<boolean | undefined>(true);
|
const [valid, setValid] = useState<boolean | undefined>(true);
|
||||||
const [validText, setValidText] = useState<string | undefined>();
|
const [validText, setValidText] = useState<string | undefined>();
|
||||||
const registrationHandler = () => {
|
const registrationHandler = () => {
|
||||||
const uname = (document.getElementById("username") as HTMLInputElement)
|
const uname = (
|
||||||
.value;
|
document.getElementById("username") as HTMLInputElement
|
||||||
const passwd = encrypt(
|
).value;
|
||||||
(document.getElementById("passwd") as HTMLInputElement).value
|
const passwd = encrypt(
|
||||||
);
|
(document.getElementById("passwd") as HTMLInputElement)
|
||||||
fetch(`http://${domain}:${port}${endpoints.user}`, {
|
.value
|
||||||
method: "POST",
|
);
|
||||||
mode: "cors",
|
fetch(`http://${domain}:${port}${endpoints.user}`, {
|
||||||
headers: contentTypes.json,
|
method: "POST",
|
||||||
body: JSON.stringify({
|
mode: "cors",
|
||||||
userName: uname,
|
headers: contentTypes.json,
|
||||||
dateJoined: Date.now(),
|
body: JSON.stringify({
|
||||||
passwordHash: passwd,
|
userName: uname,
|
||||||
}),
|
dateJoined: Date.now(),
|
||||||
}).then((response) => {
|
passwordHash: passwd,
|
||||||
if (response.status === 400) {
|
}),
|
||||||
// 400 Bad request
|
}).then((response) => {
|
||||||
console.log("Username is taken or invalid!");
|
if (response.status === 400) {
|
||||||
setValid(false);
|
// 400 Bad request
|
||||||
setValidText("Username is taken or invalid!");
|
console.log("Username is taken or invalid!");
|
||||||
} else if (response.status === 200) {
|
setValid(false);
|
||||||
// 200 OK
|
setValidText("Username is taken or invalid!");
|
||||||
const futureDate = new Date();
|
} else if (response.status === 200) {
|
||||||
futureDate.setHours(futureDate.getHours() + 2);
|
// 200 OK
|
||||||
setLogin({
|
const futureDate = new Date();
|
||||||
username: uname,
|
futureDate.setHours(futureDate.getHours() + 2);
|
||||||
lastSeen: Date.now(),
|
setLogin({
|
||||||
validUntil: futureDate.getUTCMilliseconds(),
|
username: uname,
|
||||||
});
|
lastSeen: Date.now(),
|
||||||
document.title = `IRC User ${uname}`;
|
validUntil: futureDate.getUTCMilliseconds(),
|
||||||
}
|
});
|
||||||
});
|
document.title = `IRC User ${uname}`;
|
||||||
};
|
}
|
||||||
// login button press handler
|
});
|
||||||
const loginHandler = () => {
|
};
|
||||||
const uname = (document.getElementById("username") as HTMLInputElement)
|
// login button press handler
|
||||||
.value;
|
const loginHandler = () => {
|
||||||
const passwd = encrypt(
|
const uname = (
|
||||||
(document.getElementById("passwd") as HTMLInputElement).value
|
document.getElementById("username") as HTMLInputElement
|
||||||
);
|
).value;
|
||||||
// async invocation of Fetch API
|
const passwd = encrypt(
|
||||||
fetch(`http://${domain}:${port}${endpoints.user}?name=${uname}`, {
|
(document.getElementById("passwd") as HTMLInputElement)
|
||||||
method: "GET",
|
.value
|
||||||
mode: "cors",
|
);
|
||||||
})
|
// async invocation of Fetch API
|
||||||
.then((res) => {
|
fetch(
|
||||||
if (res.status === 404) {
|
`http://${domain}:${port}${endpoints.user}?name=${uname}`,
|
||||||
console.log("404 not found encountered");
|
{
|
||||||
throw new Error("Username does not exist");
|
method: "GET",
|
||||||
} else if (res.status === 200) {
|
mode: "cors",
|
||||||
console.log("200 OK");
|
}
|
||||||
}
|
)
|
||||||
return res.json();
|
.then((res) => {
|
||||||
})
|
if (res.status === 404) {
|
||||||
.then((userObject) => {
|
console.log(
|
||||||
if (!userObject) {
|
"404 not found encountered"
|
||||||
return;
|
);
|
||||||
}
|
throw new Error(
|
||||||
const user = userObject as User;
|
"Username does not exist"
|
||||||
const validLogin = passwd === user.passwordHash;
|
);
|
||||||
if (!validLogin) {
|
} else if (res.status === 200) {
|
||||||
// login invalid
|
console.log("200 OK");
|
||||||
throw new Error("Password incorrect!");
|
}
|
||||||
} else {
|
return res.json();
|
||||||
// login valid
|
})
|
||||||
const validUntilDate: Date = new Date();
|
.then((userObject) => {
|
||||||
validUntilDate.setHours(validUntilDate.getHours() + 2);
|
if (!userObject) {
|
||||||
setLogin({
|
return;
|
||||||
username: user.userName,
|
}
|
||||||
lastSeen: user.lastSeen,
|
const user = userObject as User;
|
||||||
validUntil: validUntilDate.getUTCMilliseconds(),
|
const validLogin = passwd === user.passwordHash;
|
||||||
});
|
if (!validLogin) {
|
||||||
document.title = `IRC User ${uname}`;
|
// login invalid
|
||||||
}
|
throw new Error("Password incorrect!");
|
||||||
})
|
} else {
|
||||||
.catch((reason: Error) => {
|
// login valid
|
||||||
setValid(false);
|
const validUntilDate: Date = new Date();
|
||||||
setValidText(reason.message);
|
validUntilDate.setHours(
|
||||||
});
|
validUntilDate.getHours() + 2
|
||||||
};
|
);
|
||||||
return (
|
setLogin({
|
||||||
<div className="login">
|
username: user.userName,
|
||||||
<fieldset>
|
lastSeen: user.lastSeen,
|
||||||
<legend>Login window</legend>
|
validUntil: validUntilDate.getUTCMilliseconds(),
|
||||||
<p className="uname-error-text">
|
});
|
||||||
{valid && valid !== undefined ? "" : validText}
|
document.title = `IRC User ${uname}`;
|
||||||
</p>
|
}
|
||||||
<label htmlFor="username">Username: </label>
|
})
|
||||||
<br />
|
.catch((reason: Error) => {
|
||||||
<input id="username" type="text"></input>
|
setValid(false);
|
||||||
<br />
|
setValidText(reason.message);
|
||||||
<label htmlFor="passwd">Password: </label>
|
});
|
||||||
<br />
|
};
|
||||||
<input id="passwd" type="password"></input>
|
return (
|
||||||
<br />
|
<div className="login">
|
||||||
<button
|
<fieldset>
|
||||||
type="submit"
|
<legend>Login window</legend>
|
||||||
onClick={() => {
|
<p className="uname-error-text">
|
||||||
loginHandler();
|
{valid && valid !== undefined
|
||||||
}}
|
? ""
|
||||||
>
|
: validText}
|
||||||
Login
|
</p>
|
||||||
</button>
|
<label htmlFor="username">Username: </label>
|
||||||
<button
|
<br />
|
||||||
type="submit"
|
<input id="username" type="text"></input>
|
||||||
onClick={() => {
|
<br />
|
||||||
registrationHandler();
|
<label htmlFor="passwd">Password: </label>
|
||||||
}}
|
<br />
|
||||||
>
|
<input id="passwd" type="password"></input>
|
||||||
Register
|
<br />
|
||||||
</button>
|
<button
|
||||||
<button
|
disabled={!valid}
|
||||||
type="submit"
|
type="submit"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setLogin(undefined);
|
loginHandler();
|
||||||
setValid(false);
|
}}
|
||||||
}}
|
>
|
||||||
>
|
Login
|
||||||
Logout
|
</button>
|
||||||
</button>
|
<button
|
||||||
</fieldset>
|
disabled={!valid}
|
||||||
</div>
|
type="submit"
|
||||||
);
|
onClick={() => {
|
||||||
|
registrationHandler();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Register
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
disabled={valid}
|
||||||
|
type="submit"
|
||||||
|
onClick={() => {
|
||||||
|
setLogin(undefined);
|
||||||
|
setValid(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Logout
|
||||||
|
</button>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,57 +4,64 @@ import { LangContext } from "../context";
|
||||||
import strings from "../Intl/strings.json";
|
import strings from "../Intl/strings.json";
|
||||||
import "./MessageDisplay.css";
|
import "./MessageDisplay.css";
|
||||||
export const MessageDisplay = ({
|
export const MessageDisplay = ({
|
||||||
type,
|
type,
|
||||||
fromUserId,
|
fromUserId,
|
||||||
toUserId,
|
toUserId,
|
||||||
content,
|
content,
|
||||||
timeMillis,
|
timeMillis,
|
||||||
}: Message): React.ReactElement<Message> => {
|
}: Message): React.ReactElement<Message> => {
|
||||||
const dateTime: Date = new Date(timeMillis);
|
const dateTime: Date = new Date(timeMillis);
|
||||||
const lang = useContext(LangContext);
|
const lang = useContext(LangContext);
|
||||||
const msgPage = strings[lang].chat;
|
const msgPage = strings[lang].chat;
|
||||||
/* FIXED funny error
|
/* FIXED funny error
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* The line below was
|
* The line below was
|
||||||
* return (<p>[{dateTime.toLocaleString(Intl.DateTimeFormat().resolvedOptions().timeZone)}]...</p>)
|
* return (<p>[{dateTime.toLocaleString(Intl.DateTimeFormat().resolvedOptions().timeZone)}]...</p>)
|
||||||
* The line incorrectly generated a value of "UTC" as the parameter to toLocaleString()
|
* The line incorrectly generated a value of "UTC" as the parameter to toLocaleString()
|
||||||
* While "UTC" is an accepted string value, in EEST, aka. "Europe/Athens" timezone string is not an acceptable parameter.
|
* While "UTC" is an accepted string value, in EEST, aka. "Europe/Athens" timezone string is not an acceptable parameter.
|
||||||
* This caused the return statement to fail, and the message fails to render, despite it being correctly committed to the db.
|
* This caused the return statement to fail, and the message fails to render, despite it being correctly committed to the db.
|
||||||
* Funny clown moment 🤡
|
* Funny clown moment 🤡
|
||||||
*/
|
*/
|
||||||
const timeString = `${
|
const timeString = `${
|
||||||
dateTime.getHours() > 12
|
dateTime.getHours() > 12
|
||||||
? dateTime.getHours() - 12
|
? dateTime.getHours() - 12
|
||||||
: dateTime.getHours()
|
: dateTime.getHours()
|
||||||
}:${dateTime.getMinutes()} ${dateTime.getHours() > 12 ? "PM" : "AM"}`;
|
}:${dateTime.getMinutes()} ${dateTime.getHours() > 12 ? "PM" : "AM"}`;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MessageType.HELLO as MessageType:
|
case MessageType.HELLO as MessageType:
|
||||||
return (
|
return (
|
||||||
<p className="msg">
|
<p className="msg">
|
||||||
[{timeString}]{" "}
|
[{timeString}]{" "}
|
||||||
{msgPage.joinMessage.replace("$userName", fromUserId)}
|
{msgPage.joinMessage.replace(
|
||||||
</p>
|
"$userName",
|
||||||
);
|
fromUserId
|
||||||
case MessageType.MESSAGE as MessageType:
|
)}
|
||||||
return (
|
</p>
|
||||||
<p className="msg">
|
);
|
||||||
[{timeString}]{" "}
|
case MessageType.MESSAGE as MessageType:
|
||||||
{msgPage.serverMessage
|
return (
|
||||||
.replace("$userName", fromUserId)
|
<p className="msg">
|
||||||
.replace("$content", content)}
|
[{timeString}]{" "}
|
||||||
</p>
|
{msgPage.serverMessage
|
||||||
);
|
.replace(
|
||||||
case MessageType.DATA as MessageType:
|
"$userName",
|
||||||
return <></>;
|
fromUserId
|
||||||
case MessageType.CHNAME as MessageType:
|
)
|
||||||
return <></>;
|
.replace("$content", content)}
|
||||||
default:
|
</p>
|
||||||
console.error("Illegal MessageType reported!");
|
);
|
||||||
return (
|
case MessageType.DATA as MessageType:
|
||||||
<p className="msg-err">
|
return <></>;
|
||||||
[{timeString}] **THIS MESSAGE CANNOT BE CORRECTLY SHOWN
|
case MessageType.CHNAME as MessageType:
|
||||||
BECAUSE THE CLIENT ENCOUNTERED AN ERROR**
|
return <></>;
|
||||||
</p>
|
default:
|
||||||
);
|
console.error("Illegal MessageType reported!");
|
||||||
}
|
return (
|
||||||
|
<p className="msg-err">
|
||||||
|
[{timeString}] **THIS MESSAGE CANNOT BE
|
||||||
|
CORRECTLY SHOWN BECAUSE THE CLIENT
|
||||||
|
ENCOUNTERED AN ERROR**
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,51 +1,46 @@
|
||||||
export const enum MessageType {
|
export const enum MessageType {
|
||||||
MESSAGE = "MESSAGE",
|
MESSAGE = "MESSAGE",
|
||||||
CHNAME = "CHNAME",
|
CHNAME = "CHNAME",
|
||||||
HELLO = "HELLO",
|
HELLO = "HELLO",
|
||||||
DATA = "DATA",
|
DATA = "DATA",
|
||||||
}
|
}
|
||||||
export enum SystemMessageCode {
|
export enum SystemMessageCode {
|
||||||
REQ,
|
REQ,
|
||||||
RES,
|
RES,
|
||||||
ERR,
|
ERR,
|
||||||
}
|
}
|
||||||
export type HistoryFetchResult = {
|
export type HistoryFetchResult = {
|
||||||
count: number;
|
count: number;
|
||||||
items: Array<ChatMessage>;
|
items: Array<ChatMessage>;
|
||||||
};
|
};
|
||||||
export type ErrorResult = {
|
export type ErrorResult = {
|
||||||
text: string;
|
text: string;
|
||||||
};
|
};
|
||||||
export type TimestampSendRequest = {
|
export type TimestampSendRequest = {
|
||||||
ts: number;
|
ts: number;
|
||||||
};
|
};
|
||||||
export type SystemMessage = {
|
export type SystemMessage = {
|
||||||
code: SystemMessageCode;
|
code: SystemMessageCode;
|
||||||
data: HistoryFetchResult | ErrorResult | TimestampSendRequest;
|
data: HistoryFetchResult | ErrorResult | TimestampSendRequest;
|
||||||
};
|
};
|
||||||
export type ChatMessage = {
|
export type ChatMessage = {
|
||||||
fromUserId: string;
|
fromUserId: string;
|
||||||
toUserId: string;
|
toUserId: string;
|
||||||
content: string;
|
content: string;
|
||||||
timeMillis: number;
|
timeMillis: number;
|
||||||
};
|
};
|
||||||
export type HelloMessage = {
|
export type HelloMessage = {
|
||||||
fromUserId: string;
|
fromUserId: string;
|
||||||
timeMillis: number;
|
timeMillis: number;
|
||||||
};
|
};
|
||||||
export type DataMessage = {};
|
export type DataMessage = {};
|
||||||
export type Message = {
|
export type Message = {
|
||||||
type: MessageType;
|
type: MessageType;
|
||||||
// data: SystemMessage | ChatMessage | HelloMessage
|
// data: SystemMessage | ChatMessage | HelloMessage
|
||||||
fromUserId: string;
|
fromUserId: string;
|
||||||
toUserId: string;
|
toUserId: string;
|
||||||
content: string;
|
content: string;
|
||||||
timeMillis: number;
|
timeMillis: number;
|
||||||
};
|
};
|
||||||
export const acceptedLangs = [
|
export const acceptedLangs = ["en_US", "zh_TW", "el_GR", "ar_SA"] as const;
|
||||||
"en_US",
|
|
||||||
"zh_TW",
|
|
||||||
"el_GR",
|
|
||||||
"ar_SA"
|
|
||||||
] as const;
|
|
||||||
export type LangType = (typeof acceptedLangs)[number];
|
export type LangType = (typeof acceptedLangs)[number];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
export type User = {
|
export type User = {
|
||||||
id: number;
|
id: number;
|
||||||
userName: string;
|
userName: string;
|
||||||
dateJoined: number;
|
dateJoined: number;
|
||||||
lastSeen: number;
|
lastSeen: number;
|
||||||
passwordHash: string;
|
passwordHash: string;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue