Skip to content

Commit 0b8460b

Browse files
committed
Implement global settings management with TOS confirmation for queue functionality
1 parent 15f6e6d commit 0b8460b

File tree

6 files changed

+205
-29
lines changed

6 files changed

+205
-29
lines changed

config.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,36 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
386386
sendResponse({ error: error.message });
387387
});
388388
return true;
389+
// ----- Global Settings Cases -----
390+
case 'getGlobalSettings':
391+
(async () => {
392+
try {
393+
const result = await chrome.storage.local.get(['globalSettings']);
394+
const settings = result.globalSettings || { acceptedQueueTOS: false };
395+
// Ensure the setting exists with a default value
396+
if (typeof settings.acceptedQueueTOS === 'undefined') {
397+
settings.acceptedQueueTOS = false;
398+
}
399+
logConfigurationRelatedStuff('Retrieved global settings:', settings);
400+
sendResponse({ settings });
401+
} catch (error) {
402+
handleStorageError(error);
403+
sendResponse({ error: error.message, settings: { acceptedQueueTOS: false } });
404+
}
405+
})();
406+
return true;
407+
case 'saveGlobalSettings':
408+
(async () => {
409+
try {
410+
await chrome.storage.local.set({ globalSettings: request.settings });
411+
logConfigurationRelatedStuff('Saved global settings:', request.settings);
412+
sendResponse({ success: true });
413+
} catch (error) {
414+
handleStorageError(error);
415+
sendResponse({ error: error.message });
416+
}
417+
})();
418+
return true;
389419
// ----- New Cases for Dark Theme Support -----
390420
case 'getTheme':
391421
(async () => {

floating-panel-settings.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,62 @@ window.MaxExtensionFloatingPanel.savePanelSettings = function () {
114114
}
115115
};
116116

117+
/**
118+
* Loads global (non-profile) settings from the service worker.
119+
*/
120+
window.MaxExtensionFloatingPanel.loadGlobalSettings = function () {
121+
chrome.runtime.sendMessage({ type: 'getGlobalSettings' }, (response) => {
122+
if (chrome.runtime.lastError) {
123+
logConCgp('[floating-panel] Error loading global settings:', chrome.runtime.lastError.message);
124+
return;
125+
}
126+
if (response && response.settings) {
127+
window.MaxExtensionGlobalSettings = response.settings;
128+
logConCgp('[floating-panel] Loaded global settings:', response.settings);
129+
}
130+
});
131+
};
132+
133+
/**
134+
* Saves global (non-profile) settings via the service worker.
135+
*/
136+
window.MaxExtensionFloatingPanel.saveGlobalSettings = function () {
137+
chrome.runtime.sendMessage({
138+
type: 'saveGlobalSettings',
139+
settings: window.MaxExtensionGlobalSettings
140+
}, (response) => {
141+
if (chrome.runtime.lastError) {
142+
logConCgp('[floating-panel] Failed to save global settings:', chrome.runtime.lastError.message);
143+
} else if (response && response.success) {
144+
logConCgp('[floating-panel] Global settings saved successfully.');
145+
}
146+
});
147+
};
148+
149+
150+
/**
151+
* Saves the current global config to storage for the active profile.
152+
*/
153+
window.MaxExtensionFloatingPanel.saveCurrentProfileConfig = function () {
154+
if (!this.currentProfileName || !window.globalMaxExtensionConfig) {
155+
logConCgp('[floating-panel] Cannot save profile: profile name or config not available.');
156+
return;
157+
}
158+
chrome.runtime.sendMessage({
159+
type: 'saveConfig',
160+
profileName: this.currentProfileName,
161+
config: window.globalMaxExtensionConfig
162+
}, (response) => {
163+
if (chrome.runtime.lastError) {
164+
logConCgp('[floating-panel] Failed to save current profile config:', chrome.runtime.lastError.message);
165+
} else if (response && response.success) {
166+
logConCgp('[floating-panel] Current profile config saved successfully.');
167+
} else {
168+
logConCgp('[floating-panel] Failed to save current profile config. Response:', response);
169+
}
170+
});
171+
};
172+
117173
/**
118174
* Loads available profiles from the service worker.
119175
*/
@@ -184,6 +240,7 @@ window.MaxExtensionFloatingPanel.switchToProfile = function (profileName) {
184240
*/
185241
window.MaxExtensionFloatingPanel.initialize = function () {
186242
this.currentPanelSettings = { ...this.defaultPanelSettings };
243+
this.loadGlobalSettings(); // Load global settings like TOS acceptance
187244

188245
// createFloatingPanel is async. We use .then() to ensure subsequent actions
189246
// only run after the panel has been created and added to the DOM.

floating-panel-ui-queue.js

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ window.MaxExtensionFloatingPanel.initializeQueueSection = function () {
3434
this.queueDisplayArea = document.getElementById('max-extension-queue-display');
3535
this.queueProgressContainer = document.getElementById('max-extension-queue-progress-container');
3636
this.queueProgressBar = document.getElementById('max-extension-queue-progress-bar');
37+
const tosWarningContainer = document.getElementById('max-extension-queue-tos-warning');
38+
const tosAcceptButton = document.getElementById('max-extension-tos-accept-btn');
39+
const tosDeclineButton = document.getElementById('max-extension-tos-decline-btn');
3740

3841
if (!this.queueSectionElement) {
3942
logConCgp('[floating-panel-queue] Queue section element not found in the DOM.');
@@ -45,73 +48,101 @@ window.MaxExtensionFloatingPanel.initializeQueueSection = function () {
4548
event.stopPropagation();
4649
});
4750

48-
// --- DELAY INPUT AND UNIT TOGGLE LOGIC ---
49-
51+
// --- DELAY INPUT AND UNIT TOGGLE LOGIC (Profile-specific) ---
5052
const updateDelayUI = () => {
51-
const unit = globalMaxExtensionConfig.queueDelayUnit || 'min';
53+
const unit = window.globalMaxExtensionConfig.queueDelayUnit || 'min';
5254
if (unit === 'sec') {
5355
this.delayUnitToggle.textContent = 'sec';
54-
this.delayInputElement.value = globalMaxExtensionConfig.queueDelaySeconds;
56+
this.delayInputElement.value = window.globalMaxExtensionConfig.queueDelaySeconds;
5557
this.delayInputElement.title = "Delay in seconds between sending each queued prompt. Minimum 2 seconds.";
5658
} else {
5759
this.delayUnitToggle.textContent = 'min';
58-
this.delayInputElement.value = globalMaxExtensionConfig.queueDelayMinutes;
60+
this.delayInputElement.value = window.globalMaxExtensionConfig.queueDelayMinutes;
5961
this.delayInputElement.title = "Delay in minutes between sending each queued prompt. Minimum 2 minutes.";
6062
}
6163
};
62-
63-
// Set initial state from config
6464
updateDelayUI();
6565

66-
// Add listener for unit toggle
6766
this.delayUnitToggle.addEventListener('click', (event) => {
6867
event.preventDefault();
69-
globalMaxExtensionConfig.queueDelayUnit = (globalMaxExtensionConfig.queueDelayUnit === 'min') ? 'sec' : 'min';
68+
window.globalMaxExtensionConfig.queueDelayUnit = (window.globalMaxExtensionConfig.queueDelayUnit === 'min') ? 'sec' : 'min';
7069
updateDelayUI();
71-
// The config is saved when profile settings are saved.
70+
this.saveCurrentProfileConfig(); // Save to profile
7271
});
7372

74-
// Add listener for input value changes
7573
this.delayInputElement.addEventListener('change', (event) => {
7674
let delay = parseInt(event.target.value, 10);
7775
if (isNaN(delay) || delay < 2) {
7876
delay = 2;
7977
event.target.value = delay;
8078
}
8179

82-
if (globalMaxExtensionConfig.queueDelayUnit === 'sec') {
83-
globalMaxExtensionConfig.queueDelaySeconds = delay;
84-
logConCgp(`[floating-panel-queue] Queue delay set to ${delay} seconds.`);
80+
if (window.globalMaxExtensionConfig.queueDelayUnit === 'sec') {
81+
window.globalMaxExtensionConfig.queueDelaySeconds = delay;
8582
} else {
86-
globalMaxExtensionConfig.queueDelayMinutes = delay;
87-
logConCgp(`[floating-panel-queue] Queue delay set to ${delay} minutes.`);
83+
window.globalMaxExtensionConfig.queueDelayMinutes = delay;
8884
}
85+
this.saveCurrentProfileConfig(); // Save to profile
8986
});
9087

91-
// --- END DELAY LOGIC ---
88+
// --- TOS Confirmation (Global) and Queue Toggle (Profile-specific) ---
89+
const isQueueEnabled = window.globalMaxExtensionConfig.enableQueueMode || false;
90+
91+
const toggleCallback = (state) => {
92+
// Check global TOS setting first
93+
if (state && !window.MaxExtensionGlobalSettings.acceptedQueueTOS) {
94+
tosWarningContainer.style.display = 'block';
95+
this.queueModeToggle.style.display = 'none'; // Hide toggle
96+
this.queueModeToggle.querySelector('input').checked = false; // Uncheck it
97+
return;
98+
}
99+
100+
// If TOS is accepted, proceed with profile setting
101+
window.globalMaxExtensionConfig.enableQueueMode = state;
102+
expandableSection.style.display = state ? 'contents' : 'none';
103+
this.queueDisplayArea.style.display = state ? 'flex' : 'none';
104+
this.saveCurrentProfileConfig(); // Save to profile
105+
};
92106

93-
// Create and insert the Queue Mode toggle
94-
const isQueueEnabled = globalMaxExtensionConfig.enableQueueMode || false;
95107
this.queueModeToggle = MaxExtensionInterface.createToggle(
96108
'enableQueueMode',
97109
'Enable Queue Mode',
98110
isQueueEnabled,
99-
(state) => {
100-
globalMaxExtensionConfig.enableQueueMode = state;
101-
expandableSection.style.display = state ? 'contents' : 'none';
102-
this.queueDisplayArea.style.display = state ? 'flex' : 'none';
103-
}
111+
toggleCallback
104112
);
105113
this.queueModeToggle.style.margin = '0';
106114
this.queueModeToggle.querySelector('label').style.fontSize = '12px';
107115
this.queueModeToggle.title = 'When enabled, clicking buttons adds them to a queue instead of sending immediately.';
108116
togglePlaceholder.appendChild(this.queueModeToggle);
109117

110-
// Set initial visibility of controls based on config
111118
expandableSection.style.display = isQueueEnabled ? 'contents' : 'none';
112119
this.queueDisplayArea.style.display = isQueueEnabled ? 'flex' : 'none';
113120

114-
// Attach event listeners to buttons
121+
// TOS Button Listeners
122+
tosAcceptButton.addEventListener('click', () => {
123+
// 1. Update global setting
124+
window.MaxExtensionGlobalSettings.acceptedQueueTOS = true;
125+
this.saveGlobalSettings(); // Save global setting
126+
127+
// 2. Update profile setting to enable queue
128+
window.globalMaxExtensionConfig.enableQueueMode = true;
129+
this.saveCurrentProfileConfig(); // Save profile setting
130+
131+
// 3. Update UI
132+
tosWarningContainer.style.display = 'none';
133+
this.queueModeToggle.style.display = ''; // Show toggle again
134+
this.queueModeToggle.querySelector('input').checked = true;
135+
expandableSection.style.display = 'contents';
136+
this.queueDisplayArea.style.display = 'flex';
137+
});
138+
139+
tosDeclineButton.addEventListener('click', () => {
140+
tosWarningContainer.style.display = 'none';
141+
this.queueModeToggle.style.display = ''; // Show toggle again
142+
});
143+
144+
145+
// Attach event listeners to queue action buttons
115146
this.playQueueButton.addEventListener('click', () => {
116147
if (this.isQueueRunning) {
117148
this.pauseQueue();
@@ -124,7 +155,6 @@ window.MaxExtensionFloatingPanel.initializeQueueSection = function () {
124155
this.resetQueue();
125156
});
126157

127-
// Initial state update for controls
128158
this.updateQueueControlsState();
129159
};
130160

floating-panel.css

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,45 @@
128128
opacity: 0.4;
129129
}
130130

131+
/* TOS Warning Section */
132+
#max-extension-queue-tos-warning {
133+
background-color: rgba(150, 0, 0, 0.2);
134+
border: 1px solid red;
135+
border-radius: 4px;
136+
padding: 10px;
137+
margin-top: 8px;
138+
}
139+
140+
#max-extension-queue-tos-warning .warning-text {
141+
color: #ffcccc;
142+
margin: 0 0 10px 0;
143+
font-size: 12px;
144+
line-height: 1.4;
145+
}
146+
147+
#max-extension-queue-tos-warning .tos-buttons {
148+
display: flex;
149+
flex-direction: column;
150+
gap: 8px;
151+
}
152+
153+
#max-extension-queue-tos-warning .tos-buttons button {
154+
background-color: rgba(255, 255, 255, 0.1);
155+
border: 1px solid rgba(255, 255, 255, 0.3);
156+
color: white;
157+
padding: 6px;
158+
border-radius: 4px;
159+
cursor: pointer;
160+
font-size: 11px;
161+
text-align: center;
162+
width: 100%;
163+
}
164+
165+
#max-extension-queue-tos-warning .tos-buttons button:hover {
166+
background-color: rgba(255, 255, 255, 0.2);
167+
}
168+
169+
131170
#max-extension-queue-display {
132171
min-height: 30px;
133172
background-color: rgba(30, 30, 30, 0.7);

