Skip to content

Commit

Permalink
Added default settings
Browse files Browse the repository at this point in the history
Signed-off-by: Mehmet Baker <mehmet@mehmetbaker.dev>
  • Loading branch information
mehmetb committed Nov 11, 2023
1 parent 24e9897 commit 1136bfa
Show file tree
Hide file tree
Showing 8 changed files with 290 additions and 61 deletions.
100 changes: 71 additions & 29 deletions background.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2020-2021 Mehmet Baker
* Copyright 2020-2023 Mehmet Baker
*
* This file is part of dimmer.
*
Expand All @@ -23,70 +23,79 @@
* @typedef {object} TabState
* @property {boolean} isDimmed
* @property {number} opacity A number [0, 1]
* @property {boolean} [overrideGlobalState] If true, popup option 'Only for this tab' will be checked.
* @property {boolean} [applySettingsToCurrentTab] If true, popup option 'Apply settings to this tab only' will be checked.
*/

const defaultSettings = {
applyToAllTabs: true,
};

const initialState = {
isDimmed: false,
opacity: 0.7,
};

/**
* This state represents the state of all tabs that haven't selected 'Only this tab' option.
* This state is the state of tabs that checked 'Apply settings to all tabs' option.
*/
const globalState = {
isDimmed: false,
opacity: 0.7,
...initialState,
};

/**
* These states represent the states of tabs that checked the 'Only this tab' option.
* Keys are tab ids and values are dim states.
* These states are of tabs that checked the 'Apply settings to this tab only' option.
* Keys are tab ids and values are states.
* @type {Map<number, TabState>}
*/
const overriddenStates = new Map();
const localStateTabs = new Map();

const globalStateTabs = new Set();

