tabs in beiträgen gemerget

This commit is contained in:
2025-11-21 13:47:19 +01:00
parent b7a9091183
commit e55f17f0c8
4 changed files with 100 additions and 43 deletions

View File

@@ -18,6 +18,7 @@ let focusTabAdjusted = null;
let currentProfile = 1;
let currentTab = 'pending';
let posts = [];
let includeExpiredPosts = loadIncludeExpiredPreference();
let profilePollTimer = null;
const UPDATES_RECONNECT_DELAY = 5000;
let updatesEventSource = null;
@@ -235,6 +236,7 @@ const bookmarkSearchInput = document.getElementById('bookmarkSearchInput');
const bookmarkSortSelect = document.getElementById('bookmarkSortSelect');
const bookmarkSortDirectionToggle = document.getElementById('bookmarkSortDirectionToggle');
const profileSelectElement = document.getElementById('profileSelect');
const includeExpiredToggle = document.getElementById('includeExpiredToggle');
const REFRESH_SETTINGS_KEY = 'trackerRefreshSettings';
const SORT_SETTINGS_KEY = 'trackerSortSettings';
@@ -246,6 +248,37 @@ const BOOKMARKS_BASE_URL = 'https://www.facebook.com/search/top';
const BOOKMARK_WINDOW_DAYS = 28;
const BOOKMARK_SUFFIXES = ['Gewinnspiel', 'gewinnen', 'verlosen'];
const BOOKMARK_PREFS_KEY = 'trackerBookmarkPreferences';
const INCLUDE_EXPIRED_STORAGE_KEY = 'trackerIncludeExpired';
function loadIncludeExpiredPreference() {
try {
const stored = localStorage.getItem(INCLUDE_EXPIRED_STORAGE_KEY);
if (stored === 'true') {
return true;
}
if (stored === 'false') {
return false;
}
} catch (error) {
console.warn('Konnte Anzeigepräferenz für abgelaufene Beiträge nicht laden:', error);
}
return false;
}
function persistIncludeExpiredPreference(value) {
try {
localStorage.setItem(INCLUDE_EXPIRED_STORAGE_KEY, value ? 'true' : 'false');
} catch (error) {
console.warn('Konnte Anzeigepräferenz für abgelaufene Beiträge nicht speichern:', error);
}
}
function updateIncludeExpiredToggleUI() {
if (!includeExpiredToggle) {
return;
}
includeExpiredToggle.checked = includeExpiredPosts;
}
function initializeFocusParams() {
try {
@@ -333,12 +366,10 @@ const INITIAL_POST_LIMIT = 10;
const POST_LOAD_INCREMENT = 10;
const tabVisibleCounts = {
pending: INITIAL_POST_LIMIT,
expired: INITIAL_POST_LIMIT,
all: INITIAL_POST_LIMIT
};
const tabFilteredCounts = {
pending: 0,
expired: 0,
all: 0
};
let loadMoreObserver = null;
@@ -414,9 +445,6 @@ function toTimestamp(value, fallback = null) {
}
function getSortTabKey(tab = currentTab) {
if (tab === 'expired') {
return 'expired';
}
if (tab === 'all') {
return 'all';
}
@@ -1391,8 +1419,6 @@ function updateTabInUrl() {
const url = new URL(window.location.href);
if (currentTab === 'pending') {
url.searchParams.set('tab', 'pending');
} else if (currentTab === 'expired') {
url.searchParams.set('tab', 'expired');
} else {
url.searchParams.set('tab', 'all');
}
@@ -1401,9 +1427,6 @@ function updateTabInUrl() {
}
function getTabKey(tab = currentTab) {
if (tab === 'expired') {
return 'expired';
}
if (tab === 'all') {
return 'all';
}
@@ -1440,9 +1463,6 @@ function cleanupLoadMoreObserver() {
}
function getTabDisplayLabel(tab = currentTab) {
if (tab === 'expired') {
return 'Abgelaufen/Abgeschlossen';
}
if (tab === 'all') {
return 'Alle Beiträge';
}
@@ -1535,8 +1555,6 @@ function loadMorePosts(tab = currentTab, { triggeredByScroll = false } = {}) {
function setTab(tab, { updateUrl = true } = {}) {
if (tab === 'all') {
currentTab = 'all';
} else if (tab === 'expired') {
currentTab = 'expired';
} else {
currentTab = 'pending';
}
@@ -1553,7 +1571,7 @@ function initializeTabFromUrl() {
try {
const params = new URLSearchParams(window.location.search);
const tabParam = params.get('tab');
if (tabParam === 'all' || tabParam === 'pending' || tabParam === 'expired') {
if (tabParam === 'all' || tabParam === 'pending') {
currentTab = tabParam;
tabResolved = true;
} else if (initialTabOverride) {
@@ -2773,6 +2791,16 @@ if (profileSelectElement) {
});
}
if (includeExpiredToggle) {
updateIncludeExpiredToggleUI();
includeExpiredToggle.addEventListener('change', () => {
includeExpiredPosts = includeExpiredToggle.checked;
persistIncludeExpiredPreference(includeExpiredPosts);
resetVisibleCount('all');
renderPosts();
});
}
// Tab switching
document.querySelectorAll('.tab-btn').forEach(btn => {
btn.addEventListener('click', () => {
@@ -3087,10 +3115,10 @@ function renderPosts() {
if (currentTab === 'pending') {
filteredItems = sortedItems.filter((item) => !item.status.isExpired && item.status.canCurrentProfileCheck && !item.status.isComplete);
} else if (currentTab === 'expired') {
filteredItems = sortedItems.filter((item) => item.status.isExpired || item.status.isComplete);
} else if (currentTab === 'all') {
filteredItems = sortedItems.filter((item) => !item.status.isExpired && !item.status.isComplete);
} else {
filteredItems = includeExpiredPosts
? sortedItems
: sortedItems.filter((item) => !item.status.isExpired && !item.status.isComplete);
}
const tabTotalCount = filteredItems.length;
@@ -3115,22 +3143,17 @@ function renderPosts() {
if (!focusHandled && focusCandidateEntry && !searchActive) {
const candidateVisibleInCurrentTab = filteredItems.some(({ post }) => doesPostMatchFocus(post));
if (!candidateVisibleInCurrentTab) {
let desiredTab = 'all';
if (focusCandidateEntry.status.isExpired || focusCandidateEntry.status.isComplete) {
desiredTab = 'expired';
} else if (focusCandidateEntry.status.canCurrentProfileCheck && !focusCandidateEntry.status.isExpired && !focusCandidateEntry.status.isComplete) {
desiredTab = 'pending';
}
if (currentTab !== desiredTab && focusTabAdjusted !== desiredTab) {
focusTabAdjusted = desiredTab;
setTab(desiredTab);
if (currentTab !== 'all' && focusTabAdjusted !== 'all') {
focusTabAdjusted = 'all';
setTab('all');
return;
}
if (desiredTab !== 'all' && currentTab !== 'all' && focusTabAdjusted !== 'all') {
focusTabAdjusted = 'all';
setTab('all');
if (!includeExpiredPosts && (focusCandidateEntry.status.isExpired || focusCandidateEntry.status.isComplete)) {
includeExpiredPosts = true;
persistIncludeExpiredPreference(includeExpiredPosts);
updateIncludeExpiredToggleUI();
renderPosts();
return;
}
}
@@ -3163,8 +3186,8 @@ function renderPosts() {
let emptyIcon = '🎉';
if (currentTab === 'pending') {
emptyMessage = 'Keine offenen Beiträge!';
} else if (currentTab === 'expired') {
emptyMessage = 'Keine abgelaufenen oder abgeschlossenen Beiträge.';
} else {
emptyMessage = 'Keine Beiträge vorhanden.';
}
if (searchActive) {