session id coloring and avatar

This commit is contained in:
AtHeartEngineer
2023-11-05 11:56:36 +03:00
parent d68043a90d
commit 697a0f046e
6 changed files with 80 additions and 23 deletions

17
package-lock.json generated
View File

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

View File

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

View File

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

View File

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

View File

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