Skip to content

Commit

Permalink
Prepare version 1.7.0
Browse files Browse the repository at this point in the history
- Implement customization options for the popup UI (fix #7)
- Improve detection of some challenge sounds
- Clean up the code style and refactor some components
  • Loading branch information
blmage committed Jul 28, 2023
1 parent eddb5fc commit c163cfc
Show file tree
Hide file tree
Showing 21 changed files with 3,059 additions and 1,735 deletions.
371 changes: 369 additions & 2 deletions dist/assets/css/popup.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Duolingo Sound Controls",
"version": "1.6.1",
"version": "1.7.0",
"description": "Provides fine-grained sound controls for Duolingo.",
"permissions": [
"activeTab",
Expand Down
2 changes: 1 addition & 1 deletion dist/src/background.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/src/content.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/src/observer.js

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletions dist/src/popup.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
"description": "A browser extension providing fine-grained sound controls for Duolingo.",
"license": "MIT",
"author": "blmage",
"version": "1.6.1",
"version": "1.7.0",
"homepage": "https://github.com/blmage/duolingo-sound-controls",
"scripts": {
"build": "rollup -c --environment production",
"build-debug": "rollup -c --environment development",
"watch-debug": "rollup -c --environment development --watch",
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
Expand Down
3 changes: 0 additions & 3 deletions src/.babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
"pragma": "h",
"pragmaFrag": "Fragment"
}
],
[
"@babel/plugin-transform-react-jsx-source"
]
]
}
92 changes: 78 additions & 14 deletions src/background.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,66 @@
import ChromeStorage from 'chrome-storage-promise';
import { isObject } from 'duo-toolbox/utils/functions';
import { isArray, isObject } from 'duo-toolbox/utils/functions';
import { registerPopupActivationListeners } from 'duo-toolbox/extension/background';
import { onActionRequest, sendBackgroundEventNotificationToPageScript } from 'duo-toolbox/extension/ipc';

import {
ACTION_TYPE_GET_CURRENT_PROFILE,
ACTION_TYPE_UPDATE_CURRENT_PROFILE,
ACTION_TYPE_GET_READ_MESSAGES,
ACTION_TYPE_MARK_MESSAGE_AS_READ,
ACTION_TYPE_UPDATE_CURRENT_PROFILE_CUSTOMIZATION_OPTIONS,
ACTION_TYPE_UPDATE_CURRENT_PROFILE_SOUND_SETTINGS,
BACKGROUND_EVENT_TYPE_CURRENT_PROFILE_CHANGED,
} from './ipc';

import {
applyUpdateToConfig,
applyCustomizationOptionsUpdateToConfig,
applySoundSettingsUpdateToConfig,
DEFAULT_CONFIGURATION,
DEFAULT_PROFILE_ID,
isValidUpdateRequest,
isValidCustomizationOptionsUpdateRequest,
isValidSoundSettingsUpdateRequest,
} from './profiles';

/**
* @type {string}
*/
const STORAGE_KEY_PROFILES = 'profiles';

/**
* @type {string}
*/
const STORAGE_KEY_READ_MESSAGES = 'readMessages';

/**
* @param {Function} sendResult A function usable to send back the read messages.
* @returns {Promise<void>} A promise for when the request has been handled.
*/
const handleReadMessagesRequest = async sendResult => {
const readMessages = (await ChromeStorage.sync.get(STORAGE_KEY_READ_MESSAGES))[STORAGE_KEY_READ_MESSAGES] || []

sendResult(isArray(readMessages) ? readMessages : []);
};

