2022-04-23 01:06:04 +03:00
< script >
2022-08-31 12:07:25 +03:00
import { onDestroy , onMount } from "svelte";
2022-04-28 18:48:44 +03:00
import request from "../request";
2022-08-31 11:46:51 +03:00
import { apiRoute , getItem } from "../storage";
2022-09-28 16:45:16 +03:00
import { messagesStoreProvider , overlayStore , selectedChannel , sendMessageAction , setMessageInputEvent , smallViewport , typingStore , userInfoStore } from "../stores";
2022-04-23 01:06:04 +03:00
export let channel;
let messageInput = "";
2022-08-03 18:55:12 +03:00
let messageTextarea;
2022-08-07 03:00:14 +03:00
let typingList = "?no one?";
let typingMessage = "is typing...";
2022-04-23 01:06:04 +03:00
$: messages = messagesStoreProvider.getStore(channel.id);
2022-08-07 03:00:14 +03:00
$: {
2022-08-07 21:57:41 +03:00
const typing = $typingStore.filter(a => a.channelId === channel.id);
const ownIndex = typing.findIndex(a => a.user.id === $userInfoStore.id);
2022-08-07 03:00:14 +03:00
if (ownIndex !== -1) {
typing.splice(ownIndex, 1);
}
if (typing.length === 0) {
typingList = "?no one?";
typingMessage = "is typing...";
} else if (typing.length === 1) {
2022-08-07 21:57:41 +03:00
typingList = `${ typing [ 0 ]. user . username } `;
2022-08-07 03:00:14 +03:00
typingMessage = "is typing...";
} else if (typing.length > 1) {
typingList = "";
for (let i = 0; i < typing.length ; i ++) {
const item = typing[i];
if (i == (typing.length - 1)) {
// we are at the end
2022-08-07 21:57:41 +03:00
typingList += `and ${ item . user . username } `;
2022-08-07 03:00:14 +03:00
} else {
2022-08-07 21:57:41 +03:00
typingList += `${ item . user . username } , `;
2022-08-07 03:00:14 +03:00
}
}
typingMessage = "are typing...";
}
}
2022-04-23 01:06:04 +03:00
2022-04-27 20:12:04 +03:00
const sendMessage = async () => {
2022-08-03 18:55:12 +03:00
messageTextarea.focus();
2022-09-28 16:45:16 +03:00
sendMessageAction.emit({
channelId: channel.id,
content: messageInput
2022-04-23 01:06:04 +03:00
});
2022-09-28 16:45:16 +03:00
messageInput = "";
2022-04-23 01:06:04 +03:00
};
2022-04-27 20:12:04 +03:00
const onKeydown = async (e) => {
2022-05-07 16:50:04 +03:00
if (e.code === "Enter") {
if (e.shiftKey) {
return;
} else {
e.preventDefault();
await sendMessage();
}
}
2022-04-27 20:12:04 +03:00
};
2022-08-07 03:00:14 +03:00
const onInput = () => {
typingStore.didInputKey();
};
2022-08-31 12:07:25 +03:00
2022-09-01 19:56:19 +03:00
const unsubscribers = [];
2022-08-31 12:07:25 +03:00
// Focus the text area when the component first loads, or when the user selects another channel
2022-09-02 15:08:47 +03:00
const focusTextarea = () => {
if (messageTextarea && getItem("ui:useragent:formFactor") !== "touch") {
messageTextarea.focus();
}
};
2022-08-31 12:07:25 +03:00
onMount(focusTextarea);
2022-09-28 16:45:16 +03:00
unsubscribers.push(selectedChannel.on(focusTextarea));
2022-09-01 19:56:19 +03:00
// Handle the setMessageInput event
2022-09-28 16:45:16 +03:00
unsubscribers.push(setMessageInputEvent.on((value) => {
2022-09-01 19:56:19 +03:00
messageInput = value;
2022-09-02 15:08:47 +03:00
if (messageTextarea) {
messageTextarea.focus();
}
2022-09-01 19:56:19 +03:00
}));
onDestroy(() => {
unsubscribers.forEach(e => e());
});
2022-04-23 01:06:04 +03:00
< / script >
< style >
.message-input-container {
2022-04-27 20:12:04 +03:00
display: flex;
2022-08-07 03:00:14 +03:00
flex-direction: column;
2022-04-27 20:12:04 +03:00
justify-content: center;
2022-04-23 01:06:04 +03:00
width: 100%;
padding: var(--space-norm);
2022-08-07 03:00:14 +03:00
padding-bottom: 0;
2022-04-23 01:06:04 +03:00
}
2022-08-20 03:32:31 +03:00
.message-input-container.small {
padding-top: var(--space-sm);
}
.message-input.small {
padding: var(--space-xsplus);
padding-left: var(--space-sm);
border-radius: 1.4em;
}
2022-04-23 01:06:04 +03:00
.message-input {
width: 100%;
background-color : var(--background-color-2);
border: none;
color: currentColor;
border-radius: var(--radius-md);
padding: var(--space-sm);
font-size: inherit;
line-height: inherit;
2022-08-03 04:49:03 +03:00
resize: none;
2022-04-23 01:06:04 +03:00
}
2022-09-01 21:07:53 +03:00
.message-input:focus-visible {
outline: 2px solid var(--purple-2);
}
2022-04-23 01:06:04 +03:00
.message-input::placeholder {
2022-08-28 17:57:01 +03:00
color: var(--foreground-color-4);
2022-04-23 01:06:04 +03:00
}
2022-04-27 20:12:04 +03:00
.send-button {
margin-left: var(--space-sm);
2022-08-20 03:32:31 +03:00
border-radius: 50%;
background-color: var(--purple-1);
2022-08-31 12:58:12 +03:00
padding: 12px;
aspect-ratio: 1;
2022-08-20 03:32:31 +03:00
flex-shrink: 0;
2022-09-20 01:35:54 +03:00
color: var(--colored-element-text-color);
2022-04-27 20:12:04 +03:00
}
2022-08-07 03:00:14 +03:00
.invisible {
visibility: hidden;
}
.inner-input-container {
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
.typing-info-container {
padding-left: var(--space-xxs);
}
.typing-list {
font-weight: bolder;
}
.typing-message {
color: var(--foreground-color-2);
}
2022-04-23 01:06:04 +03:00
< / style >
2022-08-20 03:32:31 +03:00
< div class = "message-input-container" class:small = { $smallViewport } >
2022-08-07 03:00:14 +03:00
< div class = "inner-input-container" >
< textarea
placeholder={ $smallViewport ? `Message #$ { channel . name } ` : ` Send something interesting to # $ { channel . name } ` }
type="text"
class="message-input"
rows="1"
on:keydown={ onKeydown }
on:input={ onInput }
bind:value={ messageInput }
bind:this={ messageTextarea }
2022-08-31 11:46:51 +03:00
class:small={ $smallViewport || getItem ( "ui:alwaysUseMobileChatBar" ) }
2022-08-07 03:00:14 +03:00
/>
2022-08-31 11:46:51 +03:00
{ #if $smallViewport || getItem ( "ui:alwaysUseMobileChatBar" )}
2022-09-18 01:41:59 +03:00
< button class = "icon-button send-button material-icons-outlined" on:click = " { sendMessage } " >
arrow_upward
2022-08-07 03:00:14 +03:00
< / button >
{ /if }
< / div >
< div class = "typing-info-container" >
< span class = "typing-list" class:invisible = { typingList === "?no one?" } > { typingList } </span >
< span class = "typing-message" class:invisible = { typingList === "?no one?" } > { typingMessage } </span >
< / div >
2022-04-23 01:06:04 +03:00
< / div >