Skip to content

Commit

Permalink
Merge pull request #10 from hemit-s/jat-26
Browse files Browse the repository at this point in the history
JAT-26 Alter number of frequency bands
  • Loading branch information
xenown authored Jun 28, 2022
2 parents d30174a + 6723cec commit 843c9a4
Show file tree
Hide file tree
Showing 16 changed files with 327 additions and 39 deletions.
5 changes: 5 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ module.exports = {
'import/no-unresolved': 'error',
// Since React 17 and typescript 4.1 you can safely disable the rule
'react/react-in-jsx-scope': 'off',
// According to this:
// https://stackoverflow.com/questions/47774695/react-functional-component-default-props-vs-default-parameters
// defaultProps is going to be deprecated and we should turn off this rule.
'react/require-default-props': 'off',
'no-await-in-loop': 'off',
curly: ['error', 'all'],
},
parserOptions: {
Expand Down
2 changes: 1 addition & 1 deletion release/app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "aqua",
"version": "0.0.3",
"version": "0.0.4",
"description": "An audio equalizer app",
"license": "MIT",
"author": {
Expand Down
3 changes: 0 additions & 3 deletions src/__tests__/cucumber_tests/shared_steps/aquaSlider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ export const whenSetFrequencyGain = (
async (frequency: number, position: string) => {
const sliderElems = await webdriver.driver.$('.mainContent').$$('.range');
for (let i = 0; i < sliderElems.length; i += 1) {
// eslint-disable-next-line no-await-in-loop
const element = await sliderElems[i].$('input');
// eslint-disable-next-line no-await-in-loop
const name = await element.getAttribute('name');
if (name === `${frequency}-gain-range`) {
const coord = { x: 0, y: 0 };
Expand All @@ -23,7 +21,6 @@ export const whenSetFrequencyGain = (
}
element.dragAndDrop(coord);
// wait 1000 ms for the action.
// eslint-disable-next-line no-await-in-loop
await new Promise((resolve) => setTimeout(resolve, 1000));
return;
}
Expand Down
4 changes: 0 additions & 4 deletions src/__tests__/cucumber_tests/shared_steps/peace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export const givenPeaceIsRunning = (given: DefineStepFunction) => {
return;
}
// Wait 1s before trying again
// eslint-disable-next-line no-await-in-loop
await new Promise((resolve) => setTimeout(resolve, 1000));
}
throw new Error('Peace not running');
Expand All @@ -44,12 +43,9 @@ export const thenPeaceFrequencyGain = (
async (gain: string, frequency: string) => {
const sliderElems = await webdriver.driver.$('.mainContent').$$('.range');
for (let i = 0; i < sliderElems.length; i += 1) {
// eslint-disable-next-line no-await-in-loop
const element = await sliderElems[i].$('input');
// eslint-disable-next-line no-await-in-loop
const name = await element.getAttribute('name');
if (name === `${frequency}-gain-range`) {
// eslint-disable-next-line no-await-in-loop
const peaceHWnd = getPeaceWindowHandle();
if (!isPeaceRunning(peaceHWnd)) {
throw new Error('Peace is not running.');
Expand Down
6 changes: 6 additions & 0 deletions src/common/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export enum ErrorCode {
PEACE_NOT_RUNNING = 2,
PEACE_NOT_READY = 3,
PEACE_TIMEOUT = 4,
NEGATIVE_FREQUENCY = 5,
}

export type ErrorDescription = {
Expand Down Expand Up @@ -40,6 +41,11 @@ export const errors: Record<ErrorCode, ErrorDescription> = {
'Please restart the application. If the error persists, try reaching out to the developers to resolve the issue.',
code: ErrorCode.PEACE_TIMEOUT,
},
[ErrorCode.NEGATIVE_FREQUENCY]: {
shortError: 'Invalid frequency - frequency is negative',
action: '',
code: ErrorCode.NEGATIVE_FREQUENCY,
},
};

export const getErrorDescription = (code: ErrorCode) => errors[code];
32 changes: 32 additions & 0 deletions src/renderer/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import './styles/Button.scss';

interface IButtonProps {
children: JSX.Element | string;
ariaLabel: string;
isDisabled: boolean;
className?: string;
handleChange: () => void;
}

const Button = ({
children,
ariaLabel,
isDisabled,
className = '',
handleChange,
}: IButtonProps) => {
return (
<div
role="button"
aria-label={ariaLabel}
className={`button ${className}`}
onMouseUp={handleChange}
tabIndex={isDisabled ? -1 : 0}
aria-disabled={isDisabled}
>
{children}
</div>
);
};

export default Button;
113 changes: 108 additions & 5 deletions src/renderer/MainContent.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,98 @@
import { ErrorDescription } from 'common/errors';
import { useContext, useEffect, useState } from 'react';
import {
addEqualizerSlider,
closePeaceWindow,
getEqualizerSliderCount,
getProgramState,
removeEqualizerSlider,
showPeaceWindow,
} from './equalizerApi';
import FrequencyBand from './FrequencyBand';
import MinusIcon from './icons/MinusIcon';
import PlusIcon from './icons/PlusIcon';
import Button from './Button';
import { PeaceFoundContext } from './PeaceFoundContext';
import './styles/MainContent.scss';

const MainContent = () => {
const NUM_SLIDERS = 10;
// const FREQS = [32, 64, 125, 250, 500, 1000, 2000, 4000, 8000, 16000];
const { peaceError, setPeaceError } = useContext(PeaceFoundContext);
const [sliderIndicies, setSliderIndicies] = useState<number[]>([]);

const sliderIndicies = Array(NUM_SLIDERS)
.fill(0)
.map((_, i) => i + 1);
useEffect(() => {
const fetchResults = async () => {
try {
const sliderCount = await getEqualizerSliderCount();
const newIndices = Array(sliderCount)
.fill(0)
.map((_, i) => i + 1);
setSliderIndicies(newIndices);
} catch (e) {
setPeaceError(e as ErrorDescription);
}
};
if (!peaceError) {
fetchResults();
}
}, [peaceError, setPeaceError]);

const retryHelper = async (attempts: number, f: () => any) => {
for (let i = 0; i < attempts; i += 1) {
try {
await f();
return;
} catch (e) {
if (i === attempts) {
setPeaceError(e as ErrorDescription);
return;
}
await new Promise((resolve) => {
setTimeout(resolve, 500);
});
}
}
};

const onAddEqualizerSlider = async () => {
try {
await addEqualizerSlider();
} catch (e) {
setPeaceError(e as ErrorDescription);
return;
}
const addSlider = async () => {
await getProgramState();
await showPeaceWindow();
const newIndices = [...sliderIndicies];
newIndices.push(sliderIndicies.length + 1);
setSliderIndicies(newIndices);
};

retryHelper(5, addSlider);

try {
await closePeaceWindow();
// Ignore if we can't close peace window
// eslint-disable-next-line no-empty
} catch (e) {}
};

const onRemoveEqualizerSlider = async () => {
try {
await removeEqualizerSlider();
} catch (e) {
setPeaceError(e as ErrorDescription);
return;
}

const removeSlider = async () => {
await getProgramState();
const newIndices = [...sliderIndicies];
newIndices.pop();
setSliderIndicies(newIndices);
};
retryHelper(5, removeSlider);
};

return (
<div className="row center mainContent">
Expand All @@ -30,6 +115,24 @@ const MainContent = () => {
key={`slider-${sliderIndex}`}
/>
))}
<div className="col sliderButtons">
<Button
ariaLabel="Add Equalizer Slider"
isDisabled={false}
className="sliderButton"
handleChange={onAddEqualizerSlider}
>
<PlusIcon />
</Button>
<Button
ariaLabel="Remove Equalizer Slider"
isDisabled={false}
className="sliderButton"
handleChange={onRemoveEqualizerSlider}
>
<MinusIcon />
</Button>
</div>
</>
)}
</div>
Expand Down
19 changes: 15 additions & 4 deletions src/renderer/PrereqMissingModal.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Button from './Button';
import './styles/Modal.scss';

interface IPrereqMissingModalProps {
Expand Down Expand Up @@ -27,12 +28,22 @@ export default function PrereqMissingModal({
</p>
</div>
<div className="footer row">
<button type="button" disabled={isLoading} onClick={onRetry}>
<Button
ariaLabel="Retry"
isDisabled={isLoading}
className="small"
handleChange={onRetry}
>
Retry
</button>
<button type="button" disabled={isLoading} onClick={handleClose}>
</Button>
<Button
ariaLabel="Close"
isDisabled={isLoading}
className="small"
handleChange={handleClose}
>
Close
</button>
</Button>
</div>
</div>
</div>
Expand Down
87 changes: 81 additions & 6 deletions src/renderer/equalizerApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,15 @@ export const getFrequency = (index: number): Promise<number> => {
0,
]);

const responseHandler = buildResponseHandler<number>((result, resolve) => {
resolve(peaceFrequencyOutputToNormal(result));
});
const responseHandler = buildResponseHandler<number>(
(result, resolve, reject) => {
if (result > 22050) {
reject(getErrorDescription(ErrorCode.NEGATIVE_FREQUENCY));
return;
}
resolve(peaceFrequencyOutputToNormal(result));
}
);
return promisifyResult(responseHandler, channel);
};

Expand Down Expand Up @@ -206,7 +212,7 @@ export const enableEqualizer = (): Promise<void> => {
const responseHandler = buildResponseHandler<void>(
(result, resolve, reject) => {
if (result !== 1) {
reject(getErrorDescription(0));
reject(getErrorDescription(ErrorCode.PEACE_UNKNOWN_ERROR));
}
resolve();
}
Expand All @@ -224,7 +230,7 @@ export const disableEqualizer = (): Promise<void> => {
const responseHandler = buildResponseHandler<void>(
(result, resolve, reject) => {
if (result !== 2) {
reject(getErrorDescription(0));
reject(getErrorDescription(ErrorCode.PEACE_UNKNOWN_ERROR));
}
resolve();
}
Expand All @@ -247,8 +253,77 @@ export const getEqualizerStatus = (): Promise<boolean> => {
} else if (result === 2) {
resolve(false);
} else {
reject(getErrorDescription(0));
reject(getErrorDescription(ErrorCode.PEACE_UNKNOWN_ERROR));
}
}
);
return promisifyResult(responseHandler, channel);
};

/**
* Get number of equalizer bands
* @returns { Promise<number> } exception if failed
*/
export const getEqualizerSliderCount = (): Promise<number> => {
const channel = 'getEqualizerSliderCount';
window.electron.ipcRenderer.sendMessage('peace', [channel, 22, 13]);
const responseHandler = buildResponseHandler<number>((result, resolve) => {
resolve(result);
});
return promisifyResult(responseHandler, channel);
};

/**
* Add another slider
* @returns { Promise<void> } exception if failed
*/
export const addEqualizerSlider = (): Promise<void> => {
const channel = 'addEqualizerSlider';
window.electron.ipcRenderer.sendMessage('peace', [channel, 22, 14]);
return promisifyResult(setterResponseHandler, channel);
};

/**
* Remove rightmost slider
* @returns { Promise<void> } exception if failed
*/
export const removeEqualizerSlider = (): Promise<void> => {
const channel = 'removeEqualizerSlider';
window.electron.ipcRenderer.sendMessage('peace', [channel, 22, 15]);
return promisifyResult(setterResponseHandler, channel);
};

/**
* Show Peace window
* @returns { Promise<void> } exception if failed
*/
export const showPeaceWindow = (): Promise<void> => {
const channel = 'showPeaceWindow';
window.electron.ipcRenderer.sendMessage('peace', [channel, 1, 0]);
const responseHandler = buildResponseHandler<void>(
(result, resolve, reject) => {
if (result !== 2) {
reject(getErrorDescription(ErrorCode.PEACE_UNKNOWN_ERROR));
}
resolve();
}
);
return promisifyResult(responseHandler, channel);
};

/**
* Close Peace window
* @returns { Promise<void> } exception if failed
*/
export const closePeaceWindow = (): Promise<void> => {
const channel = 'closePeaceWindow';
window.electron.ipcRenderer.sendMessage('peace', [channel, 1, 1]);
const responseHandler = buildResponseHandler<void>(
(result, resolve, reject) => {
if (result !== 1) {
reject(getErrorDescription(ErrorCode.PEACE_UNKNOWN_ERROR));
}
resolve();
}
);
return promisifyResult(responseHandler, channel);
Expand Down
Loading

0 comments on commit 843c9a4

Please sign in to comment.