feat: store bookmark last-opened timestamps only in DB

This commit is contained in:
2026-02-12 17:57:21 +01:00
parent bbfa93a586
commit 2feba4e585
2 changed files with 51 additions and 45 deletions

View File

@@ -379,6 +379,7 @@ const DEFAULT_SORT_SETTINGS = { mode: 'created', direction: 'desc' };
const BOOKMARKS_BASE_URL = 'https://www.facebook.com/search/top';
const BOOKMARK_WINDOW_DAYS = 28;
const BOOKMARK_SUFFIXES = ['Gewinnspiel', 'gewinnen', 'verlosen'];
const DEFAULT_BOOKMARK_LABEL = 'Gewinnspiel / gewinnen / verlosen';
const BOOKMARK_PREFS_KEY = 'trackerBookmarkPreferences';
const INCLUDE_EXPIRED_STORAGE_KEY = 'trackerIncludeExpired';
const PENDING_BULK_COUNT_STORAGE_KEY = 'trackerPendingBulkCount';
@@ -914,11 +915,14 @@ function normalizeServerBookmark(entry) {
const id = typeof entry.id === 'string' ? entry.id : null;
const query = typeof entry.query === 'string' ? entry.query.trim() : '';
if (!id || !query) {
const isDefault = entry.is_default === true || !query;
if (!id || (!isDefault && !query)) {
return null;
}
const label = typeof entry.label === 'string' && entry.label.trim() ? entry.label.trim() : query;
const label = typeof entry.label === 'string' && entry.label.trim()
? entry.label.trim()
: (isDefault ? DEFAULT_BOOKMARK_LABEL : query);
const normalizeDate = (value) => {
if (!value) {
@@ -938,7 +942,8 @@ function normalizeServerBookmark(entry) {
created_at: normalizeDate(entry.created_at),
updated_at: normalizeDate(entry.updated_at),
last_clicked_at: normalizeDate(entry.last_clicked_at),
deletable: true
deletable: entry.deletable === false ? false : !isDefault,
isDefault
};
}
@@ -947,10 +952,11 @@ function deduplicateBookmarks(list) {
const deduped = [];
list.forEach((bookmark) => {
if (!bookmark || !bookmark.query) {
if (!bookmark || typeof bookmark.id !== 'string') {
return;
}
const key = bookmark.query.toLowerCase();
const query = typeof bookmark.query === 'string' ? bookmark.query : '';
const key = query.toLowerCase();
if (seen.has(key)) {
return;
}
@@ -1050,25 +1056,13 @@ function updateBookmarkSortDirectionUI() {
}
}
const DEFAULT_BOOKMARK_LAST_CLICK_KEY = 'trackerDefaultBookmarkLastClickedAt';
const bookmarkState = {
items: [],
loaded: false,
loading: false,
error: null,
defaultLastClickedAt: null
error: null
};
try {
const storedDefaultBookmark = localStorage.getItem(DEFAULT_BOOKMARK_LAST_CLICK_KEY);
if (storedDefaultBookmark) {
bookmarkState.defaultLastClickedAt = storedDefaultBookmark;
}
} catch (error) {
console.warn('Konnte letzte Nutzung des Standard-Bookmarks nicht laden:', error);
}
let bookmarkFetchPromise = null;
function formatRelativeTimeFromNow(timestamp) {
@@ -1117,10 +1111,11 @@ function upsertBookmarkInState(bookmark) {
const lowerQuery = normalized.query.toLowerCase();
const existingIndex = bookmarkState.items.findIndex((item) => {
if (!item || !item.query) {
if (!item || typeof item.id !== 'string') {
return false;
}
return item.id === normalized.id || item.query.toLowerCase() === lowerQuery;
const itemQuery = typeof item.query === 'string' ? item.query.toLowerCase() : '';
return item.id === normalized.id || itemQuery === lowerQuery;
});
if (existingIndex >= 0) {
@@ -1419,26 +1414,18 @@ function openBookmark(bookmark) {
}
const stateBookmark = bookmarkState.items.find((item) => item.id === bookmark.id) || bookmark;
const isDefaultBookmark = stateBookmark && stateBookmark.isDefault;
const nowIso = new Date().toISOString();
if (isDefaultBookmark) {
bookmarkState.defaultLastClickedAt = nowIso;
try {
localStorage.setItem(DEFAULT_BOOKMARK_LAST_CLICK_KEY, nowIso);
} catch (error) {
console.warn('Konnte Standard-Bookmark-Zeit nicht speichern:', error);
}
renderBookmarks();
} else if (stateBookmark && stateBookmark.id && stateBookmark.deletable !== false) {
if (stateBookmark && stateBookmark.id) {
upsertBookmarkInState({
id: stateBookmark.id,
label: stateBookmark.label,
query: stateBookmark.query,
last_clicked_at: nowIso,
created_at: stateBookmark.created_at || nowIso,
updated_at: nowIso
updated_at: nowIso,
deletable: stateBookmark.deletable !== false,
is_default: stateBookmark.isDefault === true
});
renderBookmarks();
markBookmarkClick(stateBookmark.id);
@@ -1588,20 +1575,13 @@ function renderBookmarks() {
}
const dynamicBookmarks = bookmarkState.items;
const staticDefault = {
id: 'default-search',
label: 'Gewinnspiel / gewinnen / verlosen',
query: '',
last_clicked_at: bookmarkState.defaultLastClickedAt || null,
deletable: false,
isDefault: true
};
const filteredBookmarks = filterBookmarksBySearch(dynamicBookmarks);
const sortedForAll = sortBookmarksForDisplay(filteredBookmarks);
const displayList = bookmarkSearchTerm ? sortedForAll : [staticDefault, ...sortedForAll];
const defaultBookmark = sortedForAll.find((bookmark) => bookmark.isDefault);
const nonDefaultBookmarks = sortedForAll.filter((bookmark) => !bookmark.isDefault);
const displayList = bookmarkSearchTerm
? sortedForAll
: (defaultBookmark ? [defaultBookmark, ...nonDefaultBookmarks] : nonDefaultBookmarks);
const titleText = bookmarkSearchTerm
? (filteredBookmarks.length ? `Suchergebnisse (${filteredBookmarks.length})` : 'Keine Treffer')
: 'Alle Bookmarks';