Optimistic sort reordering and favorite addition

This commit is contained in:
Jack Kingsman
2026-01-18 23:50:00 -08:00
parent 9c071dbc53
commit 9e86d263f7
5 changed files with 68 additions and 41 deletions

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

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-BVIx9g0k.js"></script>
<script type="module" crossorigin src="/assets/index-eCIKhXih.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CnRBRJ10.css">
</head>
<body>

View File

@@ -513,16 +513,35 @@ export function App() {
setSidebarOpen(false);
}, []);
// Toggle favorite status for a conversation (via API)
const handleToggleFavorite = useCallback(async (type: 'channel' | 'contact', id: string) => {
try {
const updatedSettings = await api.toggleFavorite(type, id);
setAppSettings(updatedSettings);
} catch (err) {
console.error('Failed to toggle favorite:', err);
toast.error('Failed to update favorite');
}
}, []);
// Toggle favorite status for a conversation (via API) with optimistic update
const handleToggleFavorite = useCallback(
async (type: 'channel' | 'contact', id: string) => {
// Compute optimistic new state
const wasFavorited = isFavorite(favorites, type, id);
const optimisticFavorites = wasFavorited
? favorites.filter((f) => {
if (f.type !== type) return true;
// Use prefix matching for contacts, exact match for channels
if (type === 'contact') return !pubkeysMatch(f.id, id);
return f.id !== id;
})
: [...favorites, { type, id }];
// Optimistic update
setAppSettings((prev) => (prev ? { ...prev, favorites: optimisticFavorites } : prev));
try {
const updatedSettings = await api.toggleFavorite(type, id);
setAppSettings(updatedSettings);
} catch (err) {
console.error('Failed to toggle favorite:', err);
// Revert on error
setAppSettings((prev) => (prev ? { ...prev, favorites } : prev));
toast.error('Failed to update favorite');
}
},
[favorites]
);
// Delete channel handler
const handleDeleteChannel = useCallback(async (key: string) => {
@@ -622,13 +641,21 @@ export function App() {
[fetchUndecryptedCount]
);
// Handle sort order change via API
// Handle sort order change via API with optimistic update
const handleSortOrderChange = useCallback(async (order: 'recent' | 'alpha') => {
// Optimistic update for responsive UI
setAppSettings((prev) => (prev ? { ...prev, sidebar_sort_order: order } : prev));
try {
const updatedSettings = await api.updateSettings({ sidebar_sort_order: order });
setAppSettings(updatedSettings);
} catch (err) {
console.error('Failed to update sort order:', err);
// Revert on error
setAppSettings((prev) =>
prev ? { ...prev, sidebar_sort_order: order === 'recent' ? 'alpha' : 'recent' } : prev
);
toast.error('Failed to save sort preference');
}
}, []);