Add extension pause toggle

This commit is contained in:
2026-04-07 19:12:08 +02:00
parent b2647bdeab
commit ad673f29ad
4 changed files with 96 additions and 4 deletions

View File

@@ -1,7 +1,7 @@
// Facebook Post Tracker Extension
// Uses API_BASE_URL from config.js
const EXTENSION_VERSION = '1.2.3';
const EXTENSION_VERSION = '1.2.4';
const PROCESSED_ATTR = 'data-fb-tracker-processed';
const PENDING_ATTR = 'data-fb-tracker-pending';
const DIALOG_ROOT_SELECTOR = '[role="dialog"], [data-pagelet*="Modal"], [data-pagelet="StoriesRecentStoriesFeedSection"]';
@@ -18,6 +18,7 @@ const FEED_HOME_PATHS = ['/', '/home.php'];
const sessionSearchRecordedUrls = new Set();
const sessionSearchInfoCache = new Map();
let profileSelectionNoticeShown = false;
let extensionPaused = false;
function isOnSearchResultsPage() {
try {
@@ -132,16 +133,57 @@ function applyDebugLoggingPreference(value) {
}
}
chrome.storage.sync.get(['debugLoggingEnabled'], (result) => {
function resetTrackerUiState() {
document.querySelectorAll('.fb-tracker-ui').forEach((element) => {
const host = getTrackerHostElement(element);
if (host) {
host.removeAttribute(PROCESSED_ATTR);
host.removeAttribute(PENDING_ATTR);
clearTrackerElementForPost(host, element);
}
element.remove();
});
document.querySelectorAll(`[${PROCESSED_ATTR}], [${PENDING_ATTR}]`).forEach((element) => {
element.removeAttribute(PROCESSED_ATTR);
element.removeAttribute(PENDING_ATTR);
});
processedPostUrls.clear();
}
function applyExtensionPausedPreference(value) {
extensionPaused = Boolean(value);
if (extensionPaused) {
hideSelectionAIButton();
resetTrackerUiState();
originalConsoleLog('[FB Tracker] Extension paused');
return;
}
originalConsoleLog('[FB Tracker] Extension resumed');
scheduleScan();
}
chrome.storage.sync.get(['debugLoggingEnabled', 'extensionPaused'], (result) => {
applyDebugLoggingPreference(result && typeof result.debugLoggingEnabled !== 'undefined'
? result.debugLoggingEnabled
: false);
applyExtensionPausedPreference(result && typeof result.extensionPaused !== 'undefined'
? result.extensionPaused
: false);
});
chrome.storage.onChanged.addListener((changes, area) => {
if (area === 'sync' && changes && Object.prototype.hasOwnProperty.call(changes, 'debugLoggingEnabled')) {
if (area !== 'sync' || !changes) {
return;
}
if (Object.prototype.hasOwnProperty.call(changes, 'debugLoggingEnabled')) {
applyDebugLoggingPreference(changes.debugLoggingEnabled.newValue);
}
if (Object.prototype.hasOwnProperty.call(changes, 'extensionPaused')) {
applyExtensionPausedPreference(changes.extensionPaused.newValue);
}
});
function getTrackerElementForPost(postElement) {
@@ -4119,6 +4161,10 @@ async function renderTrackedStatus({
// Create the tracking UI
async function createTrackerUI(postElement, buttonBar, postNum = '?', options = {}) {
if (extensionPaused) {
return;
}
// Normalize to top-level post container if nested element passed
postElement = ensurePrimaryPostElement(postElement);
@@ -4972,6 +5018,10 @@ let globalPostCounter = 0;
// Find all Facebook posts on the page
function findPosts() {
if (extensionPaused) {
return;
}
if (maybeRedirectPageReelsToMain()) {
return;
}
@@ -5100,6 +5150,9 @@ setTimeout(findPosts, 6000);
// Debounced scan function
let scanTimeout = null;
function scheduleScan() {
if (extensionPaused) {
return;
}
if (scanTimeout) {
clearTimeout(scanTimeout);
}
@@ -5405,6 +5458,11 @@ const positionSelectionAIButton = (rect) => {
const updateSelectionAIButton = async () => {
clearSelectionAIHideTimeout();
if (extensionPaused) {
hideSelectionAIButton();
return;
}
if (selectionAIEnabledCached === null) {
try {
selectionAIEnabledCached = await isAIEnabled();
@@ -5498,6 +5556,11 @@ initSelectionAIFloatingButton();
// Listen for manual reparse command
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (extensionPaused && message && (message.type === 'generateSelectionAI' || message.type === 'reparsePost')) {
sendResponse({ success: false, paused: true });
return true;
}
if (message && message.type === 'generateSelectionAI') {
handleSelectionAIRequest(message.selectionText || '', sendResponse);
return true;

View File

@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Facebook Post Tracker",
"version": "1.2.3",
"version": "1.2.4",
"description": "Track Facebook posts across multiple profiles",
"permissions": [
"storage",

View File

@@ -137,6 +137,10 @@
<button id="webInterfaceBtn" class="secondary">Web-Interface</button>
</div>
<div class="btn-group">
<button id="pauseBtn" class="secondary">Extension pausieren</button>
</div>
<script src="config.js"></script>
<script src="popup.js"></script>
</body>

View File

@@ -1,6 +1,8 @@
const profileSelect = document.getElementById('profileSelect');
const statusEl = document.getElementById('status');
const debugToggle = document.getElementById('debugLoggingToggle');
const pauseBtn = document.getElementById('pauseBtn');
let extensionPaused = false;
function isValidProfileNumber(value) {
return Number.isInteger(value) && value >= 1 && value <= 5;
@@ -63,6 +65,13 @@ function updateStatus(message, saved = false) {
statusEl.className = saved ? 'status saved' : 'status';
}
function updatePauseButton() {
if (!pauseBtn) {
return;
}
pauseBtn.textContent = extensionPaused ? 'Extension fortsetzen' : 'Extension pausieren';
}
async function initProfileSelect() {
const backendProfile = await fetchProfileState();
if (isValidProfileNumber(backendProfile)) {
@@ -100,6 +109,11 @@ if (debugToggle) {
});
}
chrome.storage.sync.get(['extensionPaused'], (result) => {
extensionPaused = Boolean(result && result.extensionPaused);
updatePauseButton();
});
function reloadFacebookTabs() {
chrome.tabs.query({ url: ['https://www.facebook.com/*', 'https://facebook.com/*'] }, (tabs) => {
tabs.forEach(tab => {
@@ -125,3 +139,14 @@ document.getElementById('saveBtn').addEventListener('click', async () => {
document.getElementById('webInterfaceBtn').addEventListener('click', () => {
chrome.tabs.create({ url: API_BASE_URL });
});
if (pauseBtn) {
pauseBtn.addEventListener('click', () => {
const nextPaused = !extensionPaused;
chrome.storage.sync.set({ extensionPaused: nextPaused }, () => {
extensionPaused = nextPaused;
updatePauseButton();
updateStatus(`Extension ${nextPaused ? 'pausiert' : 'fortgesetzt'} (wirksam ohne Reload)`, true);
});
});
}