mirror of
https://github.com/Discreetly/frontend.git
synced 2026-01-09 12:58:03 -05:00
checkpoint - untested - major refactor to stores
This commit is contained in:
8
package-lock.json
generated
8
package-lock.json
generated
@@ -10,7 +10,7 @@
|
||||
"dependencies": {
|
||||
"@semaphore-protocol/group": "^3.10.1",
|
||||
"@semaphore-protocol/identity": "^3.10.1",
|
||||
"discreetly-interfaces": "^0.1.32",
|
||||
"discreetly-interfaces": "^0.1.34",
|
||||
"libsodium-wrappers": "^0.7.11",
|
||||
"poseidon-lite": "^0.2.0",
|
||||
"qr-scanner": "^1.4.2",
|
||||
@@ -1905,9 +1905,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/discreetly-interfaces": {
|
||||
"version": "0.1.32",
|
||||
"resolved": "https://registry.npmjs.org/discreetly-interfaces/-/discreetly-interfaces-0.1.32.tgz",
|
||||
"integrity": "sha512-qATarb8KuU5IiZ1CQTGbERSL7y3fLhVFFdQ7Yvofeu47lL4e8EFzmzabJYXRabA+QgtTAPqbrazJ7TVXfwZXUw==",
|
||||
"version": "0.1.34",
|
||||
"resolved": "https://registry.npmjs.org/discreetly-interfaces/-/discreetly-interfaces-0.1.34.tgz",
|
||||
"integrity": "sha512-7purPOWOowVH44ebdweBdZ4z2RsBQy5/H7xi6PdsHkaw1xwg8u3Ev2US5EdavP1igZ+SzebJdK8jT0ZTjzX8Kg==",
|
||||
"dependencies": {
|
||||
"poseidon-lite": "^0.2.0",
|
||||
"rlnjs": "^3.1.4"
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
"dependencies": {
|
||||
"@semaphore-protocol/group": "^3.10.1",
|
||||
"@semaphore-protocol/identity": "^3.10.1",
|
||||
"discreetly-interfaces": "^0.1.32",
|
||||
"discreetly-interfaces": "^0.1.34",
|
||||
"libsodium-wrappers": "^0.7.11",
|
||||
"poseidon-lite": "^0.2.0",
|
||||
"qr-scanner": "^1.4.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import Button from './button.svelte';
|
||||
import type { ButtonI } from '../types';
|
||||
import type { ButtonI } from '$lib/types';
|
||||
export let title: string;
|
||||
export let buttons: ButtonI[] = [];
|
||||
</script>
|
||||
|
||||
@@ -3,9 +3,10 @@ import { Group } from '@semaphore-protocol/group';
|
||||
import getMessageHash from './messageHasher';
|
||||
import getRateCommitmentHash from './rateCommitmentHasher';
|
||||
import type { Identity } from '@semaphore-protocol/identity';
|
||||
import type { MessageI, RoomI } from 'discreetly-interfaces';
|
||||
import type { MessageI } from 'discreetly-interfaces';
|
||||
import type { RoomI } from '$lib/types';
|
||||
import type { RLNFullProof, MerkleProof } from 'rlnjs';
|
||||
import { getMerkleProof } from '../services/bandada';
|
||||
import { getMerkleProof } from '$lib//services/bandada';
|
||||
|
||||
const wasmPath = '/rln/circuit.wasm';
|
||||
const zkeyPath = '/rln/final.zkey';
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
import type { ConfigurationI, IdentityStoreI } from '../types/';
|
||||
import { IdentityStoreE } from '../types/';
|
||||
import type { ServerI } from 'discreetly-interfaces';
|
||||
import { storable, sessionable } from './storeFactory';
|
||||
|
||||
/**
|
||||
* @description List of server URLs, this is mainly for bootstraping the app
|
||||
*/
|
||||
export const serverListStore = storable([] as string[], 'servers');
|
||||
|
||||
interface serverDataStoreI {
|
||||
[key: string]: ServerI;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Server Metadata keyed by the server's URL
|
||||
*/
|
||||
export const serverDataStore = storable({} as serverDataStoreI, 'serverData');
|
||||
|
||||
/**
|
||||
* @description The URL of the currently selected server
|
||||
*/
|
||||
export const selectedServer = storable('', 'selectedServer');
|
||||
|
||||
/**
|
||||
* @description The room ID of the currently selected room
|
||||
*/
|
||||
export const selectedRoom = storable('', 'selectedRoom');
|
||||
|
||||
export const roomsStore = storable(
|
||||
{
|
||||
selectedRoomId: undefined,
|
||||
roomsData: {}
|
||||
},
|
||||
'roomsStore'
|
||||
);
|
||||
|
||||
export const configStore = storable(
|
||||
{
|
||||
signUpStatus: {
|
||||
inviteAccepted: false,
|
||||
identityBackedUp: false
|
||||
},
|
||||
identityStore: IdentityStoreE.NO_IDENTITY
|
||||
} as ConfigurationI,
|
||||
'signupStatus'
|
||||
);
|
||||
|
||||
// Session store (removed after the session is cleared) of the last 500 messages or so of each room the user participates in; rooms they don't have selected will not be updated
|
||||
export const messageStore = sessionable({}, 'messages');
|
||||
|
||||
// Stores the user's identity // TODO THIS NEEDS TO BE AN ENCRYPTED SEMAPHORE IDENTITY IN THE FUTURE
|
||||
export const identityStore = storable({} as IdentityStoreI, 'identity');
|
||||
serverListStore;
|
||||
@@ -0,0 +1,14 @@
|
||||
import type { ConfigurationI } from './types';
|
||||
import { IdentityStoreE } from './types';
|
||||
|
||||
const discreetlyURL = 'https://server.discreetly.chat/';
|
||||
|
||||
export const defaultServers = { discreetlyURL: { name: 'Discreetly Server', url: discreetlyURL } };
|
||||
|
||||
export const configDefaults: ConfigurationI = {
|
||||
signUpStatus: {
|
||||
inviteAccepted: false,
|
||||
identityBackedUp: false
|
||||
},
|
||||
identityStore: IdentityStoreE.NO_IDENTITY
|
||||
};
|
||||
|
||||
@@ -25,8 +25,7 @@ function joinUrlParts(parts: string[] | string): string {
|
||||
|
||||
/**
|
||||
* @description - makes a get request to the api
|
||||
* @param {string} baseUrl - the base url of the api
|
||||
* @param {string} endpoint - the endpoint to be added to the base url
|
||||
* @param {string[] | string} urlParts - the url parts to be joined to form the url
|
||||
* @returns {object} - the response from the api
|
||||
* @throws {Error} - if the request fails
|
||||
*/
|
||||
@@ -46,8 +45,7 @@ export async function get(urlParts: string[] | string): Promise<object> {
|
||||
|
||||
/**
|
||||
* @description - makes a get request to the api
|
||||
* @param {string} baseUrl - the base url of the api
|
||||
* @param {string} endpoint - the endpoint to be added to the base url
|
||||
* @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
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import type { RoomI, ServerI } from 'discreetly-interfaces';
|
||||
import type { ServerI } from 'discreetly-interfaces';
|
||||
import type { RoomI } from '$lib/types';
|
||||
|
||||
import { get, post } from './api';
|
||||
|
||||
export async function getIdentityRoomIds(server: string, idCommitment: string): Promise<string[]> {
|
||||
|
||||
60
src/lib/stores/index.ts
Normal file
60
src/lib/stores/index.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import type { ConfigurationI, IdentityStoreI } from '$lib/types';
|
||||
import type { MessageI, ServerI } from 'discreetly-interfaces';
|
||||
import type { RoomI } from '$lib/types';
|
||||
import { storable, sessionable } from './storeFactory';
|
||||
import { configDefaults } from '$lib/defaults';
|
||||
|
||||
export interface serverStoreI {
|
||||
[key: string]: ServerI;
|
||||
}
|
||||
|
||||
interface selectedRoomStoreI {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
interface roomStoreI {
|
||||
[key: string]: RoomI;
|
||||
}
|
||||
|
||||
interface messageStoreI {
|
||||
[key: string]: MessageI[];
|
||||
}
|
||||
|
||||
/* ------------------ Server State ------------------*/
|
||||
/**
|
||||
* @description Server Metadata keyed by the server's URL
|
||||
*/
|
||||
export const serverStore = storable({} as serverStoreI, 'serverData');
|
||||
|
||||
/**
|
||||
* @description The URL of the currently selected server
|
||||
*/
|
||||
export const selectedServer = storable('' as string, 'selectedServer');
|
||||
|
||||
/* ------------------ Room State ------------------*/
|
||||
/**
|
||||
* @description Room information keyed by the roomId
|
||||
*/
|
||||
export const roomsStore = storable({} as roomStoreI, 'roomsStore');
|
||||
|
||||
/**
|
||||
* @description The room ID of the currently selected room keyed by the server's URL
|
||||
*/
|
||||
export const selectedRoom = storable({} as selectedRoomStoreI, 'selectedRoom');
|
||||
|
||||
/**
|
||||
* @description Session store (removed after the session is cleared) of the last 500 messages or so of each room the user participates in; rooms they don't have selected will not be updated
|
||||
*/
|
||||
export const messageStore = sessionable({} as messageStoreI, 'messages');
|
||||
|
||||
/* ------------------ Misc State ------------------*/
|
||||
/**
|
||||
* @description Configuration and misc state
|
||||
*/
|
||||
export const configStore = storable(configDefaults as ConfigurationI, 'configStore');
|
||||
|
||||
//TODO! This needs to be encrypted
|
||||
/**
|
||||
* @description Identity store, this is the user's identity
|
||||
*/
|
||||
export const identityStore = storable({} as IdentityStoreI, 'identity');
|
||||
33
src/lib/stores/servers.ts
Normal file
33
src/lib/stores/servers.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { get, type Writable } from 'svelte/store';
|
||||
import type { serverStoreI } from '.';
|
||||
import { serverStore, roomsStore } from '.';
|
||||
import { getServerData } from '$lib/services/server';
|
||||
import type { RoomI } from '$lib/types';
|
||||
|
||||
export function getServerList(store: Writable<serverStoreI> = serverStore): string[] {
|
||||
return Object.keys(get(store));
|
||||
}
|
||||
|
||||
export function getServerRooms(url: string, store: Writable<serverStoreI> = serverStore): RoomI[] {
|
||||
let roomIds = get(store)[url].rooms;
|
||||
if (!roomIds) {
|
||||
roomIds = [];
|
||||
}
|
||||
return roomIds.map((roomId) => {
|
||||
return get(roomsStore)[roomId];
|
||||
}) as RoomI[];
|
||||
}
|
||||
|
||||
export async function updateServer(
|
||||
url: string,
|
||||
store: Writable<serverStoreI> = serverStore
|
||||
): Promise<void> {
|
||||
const oldServerStore = get(store);
|
||||
getServerData(url).then((newServerData) => {
|
||||
const newServerStore = {
|
||||
...oldServerStore,
|
||||
[url]: newServerData
|
||||
};
|
||||
store.set(newServerStore);
|
||||
});
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Identity } from '@semaphore-protocol/identity';
|
||||
import type { RoomI as RI } from 'discreetly-interfaces';
|
||||
|
||||
export interface ButtonI {
|
||||
link: string;
|
||||
@@ -8,14 +9,14 @@ export interface ButtonI {
|
||||
|
||||
// For rooms where a user has a unique identity
|
||||
export interface RoomIdentityI {
|
||||
[key: string]: Identity; // The key is the room id (bigint) as a string
|
||||
[key: string]: Identity; // The key is the roomId (bigint) as a string
|
||||
}
|
||||
|
||||
export interface IdentityStoreI {
|
||||
identity: Identity;
|
||||
}
|
||||
|
||||
export interface ServerListI {
|
||||
export interface ServerUrlI {
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
@@ -41,3 +42,7 @@ export interface ConfigurationI {
|
||||
signUpStatus: SignUpStatusI;
|
||||
identityStore: IdentityStoreE;
|
||||
}
|
||||
|
||||
export interface RoomI extends RI {
|
||||
server?: string;
|
||||
}
|
||||
|
||||
@@ -1,48 +1,11 @@
|
||||
import type { RoomI, ServerI } from 'discreetly-interfaces';
|
||||
import { identityStore, serverDataStore, serverListStore, roomsStore } from './data/stores';
|
||||
import type { RoomI } from '$lib/types';
|
||||
import { identityStore, serverStore, roomsStore } from '$lib/stores';
|
||||
import { get } from 'svelte/store';
|
||||
import { getIdentityRoomIds, getRoomById, getServerData } from './services/server';
|
||||
import type { ServerListI } from './types';
|
||||
import { getIdentityRoomIds, getRoomById } from '$lib/services/server';
|
||||
|
||||
const defaultServers = [
|
||||
{ name: 'Discreetly Server', url: 'https://server.discreetly.chat/' },
|
||||
{ name: 'Localhost', url: 'http://localhost:3001/api/' } as ServerListI
|
||||
];
|
||||
// TODO! EVERYTHING IN THIS FILE SHOULD BE DEPRECATED AND MOVED TO PROPER LOCATIONS
|
||||
|
||||
export async function updateServers(): Promise<{ [key: string]: ServerI }> {
|
||||
const serverList = get(serverListStore);
|
||||
|
||||
// If the server list is empty or doesn't have the discreetly server, add the default servers
|
||||
if (
|
||||
serverList.length < 1 ||
|
||||
!serverList.find((s: ServerListI) => s.name === 'Discreetly Server')
|
||||
) {
|
||||
console.error('serverListStore is empty');
|
||||
serverListStore.set(defaultServers);
|
||||
}
|
||||
|
||||
const newServerData: { [key: string]: ServerI } = {};
|
||||
|
||||
await Promise.all(
|
||||
serverList.map(async (server: ServerListI) => {
|
||||
console.log(`Fetching server data from ${server.url}`);
|
||||
const data = await getServerData(server.url);
|
||||
console.log(`Setting server data for ${server.url}`);
|
||||
if (data) {
|
||||
newServerData[server.url] = { ...data };
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
serverDataStore.update((store: { [key: string]: ServerI } = {}) => ({
|
||||
...store,
|
||||
...newServerData
|
||||
}));
|
||||
|
||||
return newServerData;
|
||||
}
|
||||
|
||||
export async function setRooms(server: string, roomIds: string[] = []): Promise<string[]> {
|
||||
export async function __setRooms(server: string, roomIds: string[] = []): Promise<string[]> {
|
||||
const rooms: RoomI[] = [];
|
||||
for (const roomId of roomIds) {
|
||||
const result = await getRoomById(server, roomId);
|
||||
@@ -67,7 +30,7 @@ export async function setRooms(server: string, roomIds: string[] = []): Promise<
|
||||
return rooms.map((r: RoomI) => r.name);
|
||||
}
|
||||
|
||||
export async function setSelectedRoomId(selectedRoomId: string): Promise<void> {
|
||||
export async function __setSelectedRoomId(selectedRoomId: string): Promise<void> {
|
||||
roomsStore.update(() => {
|
||||
const roomsStoreData = get(roomsStore);
|
||||
return {
|
||||
@@ -77,7 +40,7 @@ export async function setSelectedRoomId(selectedRoomId: string): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateRooms(
|
||||
export async function __updateRooms(
|
||||
selectedServer: string,
|
||||
roomIds: string[] = []
|
||||
): Promise<string[]> {
|
||||
@@ -96,8 +59,8 @@ export async function updateRooms(
|
||||
rooms.forEach((r: RoomI) => {
|
||||
acceptedRoomNames = [...acceptedRoomNames, r.name];
|
||||
});
|
||||
serverDataStore.update(() => {
|
||||
const serverData = get(serverDataStore);
|
||||
serverStore.update(() => {
|
||||
const serverData = get(serverStore);
|
||||
serverData[selectedServer] = {
|
||||
...serverData[selectedServer],
|
||||
rooms
|
||||
@@ -107,10 +70,10 @@ export async function updateRooms(
|
||||
return acceptedRoomNames;
|
||||
}
|
||||
|
||||
export async function updateSingleRoom(selectedServer: string, roomId: string) {
|
||||
export async function __updateSingleRoom(selectedServer: string, roomId: string) {
|
||||
const room = await getRoomById(selectedServer, roomId);
|
||||
serverDataStore.update(() => {
|
||||
const serverData = get(serverDataStore);
|
||||
serverStore.update(() => {
|
||||
const serverData = get(serverStore);
|
||||
serverData[selectedServer] = {
|
||||
...serverData[selectedServer],
|
||||
rooms: [room]
|
||||
@@ -119,13 +82,13 @@ export async function updateSingleRoom(selectedServer: string, roomId: string) {
|
||||
});
|
||||
}
|
||||
|
||||
export function getServerForSelectedRoom(): any {
|
||||
export function __getServerForSelectedRoom(): any {
|
||||
const roomsStoreData = get(roomsStore);
|
||||
const selectedServer = roomsStoreData.roomsData[roomsStoreData.selectedRoomId]?.server;
|
||||
return selectedServer;
|
||||
}
|
||||
|
||||
export function getRoomsForServer(selectedServer: string): [] {
|
||||
export function __getRoomsForServer(selectedServer: string): [] {
|
||||
const roomsStoreData = get(roomsStore);
|
||||
const rooms: any = Object.values(roomsStoreData.roomsData);
|
||||
return rooms.filter((room: any) => room.server === selectedServer);
|
||||
|
||||
3
src/lib/utils/index.ts
Normal file
3
src/lib/utils/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import RateLimiter from './rateLimit';
|
||||
|
||||
export { RateLimiter };
|
||||
@@ -1,8 +1,21 @@
|
||||
class RateLimiter {
|
||||
numberMessages: number;
|
||||
milliSecondsPerEpoch: number;
|
||||
export interface State {
|
||||
currentEpoch: number;
|
||||
lastEpochMessageWasSent: number;
|
||||
remainingMessages: number;
|
||||
}
|
||||
|
||||
export interface EpochDetails {
|
||||
epoch: number;
|
||||
timestamp: number; // Unix epoch time
|
||||
local: string;
|
||||
}
|
||||
|
||||
class RateLimiter {
|
||||
private numberMessages: number;
|
||||
private milliSecondsPerEpoch: number;
|
||||
private lastEpochMessageWasSent: number;
|
||||
private remainingMessages: number;
|
||||
|
||||
constructor(numberMessages: number, milliSecondsPerEpoch: number) {
|
||||
this.numberMessages = numberMessages;
|
||||
this.milliSecondsPerEpoch = milliSecondsPerEpoch;
|
||||
@@ -10,15 +23,11 @@ class RateLimiter {
|
||||
this.remainingMessages = this.numberMessages;
|
||||
}
|
||||
|
||||
public getCurrentEpoch() {
|
||||
return Math.floor(new Date().getTime() / this.milliSecondsPerEpoch);
|
||||
getCurrentEpoch(): number {
|
||||
return Math.floor(Date.now() / this.milliSecondsPerEpoch);
|
||||
}
|
||||
|
||||
public updateState(): {
|
||||
currentEpoch: number;
|
||||
lastEpochMessageWasSent: number;
|
||||
remainingMessages: number;
|
||||
} {
|
||||
private updateState(): State {
|
||||
const currentEpoch = this.getCurrentEpoch();
|
||||
if (currentEpoch > this.lastEpochMessageWasSent) {
|
||||
this.remainingMessages = this.numberMessages;
|
||||
@@ -31,31 +40,22 @@ class RateLimiter {
|
||||
};
|
||||
}
|
||||
|
||||
public getRemainingMessages() {
|
||||
public getRemainingMessages(): number {
|
||||
this.updateState();
|
||||
return this.remainingMessages;
|
||||
}
|
||||
|
||||
// Returns the number of remaining messages
|
||||
// -1 means you have no more messages left
|
||||
public useMessage(): number {
|
||||
this.updateState();
|
||||
if (this.remainingMessages > 0) {
|
||||
this.remainingMessages--;
|
||||
return this.remainingMessages;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return this.remainingMessages > 0 ? this.remainingMessages : -1;
|
||||
}
|
||||
|
||||
public getEpochFromTimestamp(timestamp: number): {
|
||||
epoch: number;
|
||||
timestamp: number; // Unix epoch time
|
||||
local: string;
|
||||
} {
|
||||
const _timestamp = timestamp ? new Date(timestamp).toString() : Date.now().toString();
|
||||
const epoch = Math.floor(Number(_timestamp) / this.milliSecondsPerEpoch);
|
||||
const local = new Date(_timestamp).toLocaleString('en-US', {
|
||||
public getEpochFromTimestamp(timestamp: number = Date.now()): EpochDetails {
|
||||
const epoch = Math.floor(timestamp / this.milliSecondsPerEpoch);
|
||||
const local = new Date(timestamp).toLocaleString('en-US', {
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
hour12: true
|
||||
@@ -63,8 +63,8 @@ class RateLimiter {
|
||||
return { epoch, timestamp, local };
|
||||
}
|
||||
|
||||
public getTimestampFromEpoch(epoch?: number | bigint): string {
|
||||
const time = epoch ? Number(epoch) * this.milliSecondsPerEpoch : new Date();
|
||||
public getTimestampFromEpoch(epoch: number = this.getCurrentEpoch()): string {
|
||||
const time = epoch * this.milliSecondsPerEpoch;
|
||||
return new Date(time).toLocaleString('en-US', {
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
45
src/lib/utils/updateServers.ts
Normal file
45
src/lib/utils/updateServers.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { defaultServers } from '$lib/defaults';
|
||||
import { getServerData } from '$lib/services/server';
|
||||
import { serverStore } from '$lib/stores';
|
||||
import type { ServerUrlI } from '$lib/types';
|
||||
import type { ServerI } from 'discreetly-interfaces';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
// Function to update a single server
|
||||
export async function updateServer(server: ServerUrlI): Promise<ServerI | null> {
|
||||
console.log(`Fetching server data from ${server.url}`);
|
||||
const data = await getServerData(server.url);
|
||||
console.log(`Setting server data for ${server.url}`);
|
||||
if (data) {
|
||||
serverStore.update((store: { [key: string]: ServerI } = {}) => ({
|
||||
...store,
|
||||
[server.url]: data
|
||||
}));
|
||||
return data;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Function to update all servers
|
||||
export async function updateAllServers(): Promise<{ [key: string]: ServerI }> {
|
||||
const serverList = Object.keys(get(serverStore));
|
||||
|
||||
// If the server list is empty or doesn't have the discreetly server, add the default servers
|
||||
if (serverList.length < 1) {
|
||||
console.error('serverStore is empty, populating with');
|
||||
serverStore.set(defaultServers);
|
||||
}
|
||||
|
||||
const newServerData: { [key: string]: ServerI } = {};
|
||||
|
||||
await Promise.all(
|
||||
serverList.map(async (server: ServerUrlI) => {
|
||||
const data = await updateServer(server);
|
||||
if (data) {
|
||||
newServerData[server.url] = data;
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
return newServerData;
|
||||
}
|
||||
@@ -8,8 +8,8 @@
|
||||
import AppHeader from './AppHeader.svelte';
|
||||
import AppFooter from './AppFooter.svelte';
|
||||
import Loading from '$lib/components/loading.svelte';
|
||||
import { serverListStore, selectedServer } from '$lib/data/stores';
|
||||
import { updateServers } from '$lib/utils';
|
||||
import { serverListStore, selectedServer } from '$lib/stores';
|
||||
import { updateServers } from '$lib/stores/servers';
|
||||
|
||||
// Hack to get BigInt <-> JSON compatibility
|
||||
(BigInt.prototype as any).toJSON = function () {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { identityStore } from '$lib/data/stores';
|
||||
import { identityStore } from '$lib/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import Loading from '$lib/components/loading.svelte';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { identityStore } from '$lib/data/stores';
|
||||
import { identityStore } from '$lib/stores';
|
||||
import { AppBar } from '@skeletonlabs/skeleton';
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { AppBar } from '@skeletonlabs/skeleton';
|
||||
import { LightSwitch } from '@skeletonlabs/skeleton';
|
||||
import { identityStore } from '$lib/data/stores';
|
||||
import { identityStore } from '$lib/stores';
|
||||
</script>
|
||||
|
||||
<AppBar background="bg-surface-50-800-token">
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { serverDataStore } from '$lib/data/stores';
|
||||
import { updateServers } from '$lib/utils';
|
||||
import { serverStore } from '$lib/stores';
|
||||
import { updateServers } from '$lib/stores/servers';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
onMount(() => {
|
||||
if (!Object.keys($serverDataStore).length) {
|
||||
if (!Object.keys($serverStore).length) {
|
||||
updateServers();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if Object.keys($serverDataStore).length}
|
||||
{#if Object.keys($serverStore).length}
|
||||
<slot />
|
||||
{/if}
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
<script lang="ts">
|
||||
import ChatRoom from './ChatRoom.svelte';
|
||||
|
||||
import Sidebar from './Sidebar.svelte';
|
||||
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { Modal, modalStore } from '@skeletonlabs/skeleton';
|
||||
import type { ModalSettings } from '@skeletonlabs/skeleton';
|
||||
import type { RoomI, MessageI } from 'discreetly-interfaces';
|
||||
import {
|
||||
identityStore,
|
||||
messageStore,
|
||||
serverDataStore,
|
||||
serverListStore,
|
||||
roomsStore
|
||||
} from '$lib/data/stores';
|
||||
import { io } from 'socket.io-client';
|
||||
import { genProof } from '$lib/crypto/prover';
|
||||
import { Identity } from '@semaphore-protocol/identity';
|
||||
import RateLimiter from '$lib/rateLimit';
|
||||
import {
|
||||
getRoomsForServer,
|
||||
getServerForSelectedRoom,
|
||||
updateServers,
|
||||
setSelectedRoomId
|
||||
} from '$lib/utils';
|
||||
|
||||
const setRoom = (roomId: string) => {
|
||||
if (roomId) {
|
||||
setSelectedRoomId(roomId);
|
||||
}
|
||||
};
|
||||
let messageText = '';
|
||||
let connected: boolean = false;
|
||||
let rateManager: RateLimiter;
|
||||
let currentEpoch: number = 0;
|
||||
let messagesLeft: number = 0;
|
||||
|
||||
const selectedRoomsServer = getServerForSelectedRoom();
|
||||
let serverSelection = selectedRoomsServer;
|
||||
|
||||
$: selectedRoomId = $roomsStore.selectedRoomId;
|
||||
$: selectedRoomData = $roomsStore.roomsData[selectedRoomId];
|
||||
$: roomListForServer = getRoomsForServer(serverSelection) as RoomI[];
|
||||
|
||||
$: () => {
|
||||
if (!$messageStore[selectedRoomId]) {
|
||||
$messageStore[selectedRoomId] = { messages: [] };
|
||||
}
|
||||
};
|
||||
|
||||
$: sendButtonText = messagesLeft > 0 ? 'Send (' + messagesLeft + ' left)' : 'X';
|
||||
$: inRoom = true; // TODO fix this: $identityStore.rooms.hasOwnProperty(selectedRoom);
|
||||
$: canSendMessage = inRoom && connected;
|
||||
|
||||
let elemChat: HTMLElement;
|
||||
|
||||
// For some reason, eslint thinks ScrollBehavior is undefined...
|
||||
// eslint-disable-next-line no-undef
|
||||
function scrollChatBottom(behavior: ScrollBehavior = 'smooth'): void {
|
||||
setTimeout(() => {
|
||||
elemChat.scrollTo({ top: elemChat.scrollHeight, behavior });
|
||||
}, 1);
|
||||
}
|
||||
|
||||
const socketURL: string = selectedRoomsServer;
|
||||
|
||||
const socket = io(socketURL);
|
||||
|
||||
function sendMessage() {
|
||||
if (!connected) {
|
||||
console.debug('Not connected to chat server');
|
||||
return;
|
||||
}
|
||||
if (messageText.length === 0) {
|
||||
console.debug('Message is empty');
|
||||
return;
|
||||
}
|
||||
const identity = new Identity($identityStore.toString());
|
||||
const messageID = rateManager.useMessage();
|
||||
if (messageID == -1) {
|
||||
console.debug('Rate limit exceeded');
|
||||
return;
|
||||
} else {
|
||||
messagesLeft = messageID;
|
||||
}
|
||||
genProof(selectedRoomData, messageText, identity).then((msg) => {
|
||||
socket.emit('validateMessage', msg);
|
||||
console.debug('Sending message: ', msg);
|
||||
messageText = '';
|
||||
});
|
||||
|
||||
scrollChatBottom();
|
||||
}
|
||||
|
||||
function onPromptKeydown(event: KeyboardEvent): void {
|
||||
if (['Enter'].includes(event.code)) {
|
||||
event.preventDefault();
|
||||
sendMessage();
|
||||
}
|
||||
}
|
||||
|
||||
const addServerModal: ModalSettings = {
|
||||
type: 'prompt',
|
||||
// Data
|
||||
title: 'Enter Server Address',
|
||||
body: 'Provide the server address.',
|
||||
// Populates the input value and attributes
|
||||
value: 'http://discreetly.chat/',
|
||||
valueAttr: { type: 'url', required: true },
|
||||
// Returns the updated response value
|
||||
response: (r: string) => {
|
||||
console.log('response:', r);
|
||||
if ($serverListStore.includes(r)) {
|
||||
console.warn('Server already exists');
|
||||
return;
|
||||
}
|
||||
$serverListStore.push({ url: r, name: 'LOADING...' + r });
|
||||
$serverDataStore = updateServers();
|
||||
}
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
rateManager = new RateLimiter(selectedRoomData.userMessageLimit, selectedRoomData.rateLimit);
|
||||
scrollChatBottom('instant');
|
||||
socket.on('connect', () => {
|
||||
connected = true;
|
||||
const engine = socket.io.engine;
|
||||
|
||||
engine.once('upgrade', () => {
|
||||
console.debug('Upgraded connection to', engine.transport.name);
|
||||
});
|
||||
|
||||
engine.on('close', (reason) => {
|
||||
console.debug('socket-io-transport-closed', reason);
|
||||
});
|
||||
|
||||
socket.emit('joiningRoom', selectedRoomData?.roomId);
|
||||
});
|
||||
|
||||
socket.on('disconnected', () => {
|
||||
connected = false;
|
||||
console.debug('disconnected');
|
||||
});
|
||||
|
||||
socket.on('connect_error', (err) => {
|
||||
console.debug('chat connection error', err.message);
|
||||
});
|
||||
|
||||
socket.on('connect_timeout', (err) => {
|
||||
console.debug('chat connection timeout', err.message);
|
||||
});
|
||||
|
||||
socket.on('error', (err) => {
|
||||
console.debug('chat websocket error', err.message);
|
||||
});
|
||||
|
||||
socket.on('messageBroadcast', (data: MessageI) => {
|
||||
console.debug('Received Message: ', data);
|
||||
const roomId = data.roomId?.toString();
|
||||
if (roomId) {
|
||||
if (!$messageStore[roomId]) {
|
||||
console.debug('Creating room in message store', roomId);
|
||||
$messageStore[roomId] = { messages: [] };
|
||||
}
|
||||
$messageStore[roomId].messages = [data, ...$messageStore[roomId].messages.reverse()].slice(
|
||||
0,
|
||||
500
|
||||
);
|
||||
scrollChatBottom();
|
||||
}
|
||||
});
|
||||
|
||||
setInterval(() => {
|
||||
currentEpoch = rateManager.getCurrentEpoch();
|
||||
messagesLeft = rateManager.getRemainingMessages();
|
||||
}, 1000);
|
||||
});
|
||||
onDestroy(() => {
|
||||
socket.emit('leavingRoom', selectedRoomData?.roomId);
|
||||
socket.disconnect();
|
||||
});
|
||||
</script>
|
||||
|
||||
<section id="chat-wrapper" class="bg-surface-100-800-token">
|
||||
<!-- Navigation -->
|
||||
<Sidebar />
|
||||
<!-- Chat -->
|
||||
<ChatRoom />
|
||||
</section>
|
||||
|
||||
<style>
|
||||
#chat-wrapper {
|
||||
height: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(25%, 200px) 1fr;
|
||||
grid-template-rows: auto;
|
||||
grid-template-areas: 'sidebar chat';
|
||||
}
|
||||
#sidebar {
|
||||
grid-area: sidebar;
|
||||
}
|
||||
#chat {
|
||||
max-height: calc(100vh - 101px);
|
||||
grid-area: chat;
|
||||
}
|
||||
|
||||
#conversation {
|
||||
overflow: scroll;
|
||||
}
|
||||
</style>
|
||||
@@ -1,49 +1,32 @@
|
||||
<script lang="ts">
|
||||
import Sidebar from './Sidebar.svelte';
|
||||
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { Modal, modalStore } from '@skeletonlabs/skeleton';
|
||||
import type { ModalSettings } from '@skeletonlabs/skeleton';
|
||||
import type { RoomI, MessageI } from 'discreetly-interfaces';
|
||||
import type { MessageI } from 'discreetly-interfaces';
|
||||
import {
|
||||
identityStore,
|
||||
messageStore,
|
||||
serverDataStore,
|
||||
serverListStore,
|
||||
roomsStore
|
||||
} from '$lib/data/stores';
|
||||
roomsStore,
|
||||
selectedRoom,
|
||||
selectedServer
|
||||
} from '$lib/stores';
|
||||
import { io } from 'socket.io-client';
|
||||
import type { Socket } from 'socket.io-client';
|
||||
import { genProof } from '$lib/crypto/prover';
|
||||
import { Identity } from '@semaphore-protocol/identity';
|
||||
import RateLimiter from '$lib/rateLimit';
|
||||
import {
|
||||
getRoomsForServer,
|
||||
getServerForSelectedRoom,
|
||||
updateServers,
|
||||
setSelectedRoomId
|
||||
} from '$lib/utils';
|
||||
import RateLimiter from '$lib/utils/rateLimit';
|
||||
import { __getRoomsForServer, __getServerForSelectedRoom, __setSelectedRoomId } from '$lib/utils';
|
||||
|
||||
const setRoom = (roomId: string) => {
|
||||
if (roomId) {
|
||||
setSelectedRoomId(roomId);
|
||||
}
|
||||
};
|
||||
let messageText = '';
|
||||
let connected: boolean = false;
|
||||
let rateManager: RateLimiter;
|
||||
let currentEpoch: number = 0;
|
||||
let messagesLeft: number = 0;
|
||||
|
||||
const selectedRoomsServer = getServerForSelectedRoom();
|
||||
let serverSelection = selectedRoomsServer;
|
||||
|
||||
$: selectedRoomId = $roomsStore.selectedRoomId;
|
||||
$: selectedRoomData = $roomsStore.roomsData[selectedRoomId];
|
||||
$: roomListForServer = getRoomsForServer(serverSelection) as RoomI[];
|
||||
let socket: Socket;
|
||||
$: selectedRoomId = $selectedRoom[$selectedServer];
|
||||
$: selectedRoomData = $roomsStore[selectedRoomId];
|
||||
|
||||
$: () => {
|
||||
if (!$messageStore[selectedRoomId]) {
|
||||
$messageStore[selectedRoomId] = { messages: [] };
|
||||
$messageStore[selectedRoomId] = [];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -61,10 +44,6 @@
|
||||
}, 1);
|
||||
}
|
||||
|
||||
const socketURL: string = selectedRoomsServer;
|
||||
|
||||
const socket = io(socketURL);
|
||||
|
||||
function sendMessage() {
|
||||
if (!connected) {
|
||||
console.debug('Not connected to chat server');
|
||||
@@ -98,28 +77,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
const addServerModal: ModalSettings = {
|
||||
type: 'prompt',
|
||||
// Data
|
||||
title: 'Enter Server Address',
|
||||
body: 'Provide the server address.',
|
||||
// Populates the input value and attributes
|
||||
value: 'http://discreetly.chat/',
|
||||
valueAttr: { type: 'url', required: true },
|
||||
// Returns the updated response value
|
||||
response: (r: string) => {
|
||||
console.log('response:', r);
|
||||
if ($serverListStore.includes(r)) {
|
||||
console.warn('Server already exists');
|
||||
return;
|
||||
}
|
||||
$serverListStore.push({ url: r, name: 'LOADING...' + r });
|
||||
$serverDataStore = updateServers();
|
||||
}
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
rateManager = new RateLimiter(selectedRoomData.userMessageLimit, selectedRoomData.rateLimit);
|
||||
socket = io($selectedServer);
|
||||
rateManager = new RateLimiter(selectedRoomData.userMessageLimit!, selectedRoomData.rateLimit!);
|
||||
scrollChatBottom('instant');
|
||||
socket.on('connect', () => {
|
||||
connected = true;
|
||||
@@ -159,12 +119,9 @@
|
||||
if (roomId) {
|
||||
if (!$messageStore[roomId]) {
|
||||
console.debug('Creating room in message store', roomId);
|
||||
$messageStore[roomId] = { messages: [] };
|
||||
$messageStore[roomId] = [] as MessageI[];
|
||||
}
|
||||
$messageStore[roomId].messages = [data, ...$messageStore[roomId].messages.reverse()].slice(
|
||||
0,
|
||||
500
|
||||
);
|
||||
$messageStore[roomId] = [data, ...$messageStore[roomId].reverse()].slice(0, 500);
|
||||
scrollChatBottom();
|
||||
}
|
||||
});
|
||||
@@ -198,12 +155,12 @@
|
||||
<!-- Conversation -->
|
||||
<section id="conversation" bind:this={elemChat} class="p-4 overflow-y-auto space-y-4">
|
||||
{#if $messageStore[selectedRoomId]}
|
||||
{#each $messageStore[selectedRoomId].messages.reverse() as bubble}
|
||||
{#each $messageStore[selectedRoomId].reverse() as bubble}
|
||||
<div class="flex">
|
||||
<div class="card p-4 space-y-2 bg-surface-200-700-token">
|
||||
<header class="flex justify-between items-center">
|
||||
<small class="opacity-50 text-primary-500"
|
||||
>{rateManager.getTimestampFromEpoch(bubble.epoch)}</small
|
||||
>{rateManager.getTimestampFromEpoch(Number(bubble.epoch))}</small
|
||||
>
|
||||
<small class="opacity-50 text-primary-500">epoch: {bubble.epoch}</small>
|
||||
</header>
|
||||
|
||||
@@ -1,100 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { Modal, modalStore } from '@skeletonlabs/skeleton';
|
||||
import type { ModalSettings } from '@skeletonlabs/skeleton';
|
||||
import type { RoomI, MessageI } from 'discreetly-interfaces';
|
||||
import {
|
||||
identityStore,
|
||||
messageStore,
|
||||
serverDataStore,
|
||||
serverListStore,
|
||||
roomsStore
|
||||
} from '$lib/data/stores';
|
||||
import { io } from 'socket.io-client';
|
||||
import { genProof } from '$lib/crypto/prover';
|
||||
import { Identity } from '@semaphore-protocol/identity';
|
||||
import RateLimiter from '$lib/rateLimit';
|
||||
import {
|
||||
getRoomsForServer,
|
||||
getServerForSelectedRoom,
|
||||
updateServers,
|
||||
setSelectedRoomId
|
||||
} from '$lib/utils';
|
||||
import type { RoomI } from 'discreetly-interfaces';
|
||||
import { serverStore, selectedServer, selectedRoom } from '$lib/stores';
|
||||
|
||||
import { __getRoomsForServer, __getServerForSelectedRoom, __setSelectedRoomId } from '$lib/utils';
|
||||
import { getServerList, getServerRooms, updateServer } from '$lib/stores/servers';
|
||||
|
||||
const setRoom = (roomId: string) => {
|
||||
if (roomId) {
|
||||
setSelectedRoomId(roomId);
|
||||
__setSelectedRoomId(roomId);
|
||||
}
|
||||
};
|
||||
let messageText = '';
|
||||
let connected: boolean = false;
|
||||
let rateManager: RateLimiter;
|
||||
let currentEpoch: number = 0;
|
||||
let messagesLeft: number = 0;
|
||||
|
||||
const selectedRoomsServer = getServerForSelectedRoom();
|
||||
const selectedRoomsServer = __getServerForSelectedRoom();
|
||||
let serverSelection = selectedRoomsServer;
|
||||
|
||||
$: selectedRoomId = $roomsStore.selectedRoomId;
|
||||
$: selectedRoomData = $roomsStore.roomsData[selectedRoomId];
|
||||
$: roomListForServer = getRoomsForServer(serverSelection) as RoomI[];
|
||||
|
||||
$: () => {
|
||||
if (!$messageStore[selectedRoomId]) {
|
||||
$messageStore[selectedRoomId] = { messages: [] };
|
||||
}
|
||||
};
|
||||
|
||||
$: sendButtonText = messagesLeft > 0 ? 'Send (' + messagesLeft + ' left)' : 'X';
|
||||
$: inRoom = true; // TODO fix this: $identityStore.rooms.hasOwnProperty(selectedRoom);
|
||||
$: canSendMessage = inRoom && connected;
|
||||
|
||||
let elemChat: HTMLElement;
|
||||
|
||||
// For some reason, eslint thinks ScrollBehavior is undefined...
|
||||
// eslint-disable-next-line no-undef
|
||||
function scrollChatBottom(behavior: ScrollBehavior = 'smooth'): void {
|
||||
setTimeout(() => {
|
||||
elemChat.scrollTo({ top: elemChat.scrollHeight, behavior });
|
||||
}, 1);
|
||||
}
|
||||
|
||||
const socketURL: string = selectedRoomsServer;
|
||||
|
||||
const socket = io(socketURL);
|
||||
|
||||
function sendMessage() {
|
||||
if (!connected) {
|
||||
console.debug('Not connected to chat server');
|
||||
return;
|
||||
}
|
||||
if (messageText.length === 0) {
|
||||
console.debug('Message is empty');
|
||||
return;
|
||||
}
|
||||
const identity = new Identity($identityStore.toString());
|
||||
const messageID = rateManager.useMessage();
|
||||
if (messageID == -1) {
|
||||
console.debug('Rate limit exceeded');
|
||||
return;
|
||||
} else {
|
||||
messagesLeft = messageID;
|
||||
}
|
||||
genProof(selectedRoomData, messageText, identity).then((msg) => {
|
||||
socket.emit('validateMessage', msg);
|
||||
console.debug('Sending message: ', msg);
|
||||
messageText = '';
|
||||
});
|
||||
|
||||
scrollChatBottom();
|
||||
}
|
||||
|
||||
function onPromptKeydown(event: KeyboardEvent): void {
|
||||
if (['Enter'].includes(event.code)) {
|
||||
event.preventDefault();
|
||||
sendMessage();
|
||||
}
|
||||
}
|
||||
$: roomListForServer = getServerRooms($selectedServer) as RoomI[];
|
||||
|
||||
const addServerModal: ModalSettings = {
|
||||
type: 'prompt',
|
||||
@@ -107,75 +29,13 @@
|
||||
// Returns the updated response value
|
||||
response: (r: string) => {
|
||||
console.log('response:', r);
|
||||
if ($serverListStore.includes(r)) {
|
||||
if (getServerList().includes(r)) {
|
||||
console.warn('Server already exists');
|
||||
return;
|
||||
}
|
||||
$serverListStore.push({ url: r, name: 'LOADING...' + r });
|
||||
$serverDataStore = updateServers();
|
||||
updateServer(r);
|
||||
}
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
rateManager = new RateLimiter(selectedRoomData.userMessageLimit, selectedRoomData.rateLimit);
|
||||
scrollChatBottom('instant');
|
||||
socket.on('connect', () => {
|
||||
connected = true;
|
||||
const engine = socket.io.engine;
|
||||
|
||||
engine.once('upgrade', () => {
|
||||
console.debug('Upgraded connection to', engine.transport.name);
|
||||
});
|
||||
|
||||
engine.on('close', (reason) => {
|
||||
console.debug('socket-io-transport-closed', reason);
|
||||
});
|
||||
|
||||
socket.emit('joiningRoom', selectedRoomData?.roomId);
|
||||
});
|
||||
|
||||
socket.on('disconnected', () => {
|
||||
connected = false;
|
||||
console.debug('disconnected');
|
||||
});
|
||||
|
||||
socket.on('connect_error', (err) => {
|
||||
console.debug('chat connection error', err.message);
|
||||
});
|
||||
|
||||
socket.on('connect_timeout', (err) => {
|
||||
console.debug('chat connection timeout', err.message);
|
||||
});
|
||||
|
||||
socket.on('error', (err) => {
|
||||
console.debug('chat websocket error', err.message);
|
||||
});
|
||||
|
||||
socket.on('messageBroadcast', (data: MessageI) => {
|
||||
console.debug('Received Message: ', data);
|
||||
const roomId = data.roomId?.toString();
|
||||
if (roomId) {
|
||||
if (!$messageStore[roomId]) {
|
||||
console.debug('Creating room in message store', roomId);
|
||||
$messageStore[roomId] = { messages: [] };
|
||||
}
|
||||
$messageStore[roomId].messages = [data, ...$messageStore[roomId].messages.reverse()].slice(
|
||||
0,
|
||||
500
|
||||
);
|
||||
scrollChatBottom();
|
||||
}
|
||||
});
|
||||
|
||||
setInterval(() => {
|
||||
currentEpoch = rateManager.getCurrentEpoch();
|
||||
messagesLeft = rateManager.getRemainingMessages();
|
||||
}, 1000);
|
||||
});
|
||||
onDestroy(() => {
|
||||
socket.emit('leavingRoom', selectedRoomData?.roomId);
|
||||
socket.disconnect();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="sidebar" class="hidden lg:grid grid-rows-[auto_1fr_auto] border-r border-surface-500/30">
|
||||
@@ -189,7 +49,7 @@
|
||||
serverSelection = event.target?.value;
|
||||
}}
|
||||
>
|
||||
{#each Object.entries($serverDataStore) as [key, s]}
|
||||
{#each Object.entries($serverStore) as [key, s]}
|
||||
<option value={key}>{s.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
@@ -211,7 +71,7 @@
|
||||
}}
|
||||
>
|
||||
{#each roomListForServer as room}
|
||||
{#if room.roomId == selectedRoomId}
|
||||
{#if room.roomId == $selectedRoom[$selectedServer]}
|
||||
<option value={room.roomId} title={room.roomId ? room.roomId.toString() : ''} selected
|
||||
>{room.name}</option
|
||||
>
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { identityStore, selectedServer, serverListStore } from '$lib/data/stores';
|
||||
import { identityStore, selectedServer, serverStore } from '$lib/stores';
|
||||
import DeleteIdentity from './DeleteIdentity.svelte';
|
||||
import BackupIdentity from './BackupIdentity.svelte';
|
||||
import RestoreIdentity from './RestoreIdentity.svelte';
|
||||
import { Identity } from '@semaphore-protocol/identity';
|
||||
import Join from '../signup/Join.svelte';
|
||||
import { updateRooms } from '$lib/utils';
|
||||
import type { ServerListI } from '$lib/types';
|
||||
import { __updateRooms } from '$lib/utils';
|
||||
import { RadioGroup, RadioItem } from '@skeletonlabs/skeleton';
|
||||
|
||||
$: serverList = $serverListStore as ServerListI[];
|
||||
import { getServerList } from '$lib/stores/servers';
|
||||
|
||||
let identityExists = false;
|
||||
$: if ($identityStore.identity == undefined) {
|
||||
@@ -27,7 +25,7 @@
|
||||
|
||||
function refreshRooms() {
|
||||
console.log('Refreshing rooms');
|
||||
updateRooms($selectedServer);
|
||||
__updateRooms($selectedServer);
|
||||
}
|
||||
|
||||
function createIdentity(regenerate = false) {
|
||||
@@ -64,12 +62,12 @@
|
||||
display="flex-col"
|
||||
hover="hover:variant-soft-primary"
|
||||
>
|
||||
{#each serverList as server}
|
||||
{#each getServerList() as serverUrl}
|
||||
<RadioItem
|
||||
on:change={selectServer}
|
||||
bind:group={$selectedServer}
|
||||
name="server"
|
||||
value={server.url}>{server.name}</RadioItem
|
||||
value={$serverStore[serverUrl]}>{$serverStore[serverUrl].name}</RadioItem
|
||||
>
|
||||
{/each}
|
||||
</RadioGroup>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { identityStore } from '$lib/data/stores';
|
||||
import { identityStore } from '$lib/stores';
|
||||
import Loading from '$lib/components/loading.svelte';
|
||||
import QRCode from 'qrcode';
|
||||
import { Identity } from '@semaphore-protocol/identity';
|
||||
import type { Identity } from '@semaphore-protocol/identity';
|
||||
|
||||
let loading: boolean = false;
|
||||
let imageUrl: string | undefined = undefined;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { identityStore } from '$lib/data/stores';
|
||||
import { identityStore } from '$lib/stores';
|
||||
import type { IdentityStoreI } from '$lib/types';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
@@ -9,7 +8,7 @@
|
||||
|
||||
function deleteIdentity() {
|
||||
console.warn('DELETING IDENTITY');
|
||||
$identityStore = { identity: null, rooms: {} } as IdentityStoreI;
|
||||
$identityStore = { identity: {} } as IdentityStoreI;
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { identityStore } from '$lib/data/stores';
|
||||
import { identityStore } from '$lib/stores';
|
||||
import { Identity } from '@semaphore-protocol/identity';
|
||||
import QrScanner from 'qr-scanner';
|
||||
import { FileDropzone } from '@skeletonlabs/skeleton';
|
||||
@@ -18,7 +18,7 @@
|
||||
console.log($identityStore.identity);
|
||||
console.log(
|
||||
'Identity restored from backup file with identity commitment:',
|
||||
$identityStore.identity._commitment
|
||||
$identityStore.identity.commitment
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { identityStore, signUpStatusStore } from '$lib/data/stores';
|
||||
import { identityStore, signUpStatusStore } from '$lib/stores';
|
||||
import Loading from '$lib/components/loading.svelte';
|
||||
import { Stepper, Step } from '@skeletonlabs/skeleton';
|
||||
import { Identity } from '@semaphore-protocol/identity';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { identityStore, selectedServer, configStore } from '$lib/data/stores';
|
||||
import { setRooms } from '$lib/utils';
|
||||
import { identityStore, selectedServer, configStore } from '$lib/stores';
|
||||
import { __setRooms } from '$lib/utils';
|
||||
import { postInviteCode } from '$lib/services/server';
|
||||
import type { JoinResponseI } from '$lib/types';
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
const result = (await postInviteCode($selectedServer, { code: newCode, idc })) as JoinResponseI;
|
||||
console.log('INVITE CODE RESPONSE: ', result);
|
||||
if (result.status == 'valid' || result.status == 'already-added') {
|
||||
acceptedRoomNames = await setRooms($selectedServer, result.roomIds);
|
||||
acceptedRoomNames = await __setRooms($selectedServer, result.roomIds);
|
||||
code = '';
|
||||
$configStore.signUpStatus.inviteAccepted = true;
|
||||
} else {
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
import {
|
||||
messageStore,
|
||||
serverListStore,
|
||||
serverDataStore,
|
||||
serverStore,
|
||||
selectedServer,
|
||||
identityStore
|
||||
} from '$lib/data/stores';
|
||||
import { updateServers } from '$lib/utils';
|
||||
} from '$lib/stores';
|
||||
import { updateServers } from '$lib/stores/servers';
|
||||
import { genProof } from '$lib/crypto/prover';
|
||||
import { io } from 'socket.io-client';
|
||||
import BackupIdentity from '../identity/BackupIdentity.svelte';
|
||||
import DeleteIdentity from '../identity/DeleteIdentity.svelte';
|
||||
import RestoreIdentity from '../identity/RestoreIdentity.svelte';
|
||||
import { Identity } from '@semaphore-protocol/identity';
|
||||
import RateLimiter from '$lib/rateLimit';
|
||||
import RateLimiter from '$lib/utils/rateLimit';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let messageText = '';
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
function updateServerData() {
|
||||
console.debug('UPDATING SERVERS');
|
||||
$serverDataStore = updateServers();
|
||||
$serverStore = updateServers();
|
||||
if ($selectedServer.name == undefined) {
|
||||
$selectedServer = $serverListStore[0].url;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user