This commit is contained in:
MDeeApp
2025-10-22 18:24:28 +02:00
parent 6a2b6e46e0
commit 36dff70f98
5 changed files with 648 additions and 46 deletions

View File

@@ -1,17 +1,35 @@
const API_URL = 'https://fb.srv.medeba-media.de/api';
// Check if we should redirect to dashboard
(function checkViewRouting() {
const params = new URLSearchParams(window.location.search);
const view = params.get('view');
if (view === 'dashboard') {
// Remove view parameter and keep other params
params.delete('view');
const remainingParams = params.toString();
window.location.href = 'dashboard.html' + (remainingParams ? '?' + remainingParams : '');
let initialViewParam = null;
// Normalize incoming routing parameters without leaving the index view
(function normalizeViewRouting() {
try {
const params = new URLSearchParams(window.location.search);
const view = params.get('view');
if (!view) {
return;
}
if (view === 'dashboard') {
initialViewParam = view;
params.delete('view');
const remaining = params.toString();
const newUrl = `${window.location.pathname}${remaining ? `?${remaining}` : ''}${window.location.hash}`;
window.history.replaceState({}, document.title, newUrl);
}
} catch (error) {
console.warn('Konnte view-Parameter nicht verarbeiten:', error);
}
})();
let focusPostIdParam = null;
let focusPostUrlParam = null;
let focusNormalizedUrl = '';
let focusHandled = false;
let initialTabOverride = null;
let focusTabAdjusted = null;
let currentProfile = 1;
let currentTab = 'pending';
let posts = [];
@@ -89,6 +107,30 @@ const BOOKMARK_WINDOW_DAYS = 28;
const DEFAULT_BOOKMARKS = [];
const BOOKMARK_SUFFIXES = ['Gewinnspiel', 'gewinnen', 'verlosen'];
function initializeFocusParams() {
try {
const params = new URLSearchParams(window.location.search);
const postIdParam = params.get('postId');
const postUrlParam = params.get('postUrl');
if (postIdParam && postIdParam.trim()) {
focusPostIdParam = postIdParam.trim();
initialTabOverride = initialTabOverride || 'all';
}
if (postUrlParam && postUrlParam.trim()) {
focusPostUrlParam = postUrlParam.trim();
const normalized = normalizeFacebookPostUrl(focusPostUrlParam);
focusNormalizedUrl = normalized || focusPostUrlParam;
initialTabOverride = initialTabOverride || 'all';
}
focusHandled = false;
focusTabAdjusted = null;
} catch (error) {
console.warn('Konnte Fokus-Parameter nicht verarbeiten:', error);
}
}
let autoRefreshTimer = null;
let autoRefreshSettings = {
enabled: true,
@@ -882,18 +924,28 @@ function setTab(tab, { updateUrl = true } = {}) {
}
function initializeTabFromUrl() {
let tabResolved = false;
try {
const params = new URLSearchParams(window.location.search);
const tabParam = params.get('tab');
if (tabParam === 'all' || tabParam === 'pending' || tabParam === 'expired') {
currentTab = tabParam;
tabResolved = true;
} else if (initialTabOverride) {
currentTab = initialTabOverride;
tabResolved = true;
} else if (initialViewParam === 'dashboard') {
currentTab = 'pending';
tabResolved = true;
}
} catch (error) {
console.warn('Konnte Tab-Parameter nicht auslesen:', error);
}
updateTabButtons();
updateTabInUrl();
if (tabResolved) {
updateTabInUrl();
}
}
function normalizeDeadlineInput(value) {
@@ -2225,6 +2277,100 @@ async function normalizeLoadedPostUrls() {
return changed;
}
function doesPostMatchFocus(post) {
if (!post) {
return false;
}
if (focusPostIdParam && String(post.id) === focusPostIdParam) {
return true;
}
if (focusNormalizedUrl && post.url) {
const candidateNormalized = normalizeFacebookPostUrl(post.url) || post.url;
return candidateNormalized === focusNormalizedUrl;
}
return false;
}
function resolveFocusTargetInfo(items) {
if (!Array.isArray(items) || (!focusPostIdParam && !focusNormalizedUrl)) {
return { index: -1, post: null };
}
const index = items.findIndex(({ post }) => doesPostMatchFocus(post));
return {
index,
post: index !== -1 && items[index] ? items[index].post : null
};
}
function clearFocusParamsFromUrl() {
try {
const url = new URL(window.location.href);
let changed = false;
if (url.searchParams.has('postId')) {
url.searchParams.delete('postId');
changed = true;
}
if (url.searchParams.has('postUrl')) {
url.searchParams.delete('postUrl');
changed = true;
}
if (changed) {
const newQuery = url.searchParams.toString();
const newUrl = `${url.pathname}${newQuery ? `?${newQuery}` : ''}${url.hash}`;
window.history.replaceState({}, document.title, newUrl);
}
} catch (error) {
console.warn('Konnte Fokus-Parameter nicht aus URL entfernen:', error);
}
}
function highlightPostCard(post) {
if (!post || focusHandled) {
return;
}
const card = document.getElementById(`post-${post.id}`);
if (!card) {
return;
}
card.classList.add('post-card--highlight');
const hadTabIndex = card.hasAttribute('tabindex');
if (!hadTabIndex) {
card.setAttribute('tabindex', '-1');
card.dataset.fbTrackerTempTabindex = '1';
}
requestAnimationFrame(() => {
try {
card.scrollIntoView({ behavior: 'smooth', block: 'center' });
} catch (error) {
console.warn('Konnte Karte nicht scrollen:', error);
}
try {
card.focus({ preventScroll: true });
} catch (error) {
// ignore focus errors
}
});
window.setTimeout(() => {
card.classList.remove('post-card--highlight');
if (card.dataset.fbTrackerTempTabindex === '1') {
card.removeAttribute('tabindex');
delete card.dataset.fbTrackerTempTabindex;
}
}, 4000);
focusPostIdParam = null;
focusPostUrlParam = null;
focusNormalizedUrl = '';
focusHandled = true;
focusTabAdjusted = null;
clearFocusParamsFromUrl();
}
// Render posts
function renderPosts() {
hideLoading();
@@ -2245,6 +2391,9 @@ function renderPosts() {
}));
const sortedItems = [...postItems].sort(comparePostItems);
const focusCandidateEntry = (!focusHandled && (focusPostIdParam || focusNormalizedUrl))
? sortedItems.find((item) => doesPostMatchFocus(item.post))
: null;
let filteredItems = sortedItems;
@@ -2275,6 +2424,38 @@ 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);
return;
}
if (desiredTab !== 'all' && currentTab !== 'all' && focusTabAdjusted !== 'all') {
focusTabAdjusted = 'all';
setTab('all');
return;
}
}
}
const focusTargetInfo = resolveFocusTargetInfo(filteredItems);
if (focusTargetInfo.index !== -1) {
const requiredVisible = focusTargetInfo.index + 1;
if (requiredVisible > getVisibleCount(currentTab)) {
setVisibleCount(currentTab, requiredVisible);
}
}
updateFilteredCount(currentTab, filteredItems.length);
const visibleCount = Math.min(filteredItems.length, getVisibleCount(currentTab));
@@ -2346,6 +2527,10 @@ function renderPosts() {
observeLoadMoreElement(loadMoreContainer, currentTab);
}
if (!focusHandled && focusTargetInfo.index !== -1 && focusTargetInfo.post) {
requestAnimationFrame(() => highlightPostCard(focusTargetInfo.post));
}
}
function attachPostEventHandlers(post, status) {
@@ -3306,6 +3491,7 @@ window.addEventListener('resize', () => {
// Initialize
initializeBookmarks();
loadAutoRefreshSettings();
initializeFocusParams();
initializeTabFromUrl();
loadSortMode();
resetManualPostForm();