Compare commits

...

3 commits

Author SHA1 Message Date
hippoz
131a270562
frontend: make "create channel" modal functional 2022-04-25 22:48:29 +03:00
hippoz
b1ff452732
frontend: start working on "create channel" modal 2022-04-25 18:47:27 +03:00
hippoz
6c3d6a09fb
frontend: make generic fullscreen message class 2022-04-24 21:31:22 +03:00
9 changed files with 187 additions and 18 deletions

View file

@ -19,10 +19,24 @@
:root {
--background-color-1: hsl(180, 11%, 7%);
--background-color-2: hsl(180, 11%, 12%);
--background-color-3: hsl(180, 11%, 17%);
--foreground-color-1: rgb(253, 254, 255);
--foreground-color-2: rgb(218, 219, 220);
--foreground-color-3: rgb(153, 154, 155);
--purple-1: hsl(280, 88%, 50%);
--blue-1: hsl(200, 88%, 50%);
--green-1: hsl(140, 88%, 50%);
--yellow-1: hsl(50, 88%, 65%);
--red-1: hsl(2, 88%, 65%);
--purple-2: hsl(280, 88%, 40%);
--blue-2: hsl(200, 88%, 40%);
--green-2: hsl(140, 88%, 40%);
--yellow-2: hsl(50, 88%, 60%);
--red-2: hsl(2, 88%, 60%);
--space-unit: 1em;
--space-xxs: calc(0.25 * var(--space-unit));
--space-xs: calc(0.5 * var(--space-unit));
@ -60,12 +74,12 @@ body {
overflow: hidden;
}
.pre--loading-screen {
.fullscreen-message {
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
width: 100%;
height: 100%;
overflow: hidden;
background-color: var(--background-color-1);
}
@ -88,6 +102,89 @@ body {
margin-left: var(--space-xxs);
}
.modal-backdrop {
position: absolute;
width: 100vw;
height: 100vh;
z-index: 0;
top: 50%;
left: 50%;
background-color: rgba(0, 0, 0, 0.4);
transform: translate(-50%, -50%);
}
.modal {
display: flex;
flex-direction: column;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: var(--background-color-2);
border-radius: var(--radius-lg);
padding: var(--space-md);
}
.modal-header {
margin-bottom: var(--space-md);
text-align: center;
}
.modal-footer {
margin-top: auto;
padding-top: var(--space-norm);
}
.modal-primary-action {
float: right;
}
.modal-secondary-action {
float: left;
}
.input-label {
text-transform: uppercase;
color: var(--foreground-color-2);
}
.input {
background-color : var(--background-color-3);
border: none;
color: currentColor;
border-radius: var(--radius-md);
padding: var(--space-sm);
font-size: inherit;
line-height: inherit;
}
.button {
background-color: var(--background-color-2);
text-align: center;
border: none;
padding: var(--space-sm);
border-radius: var(--radius-md);
color: currentColor;
font: inherit;
max-height: 3em;
}
.button:hover {
background-color: var(--background-color-3)
}
.button-accent {
background-color: var(--purple-2);
}
.button-accent:hover {
background-color: var(--purple-1);
}
.button-accent:disabled {
background-color: var(--purple-2);
}
.h1 {
font-size: 2.488rem;
}

View file

@ -13,6 +13,6 @@
</head>
<body>
<div class="pre--loading-screen" id="pre--loading-screen">heating up the crt...</div>
<div class="fullscreen-message" id="pre--loading-screen">heating up the crt...</div>
</body>
</html>

View file

@ -0,0 +1,43 @@
<script>
import { fade, fly } from "svelte/transition";
import { quintInOut } from "svelte/easing";
import { overlayStore } from "../../stores";
import request from "../../request";
import { apiRoute } from "../../storage";
let channelName = "";
let createButtonEnabled = true;
const close = () => overlayStore.close('createChannel');
const create = async () => {
createButtonEnabled = false;
await request("POST", apiRoute("channels"), true, {
name: channelName
});
close();
};
</script>
<style>
.full-width {
width: 100%;
}
</style>
<div class="modal-backdrop" transition:fade="{{ duration: 300, easing: quintInOut }}" on:click="{ close }">
<div class="modal" transition:fly="{{ duration: 300, easing: quintInOut, y: 10 }}" on:click|stopPropagation>
<div class="modal-header">
<span class="h3">Create Channel</span>
</div>
<label class="input-label">
Channel Name
<input class="input full-width" bind:value={ channelName } />
</label>
<div class="modal-footer">
<button class="button modal-secondary-action" on:click="{ close }">Cancel</button>
<button class="button button-accent modal-primary-action" on:click="{ create }" disabled="{ !createButtonEnabled }">Create</button>
</div>
</div>
</div>

View file

@ -1,7 +1,9 @@
<script>
import { CloudIcon } from "svelte-feather-icons";
import { gatewayStatus, selectedChannel } from "../../../stores";
import CreateChannel from "../../modals/CreateChannel.svelte";
import ChannelView from "./ChannelView.svelte";
import OverlayProvider from "./OverlayProvider.svelte";
import Sidebar from "./Sidebar.svelte";
</script>
@ -13,16 +15,6 @@
flex-direction: row;
overflow: hidden;
}
.fullscreen-message {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
overflow: hidden;
background-color: var(--background-color-1);
}
</style>
{#if !$gatewayStatus.ready}
@ -33,6 +25,7 @@
{/if}
<div class="flex-container">
<OverlayProvider />
<Sidebar />
{#if $selectedChannel.id === -1}
<div class="fullscreen-message">

View file

@ -0,0 +1,8 @@
<script>
import { overlayStore } from "../../../stores";
import CreateChannel from "../../modals/CreateChannel.svelte";
</script>
{#if $overlayStore.createChannel}
<CreateChannel />
{/if}

View file

@ -1,6 +1,6 @@
<script>
import { HashIcon } from "svelte-feather-icons";
import { channels, selectedChannel } from "../../../stores";
import { HashIcon, PlusIcon } from "svelte-feather-icons";
import { channels, overlayStore, selectedChannel } from "../../../stores";
import UserTopBar from "./UserTopBar.svelte";
</script>
@ -15,6 +15,12 @@
<span>{ channel.name }</span>
</button>
{/each}
<button on:click="{ () => overlayStore.open('createChannel') }" class="sidebar-button">
<div>
<PlusIcon />
</div>
<span>Create Channel</span>
</button>
</div>
</div>

View file

@ -23,7 +23,7 @@ export const GatewayEventType = {
Close: -4
}
const log = logging.logger("Gateway");
const log = logging.logger("Gateway", true);
export default {
ws: null,
@ -38,8 +38,10 @@ export default {
init() {
const token = getAuthToken();
if (!token) {
log("no auth token, skipping connection");
return false;
}
log(`connecting to gateway - gatewayBase: ${getItem("gatewayBase")}`);
this.ws = new WebSocket(getItem("gatewayBase"));
this.ws.onopen = () => {
if (this.reconnectTimeout) {

View file

@ -1,6 +1,7 @@
const defaults = {
apiBase: `${window.location.origin}/api/v1`,
gatewayBase: `${location.protocol === "https:" ? "wss" : "ws"}://${location.host}/gateway`
gatewayBase: `${location.protocol === "https:" ? "wss" : "ws"}://${location.host}/gateway`,
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidHlwZSI6MSwiaWF0IjoxNjUwODQzMjY1LCJleHAiOjE2NTEwMTYwNjV9.ssu-MlMkwKQOcP5nmJ98KbqudcGW5XBYPc_d6et4oxo"
};
const dummyProvider = {

View file

@ -219,8 +219,27 @@ class MessagesStoreProvider {
}
}
class OverlayStore extends Store {
constructor() {
super({
createChannel: false
});
}
open(name) {
this.value[name] = true;
this.updated();
}
close(name) {
this.value[name] = false;
this.updated();
}
}
export const channels = new ChannelsStore();
export const gatewayStatus = new GatewayStatusStore();
export const messagesStoreProvider = new MessagesStoreProvider();
export const userInfoStore = new UserInfoStore();
export const overlayStore = new OverlayStore();
export const selectedChannel = writable({ id: -1, name: "none", creator_id: -1 });