Dead and trivial code rip out (whoof)

This commit is contained in:
Jack Kingsman
2026-02-04 12:06:36 -08:00
parent edfc95a2e2
commit ad5e799a62
21 changed files with 28 additions and 744 deletions
-2
View File
@@ -58,7 +58,6 @@ await RawPacketRepository.mark_decrypted(packet_id, message_id)
settings = await AppSettingsRepository.get()
await AppSettingsRepository.update(auto_decrypt_dm_on_advert=True)
await AppSettingsRepository.add_favorite("contact", public_key)
await AppSettingsRepository.update_last_message_time("channel-KEY", timestamp)
```
### Radio Connection
@@ -512,7 +511,6 @@ All endpoints are prefixed with `/api`.
- `POST /api/settings/favorites` - Add a favorite
- `DELETE /api/settings/favorites` - Remove a favorite
- `POST /api/settings/favorites/toggle` - Toggle favorite status
- `POST /api/settings/last-message-time` - Update last message time for a conversation
- `POST /api/settings/migrate` - One-time migration from frontend localStorage
### WebSocket
-27
View File
@@ -874,33 +874,6 @@ class AppSettingsRepository:
]
return await AppSettingsRepository.update(favorites=new_favorites)
@staticmethod
async def update_last_message_time(state_key: str, timestamp: int) -> None:
"""Update the last message time for a conversation atomically.
Only updates if the new timestamp is greater than the existing one.
Uses SQLite's json_set for atomic update to avoid race conditions.
"""
# Use COALESCE to handle NULL or missing keys, json_set for atomic update
# Only update if new timestamp > existing (or key doesn't exist)
await db.conn.execute(
"""
UPDATE app_settings
SET last_message_times = json_set(
COALESCE(last_message_times, '{}'),
'$.' || ?,
?
)
WHERE id = 1
AND (
json_extract(last_message_times, '$.' || ?) IS NULL
OR json_extract(last_message_times, '$.' || ?) < ?
)
""",
(state_key, timestamp, state_key, state_key, timestamp),
)
await db.conn.commit()
@staticmethod
async def migrate_preferences_from_frontend(
favorites: list[dict],
-18
View File
@@ -63,13 +63,6 @@ class FavoriteRequest(BaseModel):
id: str = Field(description="Channel key or contact public key")
class LastMessageTimeUpdate(BaseModel):
state_key: str = Field(
description="Conversation state key (e.g., 'channel-KEY' or 'contact-PREFIX')"
)
timestamp: int = Field(description="Unix timestamp of the last message")
class MigratePreferencesRequest(BaseModel):
favorites: list[FavoriteRequest] = Field(
default_factory=list,
@@ -144,17 +137,6 @@ async def toggle_favorite(request: FavoriteRequest) -> AppSettings:
return await AppSettingsRepository.add_favorite(request.type, request.id)
@router.post("/last-message-time")
async def update_last_message_time(request: LastMessageTimeUpdate) -> dict:
"""Update the last message time for a conversation.
Used to track when conversations last received messages for sidebar sorting.
Only updates if the new timestamp is greater than the existing one.
"""
await AppSettingsRepository.update_last_message_time(request.state_key, request.timestamp)
return {"status": "ok"}
@router.post("/migrate", response_model=MigratePreferencesResponse)
async def migrate_preferences(request: MigratePreferencesRequest) -> MigratePreferencesResponse:
"""Migrate all preferences from frontend localStorage to database.
+4 -12
View File
@@ -192,19 +192,11 @@ server: {
## Type Definitions (`types.ts`)
### Key Type Aliases
```typescript
type PublicKey = string; // 64-char hex identifying a contact/node
type PubkeyPrefix = string; // 12-char hex prefix (used in message routing)
type ChannelKey = string; // 32-char hex identifying a channel
```
### Key Interfaces
```typescript
interface Contact {
public_key: PublicKey;
public_key: string; // 64-char hex public key
name: string | null;
type: number; // 0=unknown, 1=client, 2=repeater, 3=room
on_radio: boolean;
@@ -215,7 +207,7 @@ interface Contact {
}
interface Channel {
key: ChannelKey;
key: string; // 32-char hex channel key
name: string;
is_hashtag: boolean;
on_radio: boolean;
@@ -224,7 +216,7 @@ interface Channel {
interface Message {
id: number;
type: 'PRIV' | 'CHAN';
conversation_key: string; // PublicKey for PRIV, ChannelKey for CHAN
conversation_key: string; // public key for PRIV, channel key for CHAN
text: string;
outgoing: boolean;
acked: number; // 0=not acked, 1+=ack count (flood echoes)
@@ -233,7 +225,7 @@ interface Message {
interface Conversation {
type: 'contact' | 'channel' | 'raw' | 'map' | 'visualizer';
id: string; // PublicKey for contacts, ChannelKey for channels, 'raw'/'map'/'visualizer' for special views
id: string; // public key for contacts, channel key for channels, 'raw'/'map'/'visualizer' for special views
name: string;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -13,7 +13,7 @@
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="manifest" href="/site.webmanifest" />
<script type="module" crossorigin src="/assets/index-BrthzT77.js"></script>
<script type="module" crossorigin src="/assets/index-CWnjp-zX.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DJA5wYVF.css">
</head>
<body>
-7
View File
@@ -204,13 +204,6 @@ export const api = {
body: JSON.stringify({ type, id }),
}),
// Last message time tracking
updateLastMessageTime: (stateKey: string, timestamp: number) =>
fetchJson<{ status: string }>('/settings/last-message-time', {
method: 'POST',
body: JSON.stringify({ state_key: stateKey, timestamp }),
}),
// Preferences migration (one-time, from localStorage to database)
migratePreferences: (request: MigratePreferencesRequest) =>
fetchJson<MigratePreferencesResponse>('/settings/migrate', {
+1 -2
View File
@@ -12,8 +12,7 @@ import {
type SimulationLinkDatum,
} from 'd3-force';
import { MeshCoreDecoder, PayloadType } from '@michaelhart/meshcore-decoder';
import type { Contact, RawPacket, RadioConfig } from '../types';
import { CONTACT_TYPE_REPEATER } from '../utils/contactAvatar';
import { CONTACT_TYPE_REPEATER, type Contact, type RawPacket, type RadioConfig } from '../types';
import { Checkbox } from './ui/checkbox';
// =============================================================================
+11 -11
View File
@@ -1,9 +1,14 @@
import { useState } from 'react';
import type { Contact, Channel, Conversation, Favorite } from '../types';
import {
CONTACT_TYPE_REPEATER,
type Contact,
type Channel,
type Conversation,
type Favorite,
} from '../types';
import { getStateKey, type ConversationTimes } from '../utils/conversationState';
import { getContactDisplayName } from '../utils/pubkey';
import { ContactAvatar } from './ContactAvatar';
import { CONTACT_TYPE_REPEATER } from '../utils/contactAvatar';
import { isFavorite } from '../utils/favorites';
import { Input } from './ui/input';
import { Button } from './ui/button';
@@ -32,11 +37,6 @@ interface SidebarProps {
onSortOrderChange?: (order: SortOrder) => void;
}
/** Format unread count for display */
function formatUnreadCount(count: number): string {
return `${count}`;
}
export function Sidebar({
contacts,
channels,
@@ -379,7 +379,7 @@ export function Sidebar({
: 'bg-primary text-primary-foreground'
)}
>
{formatUnreadCount(unreadCount)}
{unreadCount}
</span>
)}
</div>
@@ -422,7 +422,7 @@ export function Sidebar({
: 'bg-primary text-primary-foreground'
)}
>
{formatUnreadCount(unreadCount)}
{unreadCount}
</span>
)}
</div>
@@ -474,7 +474,7 @@ export function Sidebar({
: 'bg-primary text-primary-foreground'
)}
>
{formatUnreadCount(unreadCount)}
{unreadCount}
</span>
)}
</div>
@@ -535,7 +535,7 @@ export function Sidebar({
: 'bg-primary text-primary-foreground'
)}
>
{formatUnreadCount(unreadCount)}
{unreadCount}
</span>
)}
</div>
+3 -7
View File
@@ -1,7 +1,3 @@
export { useRepeaterMode, type UseRepeaterModeResult } from './useRepeaterMode';
export { useUnreadCounts, type UseUnreadCountsResult } from './useUnreadCounts';
export {
useConversationMessages,
type UseConversationMessagesResult,
getMessageContentKey,
} from './useConversationMessages';
export { useRepeaterMode } from './useRepeaterMode';
export { useUnreadCounts } from './useUnreadCounts';
export { useConversationMessages, getMessageContentKey } from './useConversationMessages';
-41
View File
@@ -15,7 +15,6 @@ export interface UseUnreadCountsResult {
lastMessageTimes: ConversationTimes;
incrementUnread: (stateKey: string, hasMention?: boolean) => void;
markAllRead: () => void;
markConversationRead: (conv: Conversation) => void;
trackNewMessage: (msg: Message) => void;
}
@@ -136,45 +135,6 @@ export function useUnreadCounts(
});
}, []);
// Mark a specific conversation as read
// Calls server API to persist read state across devices
const markConversationRead = useCallback((conv: Conversation) => {
if (conv.type === 'raw' || conv.type === 'map' || conv.type === 'visualizer') return;
const key = getStateKey(conv.type as 'channel' | 'contact', conv.id);
// Update local state immediately
setUnreadCounts((prev) => {
if (prev[key]) {
const next = { ...prev };
delete next[key];
return next;
}
return prev;
});
// Also clear mentions for this conversation
setMentions((prev) => {
if (prev[key]) {
const next = { ...prev };
delete next[key];
return next;
}
return prev;
});
// Persist to server (fire-and-forget)
if (conv.type === 'channel') {
api.markChannelRead(conv.id).catch((err) => {
console.error('Failed to mark channel as read on server:', err);
});
} else if (conv.type === 'contact') {
api.markContactRead(conv.id).catch((err) => {
console.error('Failed to mark contact as read on server:', err);
});
}
}, []);
// Track a new incoming message for unread counts
const trackNewMessage = useCallback((msg: Message) => {
let conversationKey: string | null = null;
@@ -197,7 +157,6 @@ export function useUnreadCounts(
lastMessageTimes,
incrementUnread,
markAllRead,
markConversationRead,
trackNewMessage,
};
}
+2 -6
View File
@@ -1,10 +1,6 @@
import { describe, it, expect } from 'vitest';
import {
getAvatarText,
getAvatarColor,
getContactAvatar,
CONTACT_TYPE_REPEATER,
} from '../utils/contactAvatar';
import { getAvatarText, getAvatarColor, getContactAvatar } from '../utils/contactAvatar';
import { CONTACT_TYPE_REPEATER } from '../types';
describe('getAvatarText', () => {
it('returns first emoji when name contains emoji', () => {
+2 -13
View File
@@ -1,14 +1,3 @@
/**
* Type aliases for key types used throughout the application.
* These are all hex strings but serve different purposes.
*/
/** 64-character hex string identifying a contact/node */
export type PublicKey = string;
/** 32-character hex string identifying a channel */
export type ChannelKey = string;
export interface RadioSettings {
freq: number;
bw: number;
@@ -48,7 +37,7 @@ export interface MaintenanceResult {
}
export interface Contact {
public_key: PublicKey;
public_key: string;
name: string | null;
type: number;
flags: number;
@@ -64,7 +53,7 @@ export interface Contact {
}
export interface Channel {
key: ChannelKey;
key: string;
name: string;
is_hashtag: boolean;
on_radio: boolean;
+1 -2
View File
@@ -6,8 +6,7 @@
* Repeaters (type=2) always show 🛜 with a gray background.
*/
// Contact type constants (matches backend)
export const CONTACT_TYPE_REPEATER = 2;
import { CONTACT_TYPE_REPEATER } from '../types';
// Repeater avatar styling
const REPEATER_AVATAR = {
+1 -1
View File
@@ -13,7 +13,7 @@ const LAST_MESSAGE_KEY = 'remoteterm-lastMessageTime';
const SORT_ORDER_KEY = 'remoteterm-sortOrder';
export type ConversationTimes = Record<string, number>;
export type SortOrder = 'recent' | 'alpha';
type SortOrder = 'recent' | 'alpha';
// In-memory cache of last message times (loaded from server on init)
let lastMessageTimesCache: ConversationTimes = {};
-3
View File
@@ -43,6 +43,3 @@ export function clearLocalStorageFavorites(): void {
// localStorage might be disabled
}
}
// Re-export the Favorite type for convenience
export type { Favorite };
+1 -1
View File
@@ -14,7 +14,7 @@ const PUBKEY_PREFIX_LENGTH = 12;
* Extract the 12-character prefix from a public key.
* Works with both full keys and existing prefixes.
*/
export function getPubkeyPrefix(key: string): string {
function getPubkeyPrefix(key: string): string {
return key.slice(0, PUBKEY_PREFIX_LENGTH);
}
+1 -1
View File
@@ -1,6 +1,6 @@
import type { Conversation } from '../types';
export interface ParsedHashConversation {
interface ParsedHashConversation {
type: 'channel' | 'contact' | 'raw' | 'map' | 'visualizer';
name: string;
/** For map view: public key prefix to focus on */