mirror of
https://github.com/Discreetly/frontend.git
synced 2026-01-10 05:18:06 -05:00
session id coloring and avatar
This commit is contained in:
17
package-lock.json
generated
17
package-lock.json
generated
@@ -20,11 +20,12 @@
|
||||
"@web3modal/wagmi": "^3.1.0",
|
||||
"autolinker": "^4.0.0",
|
||||
"date-fns": "^2.30.0",
|
||||
"discreetly-interfaces": "^0.1.41",
|
||||
"discreetly-interfaces": "^0.1.42",
|
||||
"dompurify": "^3.0.5",
|
||||
"idc-nullifier": "^0.0.6",
|
||||
"libsodium-wrappers": "^0.7.11",
|
||||
"marked": "^7.0.5",
|
||||
"minidenticons": "^4.2.0",
|
||||
"node-emoji": "^2.1.0",
|
||||
"poseidon-lite": "^0.2.0",
|
||||
"qr-scanner": "^1.4.2",
|
||||
@@ -4522,9 +4523,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/discreetly-interfaces": {
|
||||
"version": "0.1.41",
|
||||
"resolved": "https://registry.npmjs.org/discreetly-interfaces/-/discreetly-interfaces-0.1.41.tgz",
|
||||
"integrity": "sha512-EFSQn/SWTuFSaYMxZpbIFRFOMfvyZudL0HO0QGhi+w/EAaR+rTjHHbeTZG9chrS/HUSQ/vyH6JgotLAlQp5bVA==",
|
||||
"version": "0.1.42",
|
||||
"resolved": "https://registry.npmjs.org/discreetly-interfaces/-/discreetly-interfaces-0.1.42.tgz",
|
||||
"integrity": "sha512-1nLULAJYc7ZC59gpT0sT3fyqjrhsdgUiRnMwd/jFq3v6wtESZAEma7eWw6SordVYxVUoOkAurxwEZf830aNQow==",
|
||||
"dependencies": {
|
||||
"@ethersproject/bytes": "^5.7.0",
|
||||
"@ethersproject/keccak256": "^5.7.0",
|
||||
@@ -7163,6 +7164,14 @@
|
||||
"mini-svg-data-uri": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/minidenticons": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minidenticons/-/minidenticons-4.2.0.tgz",
|
||||
"integrity": "sha512-2T3VU1N30yI3kXMRbdLsJ5DgsBoGLi2+2hbm1xTOU2RQXWW5wwpmz9XQohVSsVlhymf4W69sMGj6s39t796PBA==",
|
||||
"engines": {
|
||||
"node": ">=15.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/minimalistic-assert": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
||||
|
||||
@@ -70,11 +70,12 @@
|
||||
"@web3modal/wagmi": "^3.1.0",
|
||||
"autolinker": "^4.0.0",
|
||||
"date-fns": "^2.30.0",
|
||||
"discreetly-interfaces": "^0.1.41",
|
||||
"discreetly-interfaces": "^0.1.42",
|
||||
"dompurify": "^3.0.5",
|
||||
"idc-nullifier": "^0.0.6",
|
||||
"libsodium-wrappers": "^0.7.11",
|
||||
"marked": "^7.0.5",
|
||||
"minidenticons": "^4.2.0",
|
||||
"node-emoji": "^2.1.0",
|
||||
"poseidon-lite": "^0.2.0",
|
||||
"qr-scanner": "^1.4.2",
|
||||
|
||||
26
src/lib/utils/color.ts
Normal file
26
src/lib/utils/color.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
function hashToDarkHSL(hash: number, offset = 6): string {
|
||||
console.log(hash);
|
||||
const hue = (hash + offset) % 360; // Hue ranges from 0-359
|
||||
const saturation = 22; // Full saturation
|
||||
const lightness = 12; // Keeping lightness around 30% for darkness
|
||||
return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
|
||||
}
|
||||
function stringToHash(str: string): number {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
hash += str.charCodeAt(i);
|
||||
}
|
||||
return hash % 360;
|
||||
}
|
||||
|
||||
export function colorFromSessionId(sessionId = ''): string {
|
||||
const hash = stringToHash(sessionId);
|
||||
return hashToDarkHSL(hash);
|
||||
}
|
||||
|
||||
export function bubbleBgFromSessionId(sessionId = ''): string {
|
||||
const hash = stringToHash(sessionId);
|
||||
const color1 = hashToDarkHSL(hash, -10);
|
||||
const color2 = hashToDarkHSL(hash, 10);
|
||||
return `background-image: linear-gradient(to right, ${color1},${color2})`;
|
||||
}
|
||||
@@ -5,7 +5,8 @@
|
||||
rateLimitStore,
|
||||
roomKeyStore,
|
||||
alertQueue,
|
||||
identityExists
|
||||
identityExists,
|
||||
configStore
|
||||
} from '$lib/stores';
|
||||
import { genProof } from '$lib/crypto/rlnProver';
|
||||
import type { Socket } from 'socket.io-client';
|
||||
@@ -111,7 +112,7 @@
|
||||
keyStore: any,
|
||||
roomKeyStore: any
|
||||
): Promise<string> {
|
||||
if (!roomKeyStore[roomId]) {
|
||||
if ($currentSelectedRoom.encrypted == 'AES' && !roomKeyStore[roomId]) {
|
||||
throw new Error('ROOM IS ENCRYPTED BUT NO PASSWORD WAS FOUND');
|
||||
}
|
||||
if (!keyStore) {
|
||||
@@ -157,7 +158,7 @@
|
||||
|
||||
let messageToSend: string = messageText;
|
||||
|
||||
if (room.encrypted) {
|
||||
if (room.encrypted === 'AES') {
|
||||
messageToSend = await handleEncryptedMessage(
|
||||
messageText,
|
||||
room.roomId!.toString(),
|
||||
@@ -233,7 +234,9 @@
|
||||
on:click={sendMessage}
|
||||
>
|
||||
<Send />
|
||||
{messagesLeft()}
|
||||
{#if $configStore.beta}
|
||||
<span class="ps-1">{messagesLeft()}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
export let onlineMembers: string;
|
||||
|
||||
$: roomId = $currentSelectedRoom?.roomId!.toString();
|
||||
$: encrypted = $currentSelectedRoom?.encrypted ?? false;
|
||||
$: ephemeral = $currentSelectedRoom?.ephemeral ?? false;
|
||||
$: encrypted = $currentSelectedRoom?.encrypted == 'AES' ?? false;
|
||||
$: ephemeral = $currentSelectedRoom?.ephemeral == 'EPHEMERAL' ?? false;
|
||||
$: roomName = $currentSelectedRoom?.name ?? 'Select Room';
|
||||
$: epochLengthSeconds = roomRateLimit / 1000;
|
||||
$: timeToNextEpoch = epochLengthSeconds - +timeLeftInEpoch;
|
||||
@@ -29,17 +29,17 @@
|
||||
<div class="flex flex-row">
|
||||
<span class="place-self-center mr-2">
|
||||
{#if connected}
|
||||
<FullCircle class="w-4 h-4 text-green-500" />
|
||||
<FullCircle class="w-4 h-4 text-green-500" title="Connected to Server" />
|
||||
{:else}
|
||||
<FullCircle class="w-4 h-4 text-error-500" />
|
||||
<FullCircle class="w-4 h-4 text-error-500" title="Not Connected to Server" />
|
||||
{/if}
|
||||
</span>
|
||||
<h2 class="h5 text-secondary-800-100-token" title={roomId}>
|
||||
{#if encrypted}
|
||||
🔒
|
||||
<span title="Room is encrypted">🔒</span>
|
||||
{/if}
|
||||
{#if ephemeral}
|
||||
⏳
|
||||
<span title="Room is ephemeral">⏳</span>
|
||||
{/if}
|
||||
{roomName}
|
||||
</h2>
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
import type { MessageI } from 'discreetly-interfaces';
|
||||
import { onMount } from 'svelte';
|
||||
import BubbleText from './BubbleText.svelte';
|
||||
import { minidenticon } from 'minidenticons';
|
||||
import { bubbleBgFromSessionId, colorFromSessionId } from '$lib/utils/color';
|
||||
|
||||
export let roomRateLimit: number;
|
||||
|
||||
@@ -25,8 +27,13 @@
|
||||
return r;
|
||||
}
|
||||
|
||||
function getAvatar(sessionID: string): string {
|
||||
return minidenticon(sessionID, 90, 60);
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
scrollChatBottom('instant', 1);
|
||||
console.log($currentRoomMessages);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -39,12 +46,26 @@
|
||||
{#each $currentRoomMessages as msg}
|
||||
<div class="flex flex-col items-start">
|
||||
<div
|
||||
class="card p-2 md:p-4 space-y-1 md:space-y-2 bg-surface-100-800-token border-1 border-secondary-500/30"
|
||||
class="card px-2 md:px-3 space-y-1 md:space-y-2 border border-surface-500/30 border-x-transparent"
|
||||
style={bubbleBgFromSessionId(msg.sessionId)}
|
||||
>
|
||||
<header class="flex justify-between items-center text-xs md:text-sm">
|
||||
<small class="opacity-50 text-surface-700-200-token mr-2 md:mr-4">{getTime(msg)}</small>
|
||||
<div class="pt-2 md:pt-4 flex gap-2 md:gap-3 pr-1">
|
||||
{#if msg.sessionId}
|
||||
<div
|
||||
title="avatar"
|
||||
class="flex-none w-[2.5rem] h-[2.5rem] bg-surface-500/40 rounded-full p-1"
|
||||
>
|
||||
{@html getAvatar(msg.sessionId)}
|
||||
</div>
|
||||
{/if}
|
||||
{#key msg}
|
||||
<BubbleText bubbleText={String(msg.message)} />
|
||||
{/key}
|
||||
</div>
|
||||
<footer class="flex justify-between items-center text-xs md:text-sm pb-1">
|
||||
<small class="opacity-50 text-surface-600-300-token mr-2 md:mr-4">{getTime(msg)}</small>
|
||||
{#if msg.epoch}
|
||||
<small class="hidden md:block opacity-50 text-surface-700-200-token"
|
||||
<small class="hidden md:block opacity-50 text-surface-500-400-token"
|
||||
>epoch: {msg.epoch}</small
|
||||
>
|
||||
{:else}
|
||||
@@ -52,10 +73,7 @@
|
||||
>SYSTEM MESSAGE</small
|
||||
>
|
||||
{/if}
|
||||
</header>
|
||||
{#key msg}
|
||||
<BubbleText bubbleText={String(msg.message)} />
|
||||
{/key}
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
Reference in New Issue
Block a user