frontend: link up channel sidebar with gateway and fix channel button layout issue
This commit is contained in:
parent
01649150a4
commit
381f1ae454
7 changed files with 163 additions and 39 deletions
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import ChannelView from "./Main.svelte";
|
||||
import Main from "./pages/main/Main.svelte";
|
||||
|
||||
</script>
|
||||
|
||||
<ChannelView />
|
||||
<Main />
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<script>
|
||||
import { HashIcon } from "svelte-feather-icons";
|
||||
|
||||
export let channel;
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
@ -38,7 +40,7 @@
|
|||
}
|
||||
|
||||
.message-input {
|
||||
height: 3.4em;
|
||||
height: 3em;
|
||||
width: 100%;
|
||||
background-color : var(--background-color-2);
|
||||
border: none;
|
||||
|
@ -51,7 +53,7 @@
|
|||
<div class="main-container">
|
||||
<div class="top-bar">
|
||||
<HashIcon />
|
||||
<span class="h5 channel-heading">channel name</span>
|
||||
<span class="h5 channel-heading">{ channel.name }</span>
|
||||
</div>
|
||||
<div class="messages-container">
|
||||
|
|
@ -15,5 +15,5 @@ import Sidebar from "./Sidebar.svelte";
|
|||
|
||||
<div class="flex-container">
|
||||
<Sidebar />
|
||||
<ChannelView />
|
||||
<ChannelView channel={{ name: "channel name" }} />
|
||||
</div>
|
|
@ -1,11 +1,24 @@
|
|||
<script>
|
||||
import { HashIcon } from "svelte-feather-icons";
|
||||
import { channels } from "../../../stores";
|
||||
</script>
|
||||
|
||||
<div class="sidebar">
|
||||
{#each $channels as channel}
|
||||
<button class="sidebar-button">
|
||||
<div>
|
||||
<HashIcon />
|
||||
</div>
|
||||
<span>{ channel.name }</span>
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.sidebar {
|
||||
height: 100%;
|
||||
width: 255px;
|
||||
max-width: 255px;
|
||||
padding: var(--space-sm);
|
||||
background-color: var(--background-color-1);
|
||||
}
|
||||
|
@ -13,39 +26,36 @@
|
|||
.sidebar-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
justify-content: left;
|
||||
border: none;
|
||||
background-color: var(--background-color-1);
|
||||
padding: var(--space-sm);
|
||||
margin-bottom: var(--space-xxs);
|
||||
color: currentColor;
|
||||
font: inherit;
|
||||
width: 100%;
|
||||
border-radius: var(--radius-md);
|
||||
vertical-align: middle;
|
||||
width: 100%;
|
||||
height: 3.4em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sidebar-button span {
|
||||
margin-left: var(--space-xxs);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.sidebar-button div {
|
||||
display: inline;
|
||||
flex-shrink: 0;
|
||||
|
||||
/* TODO: HACK! */
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.sidebar-button:hover {
|
||||
background-color: var(--background-color-2);
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<div class="sidebar">
|
||||
<button class="sidebar-button">
|
||||
<HashIcon />
|
||||
<span>channel name</span>
|
||||
</button>
|
||||
<button class="sidebar-button">
|
||||
<HashIcon />
|
||||
<span>channel name</span>
|
||||
</button>
|
||||
<button class="sidebar-button">
|
||||
<HashIcon />
|
||||
<span>channel name</span>
|
||||
</button>
|
||||
</div>
|
|
@ -15,6 +15,13 @@ export const GatewayPayloadType = {
|
|||
MessageDelete: 122,
|
||||
}
|
||||
|
||||
export const GatewayEventType = {
|
||||
...GatewayPayloadType,
|
||||
|
||||
Open: -5,
|
||||
Close: -4
|
||||
}
|
||||
|
||||
export default {
|
||||
ws: null,
|
||||
authenticated: false,
|
||||
|
@ -23,7 +30,10 @@ export default {
|
|||
channels: null,
|
||||
reconnectDelay: 400,
|
||||
reconnectTimeout: null,
|
||||
handlers: new Map(),
|
||||
init() {
|
||||
window.__WAFFLE_GATEWAY = this;
|
||||
|
||||
const token = getAuthToken();
|
||||
if (!token) {
|
||||
return false;
|
||||
|
@ -33,6 +43,7 @@ export default {
|
|||
if (this.reconnectTimeout) {
|
||||
clearTimeout(this.reconnectTimeout);
|
||||
}
|
||||
this.dispatch(GatewayEventType.Open, null);
|
||||
console.log("[gateway] open");
|
||||
};
|
||||
this.ws.onmessage = (event) => {
|
||||
|
@ -65,6 +76,8 @@ export default {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.dispatch(payload.t, payload.d);
|
||||
};
|
||||
this.ws.onclose = () => {
|
||||
if (this.reconnectDelay < 60000) {
|
||||
|
@ -80,6 +93,8 @@ export default {
|
|||
this.init();
|
||||
}, this.reconnectDelay);
|
||||
|
||||
this.dispatch(GatewayEventType.Close, null);
|
||||
|
||||
console.log("[gateway] close");
|
||||
};
|
||||
|
||||
|
@ -87,5 +102,33 @@ export default {
|
|||
},
|
||||
send(data) {
|
||||
return this.ws.send(JSON.stringify(data));
|
||||
},
|
||||
dispatch(event, payload) {
|
||||
const eventHandlers = this.handlers.get(event);
|
||||
if (!eventHandlers)
|
||||
return;
|
||||
|
||||
eventHandlers.forEach((e) => {
|
||||
e(payload);
|
||||
});
|
||||
},
|
||||
subscribe(event, handler) {
|
||||
if (!this.handlers.get(event)) {
|
||||
this.handlers.set(event, new Set());
|
||||
}
|
||||
|
||||
this.handlers.get(event).add(handler);
|
||||
return handler; // can later be used for unsubscribe()
|
||||
},
|
||||
unsubscribe(event, handler) {
|
||||
const eventHandlers = this.handlers.get(event);
|
||||
if (!eventHandlers)
|
||||
return;
|
||||
|
||||
eventHandlers.delete(handler);
|
||||
|
||||
if (eventHandlers.size < 1) {
|
||||
this.handlers.delete(event);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
69
frontend/src/stores.js
Normal file
69
frontend/src/stores.js
Normal file
|
@ -0,0 +1,69 @@
|
|||
import gateway, { GatewayEventType } from "./gateway";
|
||||
|
||||
export const channels = {
|
||||
_handlers: [],
|
||||
_value: [],
|
||||
_didInit: false,
|
||||
subscribe(handler) {
|
||||
this._init();
|
||||
|
||||
const newLength = this._handlers.push(handler);
|
||||
const handlerIndex = newLength - 1;
|
||||
handler(this._value);
|
||||
return () => {
|
||||
this._handlers.splice(handlerIndex, 1);
|
||||
};
|
||||
},
|
||||
_dispatchUpdate() {
|
||||
this._handlers.forEach(e => {
|
||||
e(this._value);
|
||||
});
|
||||
},
|
||||
_init() {
|
||||
window.__WAFFLE_CHANNELS_STORE = this;
|
||||
|
||||
if (this._didInit)
|
||||
return;
|
||||
|
||||
this._didInit = true;
|
||||
|
||||
const channels = gateway.channels;
|
||||
if (channels) {
|
||||
this._value = channels;
|
||||
}
|
||||
|
||||
gateway.subscribe(GatewayEventType.Ready, ({ channels }) => {
|
||||
if (channels) {
|
||||
this._value = channels;
|
||||
}
|
||||
|
||||
this._dispatchUpdate();
|
||||
});
|
||||
gateway.subscribe(GatewayEventType.ChannelCreate, (channel) => {
|
||||
this._value.push(channel);
|
||||
|
||||
this._dispatchUpdate();
|
||||
});
|
||||
gateway.subscribe(GatewayEventType.ChannelDelete, ({ id }) => {
|
||||
const index = this._value.findIndex(e => e.id === id);
|
||||
if (!index)
|
||||
return;
|
||||
|
||||
this._value.splice(index);
|
||||
|
||||
this._dispatchUpdate();
|
||||
});
|
||||
gateway.subscribe(GatewayEventType.ChannelUpdate, (data) => {
|
||||
const index = this._value.findIndex(e => e.id === data.id);
|
||||
if (!index)
|
||||
return;
|
||||
|
||||
if (!this._value[index])
|
||||
return;
|
||||
|
||||
this._value[index] = data;
|
||||
|
||||
this._dispatchUpdate();
|
||||
});
|
||||
}
|
||||
};
|
30
test.rest
30
test.rest
|
@ -19,50 +19,50 @@ content-type: application/json
|
|||
###
|
||||
|
||||
GET http://localhost:3000/api/v1/users/self HTTP/1.1
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5NzAwMTE0LCJleHAiOjE2NDk4NzI5MTR9.EOn8MBHZLCxfU5fHc0ZY2x9p3y-_RdD7X915L1B6Ftc
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjUwMTUyNjQ2LCJleHAiOjE2NTAzMjU0NDZ9.eFjOjJV3rIZWN0WrdRblflh2q8dYDGQv4qxugjbYNFk
|
||||
|
||||
###
|
||||
|
||||
POST http://localhost:3000/api/v1/channels HTTP/1.1
|
||||
content-type: application/json
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5NzAwMTE0LCJleHAiOjE2NDk4NzI5MTR9.EOn8MBHZLCxfU5fHc0ZY2x9p3y-_RdD7X915L1B6Ftc
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjUwMTUyNjQ2LCJleHAiOjE2NTAzMjU0NDZ9.eFjOjJV3rIZWN0WrdRblflh2q8dYDGQv4qxugjbYNFk
|
||||
|
||||
{
|
||||
"name": "yet another channelllll"
|
||||
"name": "idk what to call these"
|
||||
}
|
||||
|
||||
###
|
||||
|
||||
PUT http://localhost:3000/api/v1/channels/8 HTTP/1.1
|
||||
PUT http://localhost:3000/api/v1/channels/5 HTTP/1.1
|
||||
content-type: application/json
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5NzAwMTE0LCJleHAiOjE2NDk4NzI5MTR9.EOn8MBHZLCxfU5fHc0ZY2x9p3y-_RdD7X915L1B6Ftc
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjUwMTUyNjQ2LCJleHAiOjE2NTAzMjU0NDZ9.eFjOjJV3rIZWN0WrdRblflh2q8dYDGQv4qxugjbYNFk
|
||||
#Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5MjU5NDUwLCJleHAiOjE2NDk0MzIyNTB9.JmF9NujFZnln7A-ynNpeyayGBqmR5poAyACYV6RnSQY
|
||||
|
||||
{
|
||||
"name": "this is my channelaaaaaa"
|
||||
"name": "idk what to put here"
|
||||
}
|
||||
|
||||
###
|
||||
|
||||
DELETE http://localhost:3000/api/v1/channels/1 HTTP/1.1
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5NzAwMTE0LCJleHAiOjE2NDk4NzI5MTR9.EOn8MBHZLCxfU5fHc0ZY2x9p3y-_RdD7X915L1B6Ftc
|
||||
DELETE http://localhost:3000/api/v1/channels/10 HTTP/1.1
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjUwMTUyNjQ2LCJleHAiOjE2NTAzMjU0NDZ9.eFjOjJV3rIZWN0WrdRblflh2q8dYDGQv4qxugjbYNFk
|
||||
#Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5MjU5NDUwLCJleHAiOjE2NDk0MzIyNTB9.JmF9NujFZnln7A-ynNpeyayGBqmR5poAyACYV6RnSQY
|
||||
|
||||
###
|
||||
|
||||
GET http://localhost:3000/api/v1/channels/1 HTTP/1.1
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5NzAwMTE0LCJleHAiOjE2NDk4NzI5MTR9.EOn8MBHZLCxfU5fHc0ZY2x9p3y-_RdD7X915L1B6Ftc
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjUwMTUyNjQ2LCJleHAiOjE2NTAzMjU0NDZ9.eFjOjJV3rIZWN0WrdRblflh2q8dYDGQv4qxugjbYNFk
|
||||
|
||||
###
|
||||
|
||||
GET http://localhost:3000/api/v1/channels HTTP/1.1
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5NzAwMTE0LCJleHAiOjE2NDk4NzI5MTR9.EOn8MBHZLCxfU5fHc0ZY2x9p3y-_RdD7X915L1B6Ftc
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjUwMTUyNjQ2LCJleHAiOjE2NTAzMjU0NDZ9.eFjOjJV3rIZWN0WrdRblflh2q8dYDGQv4qxugjbYNFk
|
||||
|
||||
###
|
||||
|
||||
POST http://localhost:3000/api/v1/channels/5/messages HTTP/1.1
|
||||
content-type: application/json
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5NzAwMTE0LCJleHAiOjE2NDk4NzI5MTR9.EOn8MBHZLCxfU5fHc0ZY2x9p3y-_RdD7X915L1B6Ftc
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjUwMTUyNjQ2LCJleHAiOjE2NTAzMjU0NDZ9.eFjOjJV3rIZWN0WrdRblflh2q8dYDGQv4qxugjbYNFk
|
||||
|
||||
{
|
||||
"content": "i hate cheese"
|
||||
|
@ -71,13 +71,13 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6M
|
|||
###
|
||||
|
||||
GET http://localhost:3000/api/v1/channels/5/messages HTTP/1.1
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5NzAwMTE0LCJleHAiOjE2NDk4NzI5MTR9.EOn8MBHZLCxfU5fHc0ZY2x9p3y-_RdD7X915L1B6Ftc
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjUwMTUyNjQ2LCJleHAiOjE2NTAzMjU0NDZ9.eFjOjJV3rIZWN0WrdRblflh2q8dYDGQv4qxugjbYNFk
|
||||
|
||||
###
|
||||
|
||||
PUT http://localhost:3000/api/v1/messages/3 HTTP/1.1
|
||||
content-type: application/json
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5NzAwMTE0LCJleHAiOjE2NDk4NzI5MTR9.EOn8MBHZLCxfU5fHc0ZY2x9p3y-_RdD7X915L1B6Ftc
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjUwMTUyNjQ2LCJleHAiOjE2NTAzMjU0NDZ9.eFjOjJV3rIZWN0WrdRblflh2q8dYDGQv4qxugjbYNFk
|
||||
|
||||
{
|
||||
"content": "hello again!"
|
||||
|
@ -86,9 +86,9 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6M
|
|||
###
|
||||
|
||||
GET http://localhost:3000/api/v1/messages/3
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5NzAwMTE0LCJleHAiOjE2NDk4NzI5MTR9.EOn8MBHZLCxfU5fHc0ZY2x9p3y-_RdD7X915L1B6Ftc
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjUwMTUyNjQ2LCJleHAiOjE2NTAzMjU0NDZ9.eFjOjJV3rIZWN0WrdRblflh2q8dYDGQv4qxugjbYNFk
|
||||
|
||||
###
|
||||
|
||||
DELETE http://localhost:3000/api/v1/messages/2 HTTP/1.1
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjQ5NzAwMTE0LCJleHAiOjE2NDk4NzI5MTR9.EOn8MBHZLCxfU5fHc0ZY2x9p3y-_RdD7X915L1B6Ftc
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MSwiaWF0IjoxNjUwMTUyNjQ2LCJleHAiOjE2NTAzMjU0NDZ9.eFjOjJV3rIZWN0WrdRblflh2q8dYDGQv4qxugjbYNFk
|
||||
|
|
Loading…
Reference in a new issue