/**
* @param {string} messageId The ID of the message to mark as read.
* @param {Function} sendResult A function usable to notify the success of the update.
* @returns {Promise<void>} A promise for when the request has been handled.
*/
const handleReadMessageFlagRequest = async (messageId, sendResult) => {
let readMessages = (await ChromeStorage.sync.get(STORAGE_KEY_READ_MESSAGES))[STORAGE_KEY_READ_MESSAGES] || []

if (!isArray(readMessages)) {
readMessages = [];
}

if (!readMessages.includes(messageId)) {
readMessages.push(messageId);
await ChromeStorage.sync.set({ [STORAGE_KEY_READ_MESSAGES]: readMessages });
}

sendResult(true);
};

/**
* @param {Function} sendResult A function usable to send back the current profile configuration.
* @returns {Promise<void>} A promise for when the request has been handled.
Expand All @@ -32,19 +72,16 @@ const handleCurrentProfileRequest = async sendResult => {
};

/**
* @param {Object} data The new configuration data of the current profile.
* @param {Object} data New configuration data for the current profile.
* @param {Function} sendResult A function usable to notify the success of the update.
* @param {Function} updateProfile A function usable to update the current profile based on the update request.
* @returns {Promise<void>} A promise for when the request has been handled.
*/
const handleProfileUpdateRequest = async (data, sendResult) => {
if (
isObject(data)
&& isObject(data.updateRequest)
&& isValidUpdateRequest(data.updateRequest)
) {
const handleProfileUpdateRequest = async (data, sendResult, updateProfile) => {
if (isObject(data) && isObject(data.updateRequest)) {
const profiles = (await ChromeStorage.sync.get(STORAGE_KEY_PROFILES))[STORAGE_KEY_PROFILES] || {};

profiles[DEFAULT_PROFILE_ID] = applyUpdateToConfig(
profiles[DEFAULT_PROFILE_ID] = updateProfile(
profiles[DEFAULT_PROFILE_ID] || DEFAULT_CONFIGURATION,
data.updateRequest
);
Expand All @@ -62,11 +99,38 @@ const handleProfileUpdateRequest = async (data, sendResult) => {

onActionRequest(async (action, data, sender, sendResult) => {
switch (action) {
case ACTION_TYPE_GET_READ_MESSAGES:
await handleReadMessagesRequest(sendResult);
break;
case ACTION_TYPE_MARK_MESSAGE_AS_READ:
await handleReadMessageFlagRequest(data, sendResult);
break;
case ACTION_TYPE_GET_CURRENT_PROFILE:
await handleCurrentProfileRequest(sendResult);
break;
case ACTION_TYPE_UPDATE_CURRENT_PROFILE:
await handleProfileUpdateRequest(data, sendResult);
case ACTION_TYPE_UPDATE_CURRENT_PROFILE_SOUND_SETTINGS:
await handleProfileUpdateRequest(
data,
sendResult,
(profile, request) => (
!isValidSoundSettingsUpdateRequest(request)
? profile
: applySoundSettingsUpdateToConfig(profile, request)
)
);

break;
case ACTION_TYPE_UPDATE_CURRENT_PROFILE_CUSTOMIZATION_OPTIONS:
await handleProfileUpdateRequest(
data,
sendResult,
(profile, request) => (
!isValidCustomizationOptionsUpdateRequest(request)
? profile
: applyCustomizationOptionsUpdateToConfig(profile, request)
)
);

break;
}
});
Expand Down
9 changes: 9 additions & 0 deletions src/components/Accordion.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ import classNames from 'classnames';
import { Accordion as BaseAccordion } from 'primereact/accordion';

export class Accordion extends BaseAccordion {
isSelected(index) {
// Also account for "onUncontrolledTabChange" which does not exist in the base component.
const activeIndex = (this.props.onTabChange || this.props.onUncontrolledTabChange)
? this.props.activeIndex
: this.state.activeIndex;

return this.props.multiple ? (activeIndex && activeIndex.includes(index)) : (activeIndex === index);
}

onTabHeaderClick(event, tab, index) {
if (!tab.props.disabled) {
const selected = this.isSelected(index);
Expand Down
Loading

0 comments on commit c163cfc

Please sign in to comment.