mirror of
https://github.com/Discreetly/frontend.git
synced 2026-01-10 05:18:06 -05:00
tons of ux improvements
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
<svelte:fragment slot="header">Discord Bot</svelte:fragment>
|
||||
<svelte:fragment slot="description">Add the discord bot to your server Today!</svelte:fragment>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://discord.com/api/oauth2/authorize?client_id=1142162852132700200&permissions=2147483648&scope=bot"
|
||||
class="btn variant-ghost-primary">Invite Discord Bot!</a
|
||||
>
|
||||
@@ -52,8 +53,9 @@
|
||||
<Card>
|
||||
<svelte:fragment slot="header">The Word</svelte:fragment>
|
||||
<svelte:fragment slot="description"
|
||||
>Do you know <a class="link" href="https://github.com/Mach-34/the-word/">the word</a>? Prove
|
||||
it.
|
||||
>Do you know <a class="link" target="_blank" href="https://github.com/Mach-34/the-word/"
|
||||
>the word</a
|
||||
>? Prove it.
|
||||
</svelte:fragment>
|
||||
<TheWord />
|
||||
</Card>
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
<script lang="ts">
|
||||
import Card from '$lib/components/Utils/Card.svelte';
|
||||
import Button from '$lib/components/Utils/Button.svelte';
|
||||
import { identityExists } from '$lib/stores';
|
||||
import { configStore } from '$lib/stores';
|
||||
</script>
|
||||
|
||||
<Card>
|
||||
<svelte:fragment slot="header">Discreetly is an anonymous chat app</svelte:fragment>
|
||||
{#if $configStore.beta}
|
||||
<i>Dance like no one is watching, and encrypt like everyone is.</i>
|
||||
{/if}
|
||||
|
||||
<p>
|
||||
<b>True Anonymity</b> <span role="img" aria-label="Shield">🛡️</span> Chat without revealing your
|
||||
identity, thanks to
|
||||
@@ -24,21 +27,9 @@
|
||||
<i class="text-primary-500">backup your credentials</i>—once lost, they're irretrievable.
|
||||
</p>
|
||||
<p>
|
||||
<b>Community-Powered Governance</b> <span role="img" aria-label="Ballot box">🗳️</span> While you're
|
||||
anonymous, irresponsible behavior like spamming won't go unnoticed. The community can vote to take
|
||||
action.
|
||||
<b>Gated Communities</b> <span role="img" aria-label="Lock">🔏</span> Most communities can only be
|
||||
joined once, use it wisely.
|
||||
</p>
|
||||
<svelte:fragment slot="footer">
|
||||
{#if !$identityExists}
|
||||
<Button link="/signup" cls="variant-ghost-primary btn-sm m-2 sm:m-3">Sign Up</Button>
|
||||
<Button link="https://discord.gg/brJQ36KVxk" cls="variant-ghost-tertiary btn-sm m-2 sm:m-3"
|
||||
>Join Our Discord</Button
|
||||
>
|
||||
{:else}
|
||||
It looks like you are already signed up!
|
||||
<Button link="/chat" cls="variant-ghost-success">Go Chat</Button>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</Card>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
export let heading = '';
|
||||
</script>
|
||||
|
||||
<div class="px-2 sm:px-3 my-3 md:my-5 overflow-scroll h-100">
|
||||
<div class="px-2 sm:px-3 my-2 md:my-3 overflow-scroll h-100">
|
||||
{#if heading.length > 0}
|
||||
<h2 class="h2 my-2 md:my-3 text-center">{heading}</h2>
|
||||
{/if}
|
||||
|
||||
@@ -3,10 +3,11 @@ import { IdentityStoreE } from './types';
|
||||
import { dev } from '$app/environment';
|
||||
|
||||
let defaultServers: serverStoreI;
|
||||
let beta = false;
|
||||
const devServers = false;
|
||||
const beta = false;
|
||||
const anxietyBar = false;
|
||||
|
||||
if (dev) {
|
||||
beta = true;
|
||||
if (dev && devServers) {
|
||||
defaultServers = {
|
||||
'https://server.discreetly.chat/': {
|
||||
name: 'Discreetly Server',
|
||||
@@ -34,7 +35,8 @@ const configDefaults: ConfigurationI = {
|
||||
identityStore: IdentityStoreE.NO_IDENTITY,
|
||||
numMessagesToSave: 500,
|
||||
hashedPwd: undefined,
|
||||
beta: beta
|
||||
beta: beta,
|
||||
anxietyBar: anxietyBar
|
||||
};
|
||||
|
||||
export { defaultServers, configDefaults };
|
||||
|
||||
@@ -72,7 +72,7 @@ export async function post(urlParts: string[] | string, data: object): Promise<o
|
||||
}
|
||||
|
||||
/**
|
||||
* @description - makes a get request to the api
|
||||
* @description - makes a post request to the api with admin credentials
|
||||
* @param {string[] | string} urlParts - the url parts to be joined to form the url
|
||||
* @param {object} data - the data to be sent to the api
|
||||
* @returns {object} - the response from the api
|
||||
@@ -100,3 +100,31 @@ export async function postAuth(
|
||||
throw new Error(`Failed to post to ${url}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description - makes a get request to the api with admin credentials
|
||||
* @param {string[] | string} urlParts - the url parts to be joined to form the url
|
||||
* @param {object} data - the data to be sent to the api
|
||||
* @returns {object} - the response from the api
|
||||
* @throws {Error} - if the request fails
|
||||
*/
|
||||
export async function getAuth(
|
||||
urlParts: string[] | string,
|
||||
username: string,
|
||||
password: string
|
||||
): Promise<object> {
|
||||
const url = cleanURL(urlParts);
|
||||
const res = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: 'Basic ' + btoa(username + ':' + password)
|
||||
}
|
||||
});
|
||||
if (res.ok) {
|
||||
return res.json();
|
||||
} else {
|
||||
throw new Error(`Failed to post to ${url}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { MessageI, ServerI } from 'discreetly-interfaces';
|
||||
import type { IdentityStoreI, Invites, JoinResponseI, RoomI } from '$lib/types';
|
||||
import { Prover } from 'idc-nullifier';
|
||||
import type { Identity } from '@semaphore-protocol/identity';
|
||||
import { get, post, postAuth } from './api';
|
||||
import { get, getAuth, post, postAuth } from './api';
|
||||
import { getIdentity } from '$lib/utils';
|
||||
import { alertQueue } from '$lib/stores';
|
||||
|
||||
@@ -150,3 +150,7 @@ export async function createInvite(
|
||||
}
|
||||
return postAuth([serverUrl, `admin/addcode`], data, username, password) as Promise<Invites>;
|
||||
}
|
||||
|
||||
export async function getAllRooms(serverUrl: string, username: string, password: string) {
|
||||
return getAuth([serverUrl, `admin/rooms`], username, password) as Promise<RoomI[]>;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import type {
|
||||
roomPassStoreI,
|
||||
roomKeyStoreI
|
||||
} from '$lib/types';
|
||||
import { getIdentity } from '$lib/utils';
|
||||
|
||||
/* ------------------ Server State ------------------*/
|
||||
/**
|
||||
@@ -177,7 +178,9 @@ export const identityExists = derived(
|
||||
return null;
|
||||
}
|
||||
} else if ($lockStateStore === 'locked') {
|
||||
if (typeof id === 'object') {
|
||||
const encryptedId = window.localStorage.getItem('identityencrypted');
|
||||
const encryptedIdExists = encryptedId !== null && encryptedId.length > 0;
|
||||
if (typeof id === 'object' && encryptedIdExists) {
|
||||
return 'encrypted';
|
||||
} else {
|
||||
return null;
|
||||
|
||||
@@ -6,9 +6,7 @@ export enum Experiences {
|
||||
export enum IdentityStoreE {
|
||||
'NO_IDENTITY',
|
||||
'localStorage',
|
||||
'localStorageEncrypted',
|
||||
'cryptKeeper',
|
||||
'PCDPass'
|
||||
'localStorageEncrypted'
|
||||
}
|
||||
|
||||
export enum ActionRepresentationE {
|
||||
|
||||
@@ -11,6 +11,7 @@ export interface ConfigurationI {
|
||||
beta?: boolean;
|
||||
numMessagesToSave: number;
|
||||
hashedPwd: string | null | undefined;
|
||||
anxietyBar: boolean;
|
||||
}
|
||||
|
||||
export interface RoomI extends RI {
|
||||
|
||||
@@ -1,14 +1,36 @@
|
||||
<script lang="ts">
|
||||
import Introduction from '$lib/components/Onboarding/Introduction.svelte';
|
||||
import Button from '$lib/components/Utils/Button.svelte';
|
||||
|
||||
import Mask from 'svelte-material-icons/GuyFawkesMask.svelte';
|
||||
import Help from 'svelte-material-icons/ChatQuestion.svelte';
|
||||
import { identityExists } from '$lib/stores';
|
||||
console.info(
|
||||
'I see you are checking out the logs, let us know what you think on our discord: https://discord.gg/brJQ36KVxk'
|
||||
);
|
||||
</script>
|
||||
|
||||
<div class="mx-5 lg:mx-auto mt-8 md:mt-16 max-w-[80ch]">
|
||||
<div class="mx-2 md:mx-auto mt-8 md:mt-16 max-w-[80ch]">
|
||||
<h1 class="h1 mb-6 md:mb-10 text-center">Welcome to Discreetly!</h1>
|
||||
<div class="mb-5">
|
||||
<Introduction />
|
||||
<div class="flex justify-evenly">
|
||||
{#if !$identityExists}
|
||||
<Button
|
||||
link="https://discord.gg/brJQ36KVxk"
|
||||
cls="variant-ghost-tertiary btn-lg m-2 sm:m-3 px-8 min-w-[12rem]"
|
||||
>
|
||||
<span><Help /></span>
|
||||
<span>Join Our Discord</span></Button
|
||||
>
|
||||
<Button link="/signup" cls="variant-ghost-primary btn-lg m-2 sm:m-3 px-8 min-w-[12rem]">
|
||||
<span><Mask /></span>
|
||||
<span>Sign Up</span>
|
||||
</Button>
|
||||
{:else}
|
||||
It looks like you are already signed up!
|
||||
<Button link="/chat" cls="variant-ghost-success">Go Chat</Button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { passwordSet, keyStore } from '$lib/stores';
|
||||
import { passwordSet, keyStore, identityExists, configStore } from '$lib/stores';
|
||||
import {
|
||||
getModalStore,
|
||||
TabAnchor,
|
||||
@@ -21,6 +21,8 @@
|
||||
import LockOpen from 'svelte-material-icons/LockOpenVariant.svelte';
|
||||
import NoPassword from 'svelte-material-icons/LockOff.svelte';
|
||||
import Door from 'svelte-material-icons/Door.svelte';
|
||||
|
||||
import Mask from 'svelte-material-icons/GuyFawkesMask.svelte';
|
||||
import { unlockPadlock } from '$lib/utils';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
@@ -61,7 +63,10 @@
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
drawerStore.close();
|
||||
setTimeout(() => {
|
||||
drawerStore.close();
|
||||
}, 10);
|
||||
console.log($identityExists);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -75,27 +80,29 @@
|
||||
<span class="flex-auto">About</span>
|
||||
</a>
|
||||
</li>
|
||||
{#if $identityExists}
|
||||
<li id="will-close">
|
||||
<a href="/gateways"
|
||||
><Plus />
|
||||
<span class="flex-auto">Join More</span>
|
||||
</a>
|
||||
</li>
|
||||
{#if $configStore.beta}
|
||||
<li id="will-close">
|
||||
<a href="/console">
|
||||
<Console />
|
||||
<span class="flex-auto">Console</span>
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
|
||||
<li id="will-close">
|
||||
<a href="/gateways"
|
||||
><Plus />
|
||||
<span class="flex-auto">Join More</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li id="will-close">
|
||||
<a href="/console">
|
||||
<Console />
|
||||
<span class="flex-auto">Console</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li id="will-close">
|
||||
<a href="/settings">
|
||||
<Settings />
|
||||
<span class="flex-auto">Settings</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="will-close">
|
||||
<a href="/settings">
|
||||
<Settings />
|
||||
<span class="flex-auto">Settings</span>
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="arrow bg-surface-100-800-token" />
|
||||
@@ -106,42 +113,42 @@
|
||||
hover="hover:variant-soft-primary"
|
||||
flex="flex-1 lg:flex-none"
|
||||
class="bg-surface-100-800-token w-full"
|
||||
>
|
||||
<TabAnchor href="/chat" selected={$page.url.pathname === '/chat'} title="Chat">
|
||||
<svelte:fragment slot="lead"><Chat class="rail-icon" /></svelte:fragment>
|
||||
<span>Chat</span>
|
||||
</TabAnchor>
|
||||
{#if $page.url.pathname === '/chat'}
|
||||
<TabAnchor on:click={drawerOpen} title="Select Room">
|
||||
<svelte:fragment slot="lead"><Door class="rail-icon" /></svelte:fragment>
|
||||
<span>Select Room</span>
|
||||
>{#if $identityExists}
|
||||
<TabAnchor href="/chat" selected={$page.url.pathname === '/chat'} title="Chat">
|
||||
<svelte:fragment slot="lead"><Chat class="rail-icon" /></svelte:fragment>
|
||||
<span>Chat</span>
|
||||
</TabAnchor>
|
||||
{/if}
|
||||
{#if loaded}
|
||||
{#if $passwordSet}
|
||||
{#if $keyStore instanceof CryptoKey}
|
||||
<TabAnchor on:click={lock} title="Unlocked, click to lock">
|
||||
<svelte:fragment slot="lead">
|
||||
<LockOpen class="rail-icon text-warning-300-600-token" />
|
||||
</svelte:fragment>
|
||||
<span>Lock</span>
|
||||
</TabAnchor>
|
||||
{:else}
|
||||
<TabAnchor on:click={unlock} title="Locked">
|
||||
<svelte:fragment slot="lead">
|
||||
<Lock class="rail-icon text-success-500" />
|
||||
</svelte:fragment>
|
||||
<span>Unlock</span>
|
||||
</TabAnchor>
|
||||
{/if}
|
||||
{:else}
|
||||
<TabAnchor href="/settings/security" title="Password not set">
|
||||
<svelte:fragment slot="lead">
|
||||
<NoPassword class="rail-icon text-error-500" />
|
||||
</svelte:fragment>
|
||||
<span>Secure</span>
|
||||
|
||||
{#if $page.url.pathname === '/chat'}
|
||||
<TabAnchor on:click={drawerOpen} title="Select Room">
|
||||
<svelte:fragment slot="lead"><Door class="rail-icon" /></svelte:fragment>
|
||||
<span>Select Room</span>
|
||||
</TabAnchor>
|
||||
{/if}
|
||||
{#if loaded}
|
||||
{#if $passwordSet}
|
||||
{#if $keyStore instanceof CryptoKey}
|
||||
<TabAnchor on:click={lock} title="Unlocked, click to lock">
|
||||
<svelte:fragment slot="lead">
|
||||
<LockOpen class="rail-icon text-warning-300-600-token" />
|
||||
</svelte:fragment>
|
||||
<span>Lock</span>
|
||||
</TabAnchor>
|
||||
{:else}
|
||||
<TabAnchor on:click={unlock} title="Locked">
|
||||
<svelte:fragment slot="lead">
|
||||
<Lock class="rail-icon text-success-500" />
|
||||
</svelte:fragment>
|
||||
<span>Unlock</span>
|
||||
</TabAnchor>
|
||||
{/if}
|
||||
{/if}
|
||||
{/if}
|
||||
{:else}
|
||||
<TabAnchor href="/signup" selected={$page.url.pathname === '/signup'} title="SignUp">
|
||||
<svelte:fragment slot="lead"><Mask class="rail-icon" /></svelte:fragment>
|
||||
<span>SignUp</span>
|
||||
</TabAnchor>
|
||||
{/if}
|
||||
<a
|
||||
class="tab-anchor text-center cursor-pointer transition-colors duration-100 flex-1 lg:flex-none px-4 py-2 rounded-tl-container-token rounded-tr-container-token hover:variant-soft-primary"
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
import LockOpen from 'svelte-material-icons/LockOpenVariant.svelte';
|
||||
import NoPassword from 'svelte-material-icons/LockOff.svelte';
|
||||
import Plus from 'svelte-material-icons/Plus.svelte';
|
||||
import { keyStore, passwordSet } from '$lib/stores';
|
||||
import Mask from 'svelte-material-icons/GuyFawkesMask.svelte';
|
||||
import { configStore, identityExists, keyStore, passwordSet } from '$lib/stores';
|
||||
import { unlockPadlock } from '$lib/utils';
|
||||
|
||||
export let loaded: boolean;
|
||||
@@ -47,23 +48,33 @@
|
||||
<span>About</span>
|
||||
</AppRailAnchor>
|
||||
|
||||
<AppRailAnchor href="/chat" selected={$page.url.pathname === '/chat'} title="Chat">
|
||||
<svelte:fragment slot="lead"><Chat class="rail-icon" /></svelte:fragment>
|
||||
<span>Chat</span>
|
||||
</AppRailAnchor>
|
||||
{#if $identityExists}
|
||||
<AppRailAnchor href="/chat" selected={$page.url.pathname === '/chat'} title="Chat">
|
||||
<svelte:fragment slot="lead"><Chat class="rail-icon" /></svelte:fragment>
|
||||
<span>Chat</span>
|
||||
</AppRailAnchor>
|
||||
|
||||
<AppRailAnchor href="/gateways" selected={$page.url.pathname === '/gateways'} title="About">
|
||||
<svelte:fragment slot="lead"><Plus class="rail-icon" /></svelte:fragment>
|
||||
<span>Join More</span>
|
||||
</AppRailAnchor>
|
||||
<AppRailAnchor href="/gateways" selected={$page.url.pathname === '/gateways'} title="About">
|
||||
<svelte:fragment slot="lead"><Plus class="rail-icon" /></svelte:fragment>
|
||||
<span>Join More</span>
|
||||
</AppRailAnchor>
|
||||
|
||||
<AppRailAnchor href="/console" selected={$page.url.pathname === '/console'} title="About">
|
||||
<svelte:fragment slot="lead"><Console class="rail-icon" /></svelte:fragment>
|
||||
<span>Console</span>
|
||||
</AppRailAnchor>
|
||||
{#if $configStore.beta}
|
||||
<AppRailAnchor href="/console" selected={$page.url.pathname === '/console'} title="About">
|
||||
<svelte:fragment slot="lead"><Console class="rail-icon" /></svelte:fragment>
|
||||
<span>Console</span>
|
||||
</AppRailAnchor>
|
||||
{/if}
|
||||
{:else}
|
||||
<AppRailAnchor href="/signup" selected={$page.url.pathname === '/signup'} title="Sign Up">
|
||||
<svelte:fragment slot="lead"><Mask class="rail-icon" /></svelte:fragment>
|
||||
<span>Sign Up</span>
|
||||
</AppRailAnchor>
|
||||
{/if}
|
||||
|
||||
<svelte:fragment slot="trail">
|
||||
{#if loaded}
|
||||
<!---PadLock-->
|
||||
{#if $passwordSet}
|
||||
{#if $keyStore instanceof CryptoKey}
|
||||
<AppRailAnchor on:click={lock} title="Unlocked, click to lock">
|
||||
@@ -80,18 +91,18 @@
|
||||
<span>Unlock</span>
|
||||
</AppRailAnchor>
|
||||
{/if}
|
||||
{:else}
|
||||
<AppRailAnchor href="/settings/security" title="Password not set">
|
||||
<svelte:fragment slot="lead">
|
||||
<NoPassword class="rail-icon text-error-500" />
|
||||
</svelte:fragment>
|
||||
<span>Secure</span>
|
||||
|
||||
<!---Settings-->
|
||||
|
||||
<AppRailAnchor
|
||||
href="/settings"
|
||||
selected={$page.url.pathname === '/settings'}
|
||||
title="Settings"
|
||||
>
|
||||
<svelte:fragment slot="lead"><Settings class="rail-icon" /></svelte:fragment>
|
||||
<span>Settings</span>
|
||||
</AppRailAnchor>
|
||||
{/if}
|
||||
{/if}
|
||||
<AppRailAnchor href="/settings" selected={$page.url.pathname === '/settings'} title="Settings">
|
||||
<svelte:fragment slot="lead"><Settings class="rail-icon" /></svelte:fragment>
|
||||
<span>Settings</span>
|
||||
</AppRailAnchor>
|
||||
</svelte:fragment>
|
||||
</AppRail>
|
||||
|
||||
7
src/routes/admin/+layout.svelte
Normal file
7
src/routes/admin/+layout.svelte
Normal file
@@ -0,0 +1,7 @@
|
||||
<script lang="ts">
|
||||
import Container from '$lib/components/Utils/Container.svelte';
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
<slot />
|
||||
</Container>
|
||||
19
src/routes/admin/+page.svelte
Normal file
19
src/routes/admin/+page.svelte
Normal file
@@ -0,0 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { configStore } from '$lib/stores';
|
||||
import Card from '$lib/components/Utils/Card.svelte';
|
||||
</script>
|
||||
|
||||
<Card>
|
||||
<label class="label">
|
||||
<span>Username</span>
|
||||
<input type="text" class="input" bind:value={$configStore.apiUsername} />
|
||||
</label>
|
||||
<label class="label">
|
||||
<span>Password</span>
|
||||
<input type="password" class="input" bind:value={$configStore.apiPassword} />
|
||||
</label>
|
||||
</Card>
|
||||
<div class="flex gap-1 justify-around">
|
||||
<a class="btn variant-filled-primary" href="/admin/newroom">Create Room</a>
|
||||
<a class="btn variant-filled-primary" href="/admin/invite">Create Invites</a>
|
||||
</div>
|
||||
@@ -155,12 +155,4 @@
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#qr > div > canvas {
|
||||
margin: 0 auto;
|
||||
height: 250px;
|
||||
width: 250px;
|
||||
}
|
||||
#qr > div > p {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
95
src/routes/admin/join/+page.svelte
Normal file
95
src/routes/admin/join/+page.svelte
Normal file
@@ -0,0 +1,95 @@
|
||||
<script lang="ts">
|
||||
import { getAllRooms, createInvite } from '$lib/services/server';
|
||||
import { inviteCode } from '$lib/gateways/inviteCode';
|
||||
import { selectedServer, configStore, currentRoomsStore } from '$lib/stores';
|
||||
import { Accordion, AccordionItem } from '@skeletonlabs/skeleton';
|
||||
import { formatRelative } from 'date-fns';
|
||||
import type { RoomI } from '$lib/types';
|
||||
|
||||
let rooms: RoomI[] = [];
|
||||
let selectedRoomIds: string[] = [];
|
||||
$: username = $configStore.apiUsername;
|
||||
$: password = $configStore.apiPassword;
|
||||
|
||||
async function getRooms() {
|
||||
if (username && password) {
|
||||
console.log('getting rooms');
|
||||
rooms = await getAllRooms($selectedServer, username, password);
|
||||
}
|
||||
}
|
||||
|
||||
async function joinRooms() {
|
||||
const resp = await createInvite(
|
||||
$selectedServer,
|
||||
$configStore.apiUsername as string,
|
||||
$configStore.apiPassword as string,
|
||||
1,
|
||||
selectedRoomIds
|
||||
);
|
||||
const codes = resp.codes;
|
||||
codes.forEach((code) => {
|
||||
inviteCode(code.claimcode);
|
||||
});
|
||||
}
|
||||
|
||||
function updateRoomList(e: Event) {
|
||||
const target = e.target as HTMLInputElement;
|
||||
const roomId = target.value;
|
||||
if (target.checked) {
|
||||
selectedRoomIds.push(roomId);
|
||||
} else {
|
||||
selectedRoomIds = selectedRoomIds.filter((id) => id !== roomId);
|
||||
}
|
||||
console.log(selectedRoomIds);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col place-content-center max-w-sm m-auto pt-5">
|
||||
<div class="border-b border-spacing-3 pb-5 mb-5">
|
||||
<button on:click={getRooms} class="btn variant-outline-primary">Get Rooms</button>
|
||||
<button
|
||||
on:click={joinRooms}
|
||||
class="btn variant-outline-primary"
|
||||
disabled={selectedRoomIds.length == 1}>Join Rooms</button
|
||||
>
|
||||
|
||||
<h4 class="h4 my-5">Rooms:</h4>
|
||||
{#each rooms as room}
|
||||
<label class="label">
|
||||
<input
|
||||
type="checkbox"
|
||||
value={room.roomId}
|
||||
on:change={updateRoomList}
|
||||
checked={selectedRoomIds.includes(String(room.roomId))}
|
||||
/>
|
||||
<span title={String(room.roomId)}>{room.name}</span>
|
||||
</label>
|
||||
{/each}
|
||||
</div>
|
||||
<Accordion>
|
||||
<AccordionItem>
|
||||
<svelte:fragment slot="summary">API</svelte:fragment>
|
||||
<svelte:fragment slot="content"
|
||||
><label class="label">
|
||||
<span>Api Username</span>
|
||||
<input type="text" class="input" bind:value={$configStore.apiUsername} />
|
||||
</label>
|
||||
<label class="label">
|
||||
<span>Api Password</span>
|
||||
<input type="password" class="input" bind:value={$configStore.apiPassword} />
|
||||
</label></svelte:fragment
|
||||
>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#qr > div > canvas {
|
||||
margin: 0 auto;
|
||||
height: 250px;
|
||||
width: 250px;
|
||||
}
|
||||
#qr > div > p {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -5,6 +5,8 @@
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
onMount(() => {
|
||||
console.log('onMount');
|
||||
console.log($identityExists);
|
||||
if (!$identityExists) {
|
||||
goto('/signup');
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
keyStore,
|
||||
rateLimitStore,
|
||||
roomKeyStore,
|
||||
alertQueue
|
||||
alertQueue,
|
||||
identityExists
|
||||
} from '$lib/stores';
|
||||
import { genProof } from '$lib/crypto/rlnProver';
|
||||
import type { Socket } from 'socket.io-client';
|
||||
@@ -32,9 +33,12 @@
|
||||
if (sendingMessage) {
|
||||
return 'Sending...';
|
||||
}
|
||||
if ($identityExists == 'encrypted') {
|
||||
return 'Please unlock your identity to send a message';
|
||||
}
|
||||
return 'Write a message...';
|
||||
};
|
||||
$: canSendMessage = connected && !sendingMessage;
|
||||
$: canSendMessage = connected && !sendingMessage && $identityExists == 'safe';
|
||||
|
||||
function checkStatus(): boolean {
|
||||
if (!connected) {
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-row">
|
||||
{#if connected}
|
||||
{#if connected && onlineMembers !== '?'}
|
||||
<span
|
||||
class:connected
|
||||
class="flex flex-row align-middle text-sm font-mono text-secondary-300-600-token"
|
||||
@@ -65,14 +65,14 @@
|
||||
>
|
||||
{#if $configStore.beta === true}<ExperienceMenu />{/if}
|
||||
<AP health={messagesLeft()} maxHealth={userMessageLimit} />
|
||||
<div class="block sm:hidden">
|
||||
{#if $configStore.anxietyBar === false}
|
||||
<Clock time={timeToNextEpoch} maxTime={epochLengthSeconds} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden sm:block">
|
||||
{#if $configStore.anxietyBar === true}
|
||||
<ProgressBar value={timeToNextEpoch} max={epochLengthSeconds} />
|
||||
</div>
|
||||
{/if}
|
||||
</header>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import Eye from 'svelte-material-icons/Eye.svelte';
|
||||
import Container from '$lib/components/Utils/Container.svelte';
|
||||
import { identityExists } from '$lib/stores';
|
||||
import AnxietyBar from './ui/AnxietyBar.svelte';
|
||||
</script>
|
||||
|
||||
<Container heading="Manage Settings">
|
||||
@@ -28,7 +29,7 @@
|
||||
{:else}
|
||||
<Container>
|
||||
<svelte:fragment slot="header">
|
||||
<h3 class="h3 flex flex-row gap-2 items-center"><IdentityIcon /> Identity</h3>
|
||||
<h3 class="h3 flex flex-row gap-2 items-center mb-3"><IdentityIcon /> Identity</h3>
|
||||
</svelte:fragment>
|
||||
<BackupIdentity />
|
||||
<DeleteIdentity />
|
||||
@@ -36,9 +37,10 @@
|
||||
</Container>
|
||||
<Container>
|
||||
<svelte:fragment slot="header">
|
||||
<h3 class="h3 flex flex-row gap-2 items-center"><Eye /> UI</h3></svelte:fragment
|
||||
<h3 class="h3 flex flex-row gap-2 items-center mb-3"><Eye /> UI</h3></svelte:fragment
|
||||
>
|
||||
<ActionRepresentation />
|
||||
<AnxietyBar />
|
||||
</Container>
|
||||
{/if}
|
||||
</Container>
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
$configStore.beta = !$configStore.beta;
|
||||
}
|
||||
|
||||
function toggleAnxiety() {
|
||||
$configStore.anxietyBar = !$configStore.anxietyBar;
|
||||
}
|
||||
|
||||
function triggerAlert() {
|
||||
alertQueue.enqueue('TEST', t as any);
|
||||
}
|
||||
@@ -39,6 +43,7 @@
|
||||
<div>Identity Backedup: {JSON.stringify($configStore.signUpStatus.identityBackedUp)}</div>
|
||||
<div>IdentityStore Type: {IdentityStoreE[$configStore.identityStore]}</div>
|
||||
<div on:click={toggleBeta}>Beta: {JSON.stringify($configStore.beta)}</div>
|
||||
<div on:click={toggleAnxiety}>Beta: {JSON.stringify($configStore.anxietyBar)}</div>
|
||||
<div>Hashed Password: {JSON.stringify($configStore.hashedPwd)}</div>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<script>
|
||||
import Container from '$lib/components/Utils/Container.svelte';
|
||||
import ActionRepresentation from './ActionRepresentation.svelte';
|
||||
import AnxietyBar from './AnxietyBar.svelte';
|
||||
</script>
|
||||
|
||||
<Container heading="UI Settings">
|
||||
<ActionRepresentation />
|
||||
<AnxietyBar />
|
||||
</Container>
|
||||
|
||||
77
src/routes/settings/ui/AnxietyBar.svelte
Normal file
77
src/routes/settings/ui/AnxietyBar.svelte
Normal file
@@ -0,0 +1,77 @@
|
||||
<script lang="ts">
|
||||
import { configStore } from '$lib/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import AP from '$lib/components/ActionPoints/AP.svelte';
|
||||
import Clock from '$lib/components/Utils/Clock.svelte';
|
||||
import Person from 'svelte-material-icons/Account.svelte';
|
||||
import FullCircle from 'svelte-material-icons/Circle.svelte';
|
||||
import { ProgressBar } from '@skeletonlabs/skeleton';
|
||||
|
||||
let timeToNextEpoch = 0;
|
||||
let epochLengthSeconds = 20;
|
||||
|
||||
onMount(() => {
|
||||
setInterval(() => {
|
||||
timeToNextEpoch += 0.1;
|
||||
if (timeToNextEpoch >= epochLengthSeconds) {
|
||||
timeToNextEpoch = 0;
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="card variant-soft-secondary">
|
||||
<header class="card-header">
|
||||
<h3 class="h4">Anxiety Bar</h3>
|
||||
</header>
|
||||
<section class="p-2 mb-2 sm:p-4 sm:mb-4">
|
||||
<div class="flex flex-col border-b mb-3 pb-2">
|
||||
<p class="mb-5">
|
||||
This shows a progress bar in the chat room that represents how much time has ellapsed in an
|
||||
epoch. This was hidden because it gives some users anxiety, but we wanted to leave it as an
|
||||
option for those that think its fun.
|
||||
</p>
|
||||
<select id="anxiety-bar" class="select py-4" size="2" bind:value={$configStore.anxietyBar}>
|
||||
<option value={true}>Anxiety On</option>
|
||||
<option value={false}>Anxiety Off (Default)</option>
|
||||
</select>
|
||||
</div>
|
||||
<h6 class="h6 text-center mb-2">Demo</h6>
|
||||
<header
|
||||
class="flex flex-col text-xs my-5 md:text-base border border-surface-800/30 px-2 py-1 md:px-5 md:py-3 bg-surface-800"
|
||||
>
|
||||
<div class="flex flex-row justify-between place-items-center mb-2">
|
||||
<div class="flex flex-row">
|
||||
<span class="place-self-center mr-2">
|
||||
<FullCircle class="w-4 h-4 text-green-500" />
|
||||
</span>
|
||||
<h2 class="h5 text-secondary-800-100-token" title="Example Room">Example Room</h2>
|
||||
<div class="hidden sm:block ms-2 text-xs font-mono self-center">
|
||||
[{timeToNextEpoch.toFixed(1)}/{epochLengthSeconds}s]
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-row">
|
||||
<span
|
||||
class="flex flex-row align-middle text-sm font-mono text-secondary-300-600-token"
|
||||
title="Online Users"
|
||||
>
|
||||
<Person />
|
||||
37
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-row place-content-center"
|
||||
title={`These are action points, you get 4 messages every 20 seconds`}
|
||||
>
|
||||
<AP health={4} maxHealth={6} />
|
||||
{#if $configStore.anxietyBar === false}
|
||||
<Clock time={timeToNextEpoch} maxTime={epochLengthSeconds} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{#if $configStore.anxietyBar === true}
|
||||
<ProgressBar value={timeToNextEpoch} max={epochLengthSeconds} />
|
||||
{/if}
|
||||
</header>
|
||||
</section>
|
||||
</div>
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
</script>
|
||||
|
||||
<div class="h-100 mt-2 mx-2 md:mx-4">
|
||||
<div class="h-100 mt-2 mx-2 md:mx-4 mb-8">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
@@ -11,8 +11,12 @@
|
||||
import RestoreIdentity from '$lib/components/Identity/RestoreIdentity.svelte';
|
||||
import Backup from '$lib/components/Identity/BackupIdentity.svelte';
|
||||
import Gateways from '$lib/components/Onboarding/Gateways.svelte';
|
||||
import Mask from 'svelte-material-icons/GuyFawkesMask.svelte';
|
||||
import Magic from 'svelte-material-icons/MagicStaff.svelte';
|
||||
import BackupRestore from 'svelte-material-icons/BackupRestore.svelte';
|
||||
|
||||
const modalStore = getModalStore();
|
||||
let restoreIdentity = false;
|
||||
|
||||
function unlock() {
|
||||
const modal: ModalSettings = {
|
||||
@@ -50,12 +54,12 @@
|
||||
</script>
|
||||
|
||||
<Stepper
|
||||
class="max-w-sm sm:max-w-md md:max-w-3xl mx-auto mt-16"
|
||||
class="px-3 sm:max-w-md md:max-w-3xl mx-auto mt-16"
|
||||
on:complete={() => {
|
||||
goto('/chat');
|
||||
}}
|
||||
buttonCompleteLabel="Lets Go Chat Anon"
|
||||
buttonNext="variant-filled-surface-50-900-token"
|
||||
buttonNext="variant-filled-success"
|
||||
buttonComplete="variant-filled-success"
|
||||
>
|
||||
<Step class="px-10">
|
||||
@@ -69,7 +73,7 @@
|
||||
{#if !$passwordSet}
|
||||
<h2 class="h2 text-center">Set Unlock Code</h2>
|
||||
{:else}
|
||||
<h2 class="h2 text-center">Unlock Code has been set ✅</h2>
|
||||
<h2 class="h2 text-center">Unlock Code has been set ✅ Press Next to Continue</h2>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
{#if !$passwordSet}
|
||||
@@ -89,10 +93,28 @@
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
{#if $identityExists == null}
|
||||
<button on:click={() => createIdentity()} class="btn variant-ghost-success" type="button">
|
||||
Generate Identity
|
||||
</button>
|
||||
<RestoreIdentity />
|
||||
<div class="flex flex-col gap-3">
|
||||
<button
|
||||
on:click={() => createIdentity()}
|
||||
class="btn btn-lg variant-ghost-success"
|
||||
type="button"
|
||||
>
|
||||
<span><Mask /></span>
|
||||
<span>Generate New Identity</span>
|
||||
<span><Magic /></span>
|
||||
</button>
|
||||
<button
|
||||
on:click={() => (restoreIdentity = !restoreIdentity)}
|
||||
class="btn variant-ghost-primary"
|
||||
type="button"
|
||||
>
|
||||
<span><BackupRestore /></span>
|
||||
<span>Restore Identity</span>
|
||||
</button>
|
||||
</div>
|
||||
{#if restoreIdentity == true}
|
||||
<RestoreIdentity />
|
||||
{/if}
|
||||
{:else if $identityExists == 'encrypted'}
|
||||
<div on:click={unlock}>
|
||||
<p class="h4 text-center">Please unlock your wallet</p>
|
||||
|
||||
Reference in New Issue
Block a user