/**
* Returns a tab state. If the option 'Only for this tab' is selected for the tab,
* then the overridden state will be returned. Otherwise the global state will be
* returned.
* Returns a tab's state.
* @param {number} tabId Tab ID
* @returns {TabState}
*/
function getState(tabId) {
if (overriddenStates.has(tabId)) {
if (localStateTabs.has(tabId)) {
return {
...overriddenStates.get(tabId),
overrideGlobalState: true,
...localStateTabs.get(tabId),
applySettingsToCurrentTab: true,
};
}

return globalState;
}

/**
* Adds/updates the overridden states
* @param {number} tabId Tab ID.
* @param {*} params Prop(s) of TabState
* @param {{ isDimmed?: boolean, opacity?: number }} params Prop(s) of TabState
*/
function extendState(tabId, params = {}) {
const state = getState(tabId);
overriddenStates.set(tabId, {
localStateTabs.set(tabId, {
...state,
...params,
});
}

/**
* Updates the state object in background script. Also updates the states of content
* Updates the state object in the background script. Also updates the states of content
* scripts by sending them set-state commands.
* @param {number} tabId Tab ID
* @param {string|null} stateProp A property key of TabState
* @param {('isDimmed'|'opacity')|null} stateProp A property key of TabState
* @param {boolean|number} [propValue] A prop value of TabState
* @returns {Promise<void>}
*/
async function setState(tabId, stateProp, propValue) {
// If 'Only for this tab' option is selected, update the current tab only
if (overriddenStates.has(tabId)) {
// If 'Apply settings to this tab only' option is selected, update the current tab only
if (localStateTabs.has(tabId)) {
const state = getState(tabId);

if (stateProp !== null) {
state[stateProp] = propValue;
overriddenStates.set(tabId, state);
localStateTabs.set(tabId, state);
}

await browser.tabs.sendMessage(tabId, {
Expand All @@ -98,11 +107,12 @@ async function setState(tabId, stateProp, propValue) {
opacity: state.opacity,
},
});

return;
}

// If 'Only for this tab' is NOT selected, then update all tabs but the overriddens.

// If 'Apply settings to all tabs' option is checked then update all the other tabs
// that checked 'Apply settings to all tabs' option as well.
if (stateProp !== null) {
globalState[stateProp] = propValue;
}
Expand All @@ -120,7 +130,7 @@ async function setState(tabId, stateProp, propValue) {
};

for (const tab of allTabs) {
const isOverridden = overriddenStates.has(tab.id);
const isOverridden = localStateTabs.has(tab.id);
if (!isOverridden) {
const promise = browser.tabs.sendMessage(tab.id, command);
promises.push(promise);
Expand Down Expand Up @@ -180,7 +190,18 @@ async function handleMessage(message, sender) {

switch (message.command) {
case 'query': {
return getState(activeTab.id);
if (!localStateTabs.has(activeTab.id) && !globalStateTabs.has(activeTab.id)) {
if (defaultSettings.applyToAllTabs) {
globalStateTabs.add(activeTab.id);
} else {
localStateTabs.set(activeTab.id, { ...initialState });
}
}

return {
state: getState(activeTab.id),
defaultSettings,
};
}

case 'dim': {
Expand All @@ -196,24 +217,45 @@ async function handleMessage(message, sender) {
return setState(activeTab.id, 'opacity', message.data.opacity);
}

case 'override-global-state': {
case 'apply-settings-to-current-tab-only': {
globalStateTabs.delete(activeTab.id);
extendState(activeTab.id);
return Promise.resolve();
}

case 'remove-state-override': {
overriddenStates.delete(activeTab.id);
case 'apply-settings-to-all-tabs': {
// get the current state of the tab
const tabState = localStateTabs.get(activeTab.id);

if (tabState) {
// update global state settings to match the current tab's state
globalState.isDimmed = tabState.isDimmed;
globalState.opacity = tabState.opacity;
}

// remove the current tab from the ovveriden map so it can get global state changes in the future
localStateTabs.delete(activeTab.id);
globalStateTabs.add(activeTab.id);

// calling `setState` with `null` will cause all tabs that don't choose 'Apply settings to this tab only' to get
// the latest gloabl state
return setState(activeTab.id, null);
}

case 'update-default-settings': {
defaultSettings.applyToAllTabs = message.data.applyToAllTabs;
return Promise.resolve({ defaultSettings, message });
}

default: {
return Promise.resolve();
}
}
}

function handleTabRemove(tabId) {
overriddenStates.delete(tabId);
localStateTabs.delete(tabId);
globalStateTabs.delete(tabId);
}

browser.commands.onCommand.addListener(handleCommand);
Expand Down
9 changes: 5 additions & 4 deletions content_scripts/overlay.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2020-2021 Mehmet Baker
* Copyright 2020-2023 Mehmet Baker
*
* This file is part of dimmer.
*
Expand Down Expand Up @@ -76,8 +76,9 @@

switch (message.command) {
case 'set-state': {
state.opacity = message.data.opacity;

if (state.isDimmed) {
state.opacity = message.data.opacity;
state.container.style.opacity = state.opacity;
}

Expand All @@ -103,8 +104,8 @@
to: 'background',
});

state.isDimmed = !!response.isDimmed;
state.opacity = String(response.opacity) || '0';
state.isDimmed = !!response.state.isDimmed;
state.opacity = String(response.state.opacity) || '0';
state.container.style.opacity = state.isDimmed ? state.opacity : '0';

setTimeout(() => {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"main": "index.js",
"scripts": {
"build": "web-ext build --overwrite-dest -i package.json README.md yarn.lock dark-mode demo.gif _config.yml",
"dev": "env-cmd -x web-ext run --verbose -u https://mehmetbaker.dev --firefox-profile=\"\\$DARK_MODE_PROFILE\"",
"dev-dark": "env-cmd -x web-ext run --verbose -u https://mehmetbaker.dev --firefox-profile=\"\\$LIGHT_MODE_PROFILE\"",
"dev": "env-cmd -x --use-shell web-ext run -u https://wikipedia.com --verbose --firefox-profile=\"\\$LIGHT_MODE_PROFILE\"",
"dev-dark": "env-cmd -x web-ext run --verbose -u https://wikipedia.com --firefox-profile=\"\\$DARK_MODE_PROFILE\"",
"lint": "eslint content_scripts/*.js popup/*.js background.js",
"lint-fix": "eslint --fix content_scripts/*.js popup/*.js background.js",
"test": "echo \"Error: no test specified\" && exit 1"
Expand Down
4 changes: 4 additions & 0 deletions popup/back-24.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 51 additions & 0 deletions popup/popup.css
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,54 @@ button.default:hover {
button.default:hover:active {
background-color: rgba(0, 0, 0, 0.1);
}

.panel-formElements-item.checkbox-panel, .panel-formElements-item.checkbox-panel label {
display: block;
}

.panel-formElements-item.checkbox-panel input {
margin-top: 10px;
}

div.settings {
background-color: #676774ab;
mask: url(./settings-24.svg) no-repeat center;
width: 24px;
height: 24px;
padding-bottom: 0;
margin-bottom: 0;
position: absolute;
top: 5px;
right: 5px;
}

div.settings:hover {
cursor: pointer;
background-color: #676774;
}

div.back {
color: #676774ab;
position: absolute;
top: 5px;
left: 14px;
display: flex;
align-items: center;
}

div.back-icon {
display: inline-block;
background-color: #676774ab;
mask: url(./back-24.svg) no-repeat center;
width: 24px;
height: 24px;
}

div.back:hover {
cursor: pointer;
color: #676774;
}

div.back:hover div.back-icon {
background-color: #676774;
}
Loading

0 comments on commit 1136bfa

Please sign in to comment.