mirror of
https://github.com/ajvpot/meshexplorer.git
synced 2026-08-04 07:42:24 +02:00
path rep
This commit is contained in:
+16
-14
@@ -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>
|
||||
)}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
Reference in New Issue
Block a user