floating-panel.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,21 @@
5454
</div>
5555
</div>
5656
</div>
57+
<!-- TOS Confirmation -->
58+
<div id="max-extension-queue-tos-warning" style="display: none">
59+
<p class="warning-text">
60+
Please make sure that using this feature does not violate the Terms of
61+
Service of the website you are using it with.
62+
</p>
63+
<div class="tos-buttons">
64+
<button id="max-extension-tos-accept-btn">
65+
I have received permission from the website owner to use this feature
66+
</button>
67+
<button id="max-extension-tos-decline-btn">
68+
I have not received permission
69+
</button>
70+
</div>
71+
</div>
5772
<div
5873
id="max-extension-queue-display"
5974
title="Queued prompts. Click an icon to remove it from the queue."

floating-panel.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
'use strict';
3434

35-
// Define the namespace and shared properties.
35+
// Define the namespace for the floating panel and its properties.
3636
window.MaxExtensionFloatingPanel = {
3737
panelElement: null,
3838
isPanelVisible: false,
@@ -59,11 +59,16 @@ window.MaxExtensionFloatingPanel = {
5959
queueProgressContainer: null,
6060
queueProgressBar: null,
6161
playQueueButton: null,
62-
pauseQueueButton: null, // This might be the same as play button
6362
resetQueueButton: null,
6463
delayInputElement: null,
6564
queueModeToggle: null,
6665
QUEUE_MAX_SIZE: 10
6766
};
6867

68+
// Define a separate namespace for global, non-profile settings.
69+
window.MaxExtensionGlobalSettings = {
70+
acceptedQueueTOS: false
71+
};
72+
73+
6974
// No need to load files: they are imported in manifest.json

0 commit comments

Comments
 (0)