mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-08-07 09:13:04 +02:00
Add debug lines for fav click
This commit is contained in:
+24
-8
@@ -207,20 +207,36 @@ export function App() {
|
|||||||
|
|
||||||
const handleToggleFavorite = useCallback(
|
const handleToggleFavorite = useCallback(
|
||||||
async (type: 'channel' | 'contact', id: string) => {
|
async (type: 'channel' | 'contact', id: string) => {
|
||||||
|
const ts = performance.now().toFixed(2);
|
||||||
|
console.log(
|
||||||
|
`[fav-debug] handleToggleFavorite called t=${ts} type=${type} id=${id.slice(0, 12)}`
|
||||||
|
);
|
||||||
|
|
||||||
// Optimistically toggle the favorite flag
|
// Optimistically toggle the favorite flag
|
||||||
if (type === 'contact') {
|
if (type === 'contact') {
|
||||||
setContacts((prev) =>
|
setContacts((prev) => {
|
||||||
prev.map((c) => (c.public_key === id ? { ...c, favorite: !c.favorite } : c))
|
const match = prev.find((c) => c.public_key === id);
|
||||||
);
|
console.log(
|
||||||
|
`[fav-debug] optimistic contact toggle t=${ts} current=${match?.favorite} → ${!match?.favorite}`
|
||||||
|
);
|
||||||
|
return prev.map((c) => (c.public_key === id ? { ...c, favorite: !c.favorite } : c));
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
setChannels((prev) =>
|
setChannels((prev) => {
|
||||||
prev.map((c) => (c.key === id ? { ...c, favorite: !c.favorite } : c))
|
const match = prev.find((c) => c.key === id);
|
||||||
);
|
console.log(
|
||||||
|
`[fav-debug] optimistic channel toggle t=${ts} current=${match?.favorite} → ${!match?.favorite}`
|
||||||
|
);
|
||||||
|
return prev.map((c) => (c.key === id ? { ...c, favorite: !c.favorite } : c));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await api.toggleFavorite(type, id);
|
console.log(`[fav-debug] firing API request t=${ts}`);
|
||||||
} catch {
|
const result = await api.toggleFavorite(type, id);
|
||||||
|
console.log(`[fav-debug] API response t=${ts}`, result);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`[fav-debug] API error t=${ts}`, err);
|
||||||
// Revert on failure
|
// Revert on failure
|
||||||
if (type === 'contact') {
|
if (type === 'contact') {
|
||||||
setContacts((prev) =>
|
setContacts((prev) =>
|
||||||
|
|||||||
@@ -120,7 +120,12 @@ export function ChannelInfoPane({
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="text-sm flex items-center gap-2 hover:text-primary transition-colors"
|
className="text-sm flex items-center gap-2 hover:text-primary transition-colors"
|
||||||
onClick={() => onToggleFavorite('channel', channel.key)}
|
onClick={(e) => {
|
||||||
|
console.log(
|
||||||
|
`[fav-debug] ChannelInfoPane star clicked t=${performance.now().toFixed(2)} detail=${e.detail} isTrusted=${e.isTrusted}`
|
||||||
|
);
|
||||||
|
onToggleFavorite('channel', channel.key);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{channel.favorite ? (
|
{channel.favorite ? (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -351,9 +351,12 @@ export function ChatHeader({
|
|||||||
{(conversation.type === 'channel' || conversation.type === 'contact') && (
|
{(conversation.type === 'channel' || conversation.type === 'contact') && (
|
||||||
<button
|
<button
|
||||||
className="p-1 rounded hover:bg-accent text-lg leading-none transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
className="p-1 rounded hover:bg-accent text-lg leading-none transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
||||||
onClick={() =>
|
onClick={(e) => {
|
||||||
onToggleFavorite(conversation.type as 'channel' | 'contact', conversation.id)
|
console.log(
|
||||||
}
|
`[fav-debug] star clicked t=${performance.now().toFixed(2)} detail=${e.detail} isTrusted=${e.isTrusted}`
|
||||||
|
);
|
||||||
|
onToggleFavorite(conversation.type as 'channel' | 'contact', conversation.id);
|
||||||
|
}}
|
||||||
title={favoriteTitle}
|
title={favoriteTitle}
|
||||||
aria-label={isFav ? 'Remove from favorites' : 'Add to favorites'}
|
aria-label={isFav ? 'Remove from favorites' : 'Add to favorites'}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -377,7 +377,12 @@ export function ContactInfoPane({
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="text-sm flex items-center gap-2 hover:text-primary transition-colors"
|
className="text-sm flex items-center gap-2 hover:text-primary transition-colors"
|
||||||
onClick={() => onToggleFavorite('contact', contact.public_key)}
|
onClick={(e) => {
|
||||||
|
console.log(
|
||||||
|
`[fav-debug] ContactInfoPane star clicked t=${performance.now().toFixed(2)} detail=${e.detail} isTrusted=${e.isTrusted}`
|
||||||
|
);
|
||||||
|
onToggleFavorite('contact', contact.public_key);
|
||||||
|
}}
|
||||||
title="Favorite contacts stay loaded on the radio for ACK support"
|
title="Favorite contacts stay loaded on the radio for ACK support"
|
||||||
>
|
>
|
||||||
{contact.favorite ? (
|
{contact.favorite ? (
|
||||||
|
|||||||
@@ -266,7 +266,12 @@ export function RepeaterDashboard({
|
|||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
className="p-1 rounded hover:bg-accent text-lg leading-none transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
className="p-1 rounded hover:bg-accent text-lg leading-none transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
||||||
onClick={() => onToggleFavorite('contact', conversation.id)}
|
onClick={(e) => {
|
||||||
|
console.log(
|
||||||
|
`[fav-debug] RepeaterDashboard star clicked t=${performance.now().toFixed(2)} detail=${e.detail} isTrusted=${e.isTrusted}`
|
||||||
|
);
|
||||||
|
onToggleFavorite('contact', conversation.id);
|
||||||
|
}}
|
||||||
title={
|
title={
|
||||||
isFav
|
isFav
|
||||||
? 'Remove from favorites. Favorite contacts stay loaded on the radio for ACK support.'
|
? 'Remove from favorites. Favorite contacts stay loaded on the radio for ACK support.'
|
||||||
|
|||||||
@@ -12,7 +12,16 @@ export function mergeContactIntoList(contacts: Contact[], incoming: Contact): Co
|
|||||||
const idx = contacts.findIndex((c) => c.public_key === incoming.public_key);
|
const idx = contacts.findIndex((c) => c.public_key === incoming.public_key);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
const existing = contacts[idx];
|
const existing = contacts[idx];
|
||||||
const merged = { ...existing, ...incoming };
|
// Preserve user-action-only fields that should not be overwritten by
|
||||||
|
// radio-event-driven WS updates (adverts, path updates, syncs). These
|
||||||
|
// fields are only changed via explicit user actions (favorite toggle,
|
||||||
|
// mark-read) or full REST refetches, not via mesh/radio events.
|
||||||
|
const merged = {
|
||||||
|
...existing,
|
||||||
|
...incoming,
|
||||||
|
favorite: existing.favorite,
|
||||||
|
last_read_at: existing.last_read_at,
|
||||||
|
};
|
||||||
const unchanged = (Object.keys(merged) as (keyof Contact)[]).every(
|
const unchanged = (Object.keys(merged) as (keyof Contact)[]).every(
|
||||||
(k) => existing[k] === merged[k]
|
(k) => existing[k] === merged[k]
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user