mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-08-07 01:03:34 +02:00
Path display improvements, focusable maps, contact distance display, click to copy keys
This commit is contained in:
@@ -10,8 +10,16 @@ export interface PathHop {
|
||||
export interface ResolvedPath {
|
||||
sender: { name: string; prefix: string; lat: number | null; lon: number | null };
|
||||
hops: PathHop[];
|
||||
receiver: { name: string; prefix: string; lat: number | null; lon: number | null };
|
||||
receiver: {
|
||||
name: string;
|
||||
prefix: string;
|
||||
lat: number | null;
|
||||
lon: number | null;
|
||||
publicKey: string | null;
|
||||
};
|
||||
totalDistances: number[] | null; // Single-element array with sum of unambiguous distances
|
||||
/** True if path has any gaps (unknown, ambiguous, or missing location hops) */
|
||||
hasGaps: boolean;
|
||||
}
|
||||
|
||||
export interface SenderInfo {
|
||||
@@ -101,6 +109,16 @@ export function isValidLocation(lat: number | null, lon: number | null): boolean
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format distance in human-readable form (m or km)
|
||||
*/
|
||||
export function formatDistance(km: number): string {
|
||||
if (km < 1) {
|
||||
return `${Math.round(km * 1000)}m`;
|
||||
}
|
||||
return `${km.toFixed(1)}km`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort contacts by distance from a reference point
|
||||
* Contacts without location are placed at the end
|
||||
@@ -164,6 +182,7 @@ export function resolvePath(
|
||||
prefix: receiverPrefix,
|
||||
lat: config?.lat ?? null,
|
||||
lon: config?.lon ?? null,
|
||||
publicKey: config?.public_key ?? null,
|
||||
};
|
||||
|
||||
// Build hops
|
||||
@@ -229,11 +248,20 @@ export function resolvePath(
|
||||
// Calculate total distances (can be multiple if ambiguous)
|
||||
const totalDistances = calculateTotalDistances(resolvedSender, hops, resolvedReceiver);
|
||||
|
||||
// Determine if path has any gaps (unknown, ambiguous, or missing location)
|
||||
const hasGaps =
|
||||
!isValidLocation(resolvedSender.lat, resolvedSender.lon) ||
|
||||
!isValidLocation(resolvedReceiver.lat, resolvedReceiver.lon) ||
|
||||
hops.some(
|
||||
(hop) => hop.matches.length !== 1 || !isValidLocation(hop.matches[0].lat, hop.matches[0].lon)
|
||||
);
|
||||
|
||||
return {
|
||||
sender: resolvedSender,
|
||||
hops,
|
||||
receiver: resolvedReceiver,
|
||||
totalDistances,
|
||||
hasGaps,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@ import type { Conversation } from '../types';
|
||||
export interface ParsedHashConversation {
|
||||
type: 'channel' | 'contact' | 'raw' | 'map';
|
||||
name: string;
|
||||
/** For map view: public key prefix to focus on */
|
||||
mapFocusKey?: string;
|
||||
}
|
||||
|
||||
// Parse URL hash to get conversation (e.g., #channel/Public or #contact/JohnDoe or #raw)
|
||||
// Parse URL hash to get conversation (e.g., #channel/Public or #contact/JohnDoe or #raw or #map/focus/ABCD1234)
|
||||
export function parseHashConversation(): ParsedHashConversation | null {
|
||||
const hash = window.location.hash.slice(1); // Remove leading #
|
||||
if (!hash) return null;
|
||||
@@ -18,6 +20,15 @@ export function parseHashConversation(): ParsedHashConversation | null {
|
||||
return { type: 'map', name: 'map' };
|
||||
}
|
||||
|
||||
// Check for map with focus: #map/focus/{pubkey_prefix}
|
||||
if (hash.startsWith('map/focus/')) {
|
||||
const focusKey = hash.slice('map/focus/'.length);
|
||||
if (focusKey) {
|
||||
return { type: 'map', name: 'map', mapFocusKey: decodeURIComponent(focusKey) };
|
||||
}
|
||||
return { type: 'map', name: 'map' };
|
||||
}
|
||||
|
||||
const slashIndex = hash.indexOf('/');
|
||||
if (slashIndex === -1) return null;
|
||||
|
||||
@@ -30,6 +41,14 @@ export function parseHashConversation(): ParsedHashConversation | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a URL hash for focusing on a contact in the map view
|
||||
* @param publicKeyPrefix - The public key or prefix to focus on
|
||||
*/
|
||||
export function getMapFocusHash(publicKeyPrefix: string): string {
|
||||
return `#map/focus/${encodeURIComponent(publicKeyPrefix)}`;
|
||||
}
|
||||
|
||||
// Generate URL hash from conversation
|
||||
export function getConversationHash(conv: Conversation | null): string {
|
||||
if (!conv) return '';
|
||||
|
||||
Reference in New Issue
Block a user