This commit is contained in:
ajvpot
2025-07-28 00:00:00 +00:00
parent 7563d0f018
commit 73d412ca50
3 changed files with 59 additions and 17 deletions
+16 -14
View File
@@ -174,20 +174,22 @@ export default function ChatBox({ showAllMessagesTab = false, className = "", st
{(!minimized) && (
<>
{showTabs && (
<div className={`flex gap-1 border-b border-gray-200 dark:border-neutral-800 ${startExpanded ? "px-4 py-2" : "mb-2"}`}>
{allTabs.map((key, idx) => (
<button
key={key.privateKey + idx}
className={`px-2 py-1 text-xs rounded-t font-mono ${
idx === selectedTab
? "bg-gray-100 dark:bg-neutral-800 text-blue-700 dark:text-blue-400 border-b-2 border-blue-500"
: "bg-transparent text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-neutral-800"
}`}
onClick={() => setSelectedTab(idx)}
>
{key.channelName || getChannelIdFromKey(key.privateKey).toUpperCase()}
</button>
))}
<div className={`border-b border-gray-200 dark:border-neutral-800 ${startExpanded ? "px-4 py-2" : "mb-2"}`}>
<div className="flex gap-1 overflow-x-auto scrollbar-hide">
{allTabs.map((key, idx) => (
<button
key={key.privateKey + idx}
className={`px-2 py-1 text-xs rounded-t font-mono whitespace-nowrap flex-shrink-0 ${
idx === selectedTab
? "bg-gray-100 dark:bg-neutral-800 text-blue-700 dark:text-blue-400 border-b-2 border-blue-500"
: "bg-transparent text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-neutral-800"
}`}
onClick={() => setSelectedTab(idx)}
>
{key.channelName || getChannelIdFromKey(key.privateKey).toUpperCase()}
</button>
))}
</div>
</div>
)}
+1 -3
View File
@@ -67,14 +67,12 @@ export async function getLatestChatMessages({ limit = 20, before, after, channel
params.channelId = channelId;
}
const whereClause = where.length > 0 ? `WHERE ${where.join(' AND ')}` : '';
const query = `SELECT ingest_timestamp, origins, mesh_timestamp, path_len, channel_hash, mac, hex(encrypted_message) AS encrypted_message, message_count, origin_path_array FROM meshcore_public_channel_messages ${whereClause} ORDER BY ingest_timestamp DESC LIMIT {limit:UInt32}`;
const query = `SELECT ingest_timestamp, mesh_timestamp, channel_hash, mac, hex(encrypted_message) AS encrypted_message, message_count, origin_path_array FROM meshcore_public_channel_messages ${whereClause} ORDER BY ingest_timestamp DESC LIMIT {limit:UInt32}`;
const resultSet = await clickhouse.query({ query, query_params: params, format: 'JSONEachRow' });
const rows = await resultSet.json();
return rows as Array<{
ingest_timestamp: string;
origins: string[];
mesh_timestamp: string;
path_len: number;
channel_hash: string;
mac: string;
encrypted_message: string;
+42
View File
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: MIT
// from https://github.com/recrof/map.meshcore.dev/blob/main/src/node-utils.js
// Modified to add TypeScript types and support targets earlier than ES2020.
function fnv1aHash(str: string): number {
let hash = BigInt(0x811c9dc5);
for (let i = 0; i < str.length; i++) {
hash = BigInt.asIntN(32, hash ^ BigInt(str.charCodeAt(i)));
hash = BigInt.asIntN(32, hash * BigInt(0x01000193));
}
return Number(hash & BigInt(0xFFFFFFFF));
}
export function getColourForName(name: string, saturation: number = 60, lightness: number = 50): string {
const hash = fnv1aHash(name);
return `hsl(${hash % 360}deg, ${saturation}%, ${lightness}%)`;
}
export function getNameIconLabel(name: string): string {
if (typeof name !== 'string' || name.length === 0) {
return ''
}
const match = name.match(/\p{Emoji_Presentation}/u);
if (!match) {
name = name.trim();
const segments = name.split(' ');
if (segments.length == 1) {
return name.charAt(0);
}
const firstSegment = segments.at(0);
const lastSegment = segments.at(-1);
if (firstSegment && lastSegment) {
return `${firstSegment[0]}${lastSegment[0]}`;
}
return '';
}
return match[0];
}