frontend: separate more elements into different components
This commit is contained in:
parent
6a1e89c288
commit
3668b45a30
4 changed files with 102 additions and 84 deletions
26
frontend/src/components/pages/main/ChannelTopBar.svelte
Normal file
26
frontend/src/components/pages/main/ChannelTopBar.svelte
Normal file
|
@ -0,0 +1,26 @@
|
|||
<script>
|
||||
import { HashIcon } from "svelte-feather-icons";
|
||||
|
||||
export let channel;
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.top-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
height: 3.4em;
|
||||
width: 100%;
|
||||
padding: var(--space-xs);
|
||||
border-bottom: 1px solid var(--background-color-2);
|
||||
}
|
||||
|
||||
.channel-heading {
|
||||
margin-left: var(--space-xxs);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="top-bar">
|
||||
<HashIcon />
|
||||
<span class="h5 channel-heading">{ channel.name }</span>
|
||||
</div>
|
|
@ -1,48 +1,9 @@
|
|||
<script>
|
||||
import { HashIcon } from "svelte-feather-icons";
|
||||
import request from "../../../request";
|
||||
import { apiRoute } from "../../../storage";
|
||||
import { messagesStoreProvider, userInfoStore } from "../../../stores";
|
||||
import ChannelTopBar from "./ChannelTopBar.svelte";
|
||||
import MessageInput from "./MessageInput.svelte";
|
||||
import Messages from "./Messages.svelte";
|
||||
|
||||
export let channel;
|
||||
let messageInput = "";
|
||||
|
||||
$: messages = messagesStoreProvider.getStore(channel.id);
|
||||
|
||||
const onKeydown = async (e) => {
|
||||
if (e.code !== "Enter")
|
||||
return;
|
||||
|
||||
if (messageInput.trim() === "" || !$userInfoStore)
|
||||
return;
|
||||
|
||||
// optimistically add message to store
|
||||
const optimisticMessageId = Math.floor(Math.random() * 999999);
|
||||
const optimisticMessage = {
|
||||
id: optimisticMessageId,
|
||||
content: messageInput,
|
||||
channel_id: channel.id,
|
||||
author_id: $userInfoStore.id,
|
||||
author_username: $userInfoStore.username,
|
||||
created_at: Date.now().toString(),
|
||||
_isPending: true
|
||||
};
|
||||
messages.addMessage(optimisticMessage);
|
||||
messageInput = "";
|
||||
|
||||
const res = await request("POST", apiRoute(`channels/${channel.id}/messages`), true, {
|
||||
content: optimisticMessage.content
|
||||
});
|
||||
|
||||
if (res.success && res.ok) {
|
||||
messages.setMessage(optimisticMessageId, res.json);
|
||||
} else {
|
||||
messages.deleteMessage({
|
||||
id: optimisticMessageId
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
@ -54,49 +15,10 @@
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.top-bar {
|
||||
height: 3.4em;
|
||||
width: 100%;
|
||||
padding: var(--space-xs);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid var(--background-color-2);
|
||||
}
|
||||
|
||||
.channel-heading {
|
||||
margin-left: var(--space-xxs);
|
||||
}
|
||||
|
||||
.message-input-container {
|
||||
width: 100%;
|
||||
padding: var(--space-norm);
|
||||
}
|
||||
|
||||
.message-input {
|
||||
height: 3em;
|
||||
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;
|
||||
}
|
||||
|
||||
.message-input::placeholder {
|
||||
color: var(--foreground-color-3);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="main-container">
|
||||
<div class="top-bar">
|
||||
<HashIcon />
|
||||
<span class="h5 channel-heading">{ channel.name }</span>
|
||||
</div>
|
||||
<ChannelTopBar channel={ channel } />
|
||||
<Messages channelId="{ channel.id }" />
|
||||
<div class="message-input-container">
|
||||
<input placeholder={`Send something interesting to #${channel.name}`} type="text" class="message-input" on:keydown={ onKeydown } bind:value={ messageInput }>
|
||||
</div>
|
||||
<MessageInput channel={ channel } />
|
||||
</div>
|
||||
|
|
71
frontend/src/components/pages/main/MessageInput.svelte
Normal file
71
frontend/src/components/pages/main/MessageInput.svelte
Normal file
|
@ -0,0 +1,71 @@
|
|||
<script>
|
||||
import request from "../../../request";
|
||||
import { apiRoute } from "../../../storage";
|
||||
import { messagesStoreProvider, userInfoStore } from "../../../stores";
|
||||
|
||||
export let channel;
|
||||
let messageInput = "";
|
||||
|
||||
$: messages = messagesStoreProvider.getStore(channel.id);
|
||||
|
||||
const onKeydown = async (e) => {
|
||||
if (e.code !== "Enter")
|
||||
return;
|
||||
|
||||
if (messageInput.trim() === "" || !$userInfoStore)
|
||||
return;
|
||||
|
||||
// optimistically add message to store
|
||||
const optimisticMessageId = Math.floor(Math.random() * 999999);
|
||||
const optimisticMessage = {
|
||||
id: optimisticMessageId,
|
||||
content: messageInput,
|
||||
channel_id: channel.id,
|
||||
author_id: $userInfoStore.id,
|
||||
author_username: $userInfoStore.username,
|
||||
created_at: Date.now().toString(),
|
||||
_isPending: true
|
||||
};
|
||||
messages.addMessage(optimisticMessage);
|
||||
messageInput = "";
|
||||
|
||||
const res = await request("POST", apiRoute(`channels/${channel.id}/messages`), true, {
|
||||
content: optimisticMessage.content
|
||||
});
|
||||
|
||||
if (res.success && res.ok) {
|
||||
messages.setMessage(optimisticMessageId, res.json);
|
||||
} else {
|
||||
messages.deleteMessage({
|
||||
id: optimisticMessageId
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.message-input-container {
|
||||
width: 100%;
|
||||
padding: var(--space-norm);
|
||||
}
|
||||
|
||||
.message-input {
|
||||
height: 3em;
|
||||
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;
|
||||
}
|
||||
|
||||
.message-input::placeholder {
|
||||
color: var(--foreground-color-3);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="message-input-container">
|
||||
<input placeholder={`Send something interesting to #${channel.name}`} type="text" class="message-input" on:keydown={ onKeydown } bind:value={ messageInput }>
|
||||
</div>
|
|
@ -1,7 +1,6 @@
|
|||
import App from './components/App.svelte';
|
||||
import gateway from './gateway';
|
||||
import request from './request';
|
||||
import { apiRoute, initStorageDefaults } from './storage';
|
||||
import { initStorageDefaults } from './storage';
|
||||
|
||||
initStorageDefaults();
|
||||
gateway.init();
|
||||
|
|
Loading…
Reference in a new issue