tons of ux improvements

This commit is contained in:
AtHeartEngineer
2023-11-04 11:37:14 +03:00
parent 53ff6c93bc
commit e527dab966
32 changed files with 429 additions and 133 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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}

View File

@@ -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 };

View File

@@ -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}`);
}
}

View File

@@ -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[]>;
}

View File

@@ -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;

View File

@@ -6,9 +6,7 @@ export enum Experiences {
export enum IdentityStoreE {
'NO_IDENTITY',
'localStorage',
'localStorageEncrypted',
'cryptKeeper',
'PCDPass'
'localStorageEncrypted'
}
export enum ActionRepresentationE {

View File

@@ -11,6 +11,7 @@ export interface ConfigurationI {
beta?: boolean;
numMessagesToSave: number;
hashedPwd: string | null | undefined;
anxietyBar: boolean;
}
export interface RoomI extends RI {

View File

@@ -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>

View File

@@ -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"

View File

@@ -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>

View File

@@ -0,0 +1,7 @@
<script lang="ts">
import Container from '$lib/components/Utils/Container.svelte';
</script>
<Container>
<slot />
</Container>

View 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>

View File

@@ -155,12 +155,4 @@
</div>
<style>
#qr > div > canvas {
margin: 0 auto;
height: 250px;
width: 250px;
}
#qr > div > p {
text-align: center;
}
</style>

View 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>

View File

@@ -5,6 +5,8 @@
import { onMount } from 'svelte';
onMount(() => {
console.log('onMount');
console.log($identityExists);
if (!$identityExists) {
goto('/signup');
}

View File

@@ -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) {

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View 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>

View File

@@ -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>

View File

@@ -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>