refactor Settings

This commit is contained in:
Jeremie Pardou-Piquemal 2022-12-15 22:52:54 +01:00
parent c9fa5599b4
commit 7eb31f13e3
3 changed files with 192 additions and 171 deletions

View File

@ -1,4 +1,3 @@
import React from 'react';
import { render, fireEvent, waitFor } from '@testing-library/react'; import { render, fireEvent, waitFor } from '@testing-library/react';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { describe, it, expect, vi } from 'vitest'; import { describe, it, expect, vi } from 'vitest';
@ -9,10 +8,6 @@ import Settings from '.';
const store = configureStore(); const store = configureStore();
const mockTranslations = {
sound: 'soundCheck',
};
vi.useFakeTimers(); vi.useFakeTimers();
vi.mock('@/components/RoomLink'); vi.mock('@/components/RoomLink');
@ -39,11 +34,14 @@ describe('Settings component', () => {
<Settings <Settings
soundIsEnabled={true} soundIsEnabled={true}
toggleSoundEnabled={() => {}} toggleSoundEnabled={() => {}}
persistenceIsEnabled={true}
togglePersistenceEnabled={() => {}}
notificationIsEnabled={true} notificationIsEnabled={true}
toggleNotificationEnabled={() => {}} toggleNotificationEnabled={() => {}}
toggleNotificationAllowed={vi.fn()} toggleNotificationAllowed={vi.fn()}
roomId="roomId" roomId="roomId"
setLanguage={() => {}} setLanguage={() => {}}
language="en"
translations={{}} translations={{}}
/> />
</Provider>, </Provider>,
@ -56,12 +54,15 @@ describe('Settings component', () => {
<Settings <Settings
soundIsEnabled={true} soundIsEnabled={true}
toggleSoundEnabled={() => {}} toggleSoundEnabled={() => {}}
persistenceIsEnabled={true}
togglePersistenceEnabled={() => {}}
notificationIsEnabled={true} notificationIsEnabled={true}
notificationIsAllowed={false} notificationIsAllowed={false}
toggleNotificationEnabled={() => {}} toggleNotificationEnabled={() => {}}
toggleNotificationAllowed={vi.fn()} toggleNotificationAllowed={vi.fn()}
roomId="roomId" roomId="roomId"
setLanguage={() => {}} setLanguage={() => {}}
language="en"
translations={{}} translations={{}}
/> />
</Provider>, </Provider>,
@ -77,18 +78,20 @@ describe('Settings component', () => {
<Settings <Settings
soundIsEnabled={true} soundIsEnabled={true}
toggleSoundEnabled={toggleSound} toggleSoundEnabled={toggleSound}
persistenceIsEnabled={true}
togglePersistenceEnabled={() => {}}
notificationIsEnabled={true} notificationIsEnabled={true}
notificationIsAllowed={true} notificationIsAllowed={true}
toggleNotificationEnabled={() => {}} toggleNotificationEnabled={() => {}}
toggleNotificationAllowed={vi.fn()} toggleNotificationAllowed={vi.fn()}
roomId="roomId" roomId="roomId"
setLanguage={() => {}} setLanguage={() => {}}
language="en"
translations={{}} translations={{}}
/> />
</Provider>, </Provider>,
); );
//console.log(getAllByText(mockTranslations.sound)[1]);
fireEvent.click(getByText('Sound')); fireEvent.click(getByText('Sound'));
expect(toggleSound).toHaveBeenCalledWith(false); expect(toggleSound).toHaveBeenCalledWith(false);
@ -105,12 +108,15 @@ describe('Settings component', () => {
<Settings <Settings
soundIsEnabled={true} soundIsEnabled={true}
toggleSoundEnabled={() => {}} toggleSoundEnabled={() => {}}
persistenceIsEnabled={true}
togglePersistenceEnabled={() => {}}
notificationIsEnabled={true} notificationIsEnabled={true}
notificationIsAllowed={true} notificationIsAllowed={true}
toggleNotificationEnabled={toggleNotifications} toggleNotificationEnabled={toggleNotifications}
toggleNotificationAllowed={vi.fn()} toggleNotificationAllowed={vi.fn()}
roomId="roomId" roomId="roomId"
setLanguage={() => {}} setLanguage={() => {}}
language="en"
translations={{}} translations={{}}
/> />
</Provider>, </Provider>,
@ -137,12 +143,15 @@ describe('Settings component', () => {
<Settings <Settings
soundIsEnabled={true} soundIsEnabled={true}
toggleSoundEnabled={() => {}} toggleSoundEnabled={() => {}}
persistenceIsEnabled={true}
togglePersistenceEnabled={() => {}}
notificationIsEnabled={true} notificationIsEnabled={true}
notificationIsAllowed={true} notificationIsAllowed={true}
toggleNotificationEnabled={toggleNotifications} toggleNotificationEnabled={toggleNotifications}
toggleNotificationAllowed={toggleAllowed} toggleNotificationAllowed={toggleAllowed}
roomId="roomId" roomId="roomId"
setLanguage={() => {}} setLanguage={() => {}}
language="en"
translations={{}} translations={{}}
/> />
</Provider>, </Provider>,
@ -166,11 +175,14 @@ describe('Settings component', () => {
<Settings <Settings
soundIsEnabled={true} soundIsEnabled={true}
toggleSoundEnabled={() => {}} toggleSoundEnabled={() => {}}
persistenceIsEnabled={true}
togglePersistenceEnabled={() => {}}
notificationIsEnabled={true} notificationIsEnabled={true}
toggleNotificationEnabled={() => {}} toggleNotificationEnabled={() => {}}
toggleNotificationAllowed={vi.fn()} toggleNotificationAllowed={vi.fn()}
roomId="roomId" roomId="roomId"
setLanguage={changeLang} setLanguage={changeLang}
language="en"
translations={{}} translations={{}}
/> />
</Provider>, </Provider>,

View File

@ -50,6 +50,7 @@ exports[`Settings component > should display 1`] = `
for="persistence-control" for="persistence-control"
> >
<input <input
checked=""
class="form-check-input" class="form-check-input"
id="persistence-control" id="persistence-control"
type="checkbox" type="checkbox"
@ -261,6 +262,7 @@ exports[`Settings component > should display 2`] = `
for="persistence-control" for="persistence-control"
> >
<input <input
checked=""
class="form-check-input" class="form-check-input"
id="persistence-control" id="persistence-control"
type="checkbox" type="checkbox"

View File

@ -1,4 +1,3 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import RoomLink from '@/components/RoomLink'; import RoomLink from '@/components/RoomLink';
@ -6,193 +5,201 @@ import T from '@/components/T';
import classes from './styles.module.scss'; import classes from './styles.module.scss';
class Settings extends Component { const Settings = ({
handleSoundToggle() { soundIsEnabled,
this.props.toggleSoundEnabled(!this.props.soundIsEnabled); persistenceIsEnabled,
} toggleSoundEnabled,
notificationIsEnabled,
notificationIsAllowed,
toggleNotificationEnabled,
toggleNotificationAllowed,
togglePersistenceEnabled,
roomId,
setLanguage,
language,
translations,
}) => {
const handleSoundToggle = () => {
toggleSoundEnabled(!soundIsEnabled);
};
handlePersistenceToggle() { const handlePersistenceToggle = () => {
this.props.togglePersistenceEnabled(!this.props.persistenceIsEnabled); togglePersistenceEnabled(!persistenceIsEnabled);
} };
handleNotificationToggle() { const handleNotificationToggle = () => {
Notification.requestPermission().then(permission => { Notification.requestPermission().then(permission => {
if (permission === 'granted') { if (permission === 'granted') {
this.props.toggleNotificationEnabled(!this.props.notificationIsEnabled); toggleNotificationEnabled(!notificationIsEnabled);
this.props.toggleNotificationAllowed(true); toggleNotificationAllowed(true);
} }
if (permission === 'denied') { if (permission === 'denied') {
this.props.toggleNotificationAllowed(false); toggleNotificationAllowed(false);
} }
}); });
} };
handleLanguageChange(evt) { const handleLanguageChange = evt => {
const language = evt.target.value; setLanguage(evt.target.value);
this.props.setLanguage(language); };
}
render() { return (
return ( <div className={classes.styles}>
<div className={classes.styles}> <section>
<section> <h4>
<h4> <T path="newMessageNotification" />
<T path="newMessageNotification" /> </h4>
</h4> <form>
<form> <div className="form-check">
<div className="form-check"> <label className="form-check-label" htmlFor="sound-control">
<label className="form-check-label" htmlFor="sound-control"> <input
<input id="sound-control"
id="sound-control" onChange={handleSoundToggle}
onChange={this.handleSoundToggle.bind(this)} className="form-check-input"
className="form-check-input" type="checkbox"
type="checkbox" checked={soundIsEnabled}
checked={this.props.soundIsEnabled} />
/> <T path="sound" />
<T path="sound" /> </label>
</label>
</div>
<div className="form-check">
<label className="form-check-label" htmlFor="notif-control">
{this.props.notificationIsAllowed !== false && (
<>
<input
id="notif-control"
onChange={this.handleNotificationToggle.bind(this)}
className="form-check-input"
type="checkbox"
checked={this.props.notificationIsEnabled}
disabled={this.props.notificationIsAllowed === false} // Important to keep '=== false' here
/>
<T path="desktopNotification" />
</>
)}
{this.props.notificationIsAllowed === false && <T path="desktopNotificationBlocked" />}
</label>
</div>
<div className="form-check">
<label className="form-check-label" htmlFor="persistence-control">
<input
id="persistence-control"
onChange={this.handlePersistenceToggle.bind(this)}
className="form-check-input"
type="checkbox"
checked={this.props.persistenceIsEnabled}
/>
<T path="persistence" />
</label>
</div>
</form>
</section>
<section>
<h4 className="mb-3">
<T path="copyRoomHeader" />
</h4>
<RoomLink roomId={this.props.roomId} translations={this.props.translations} />
</section>
<section>
<h4 className="mb-3">
<T path="languageDropdownHeader" />
</h4>
<p>
<a
href="https://github.com/darkwire/darkwire.io/blob/master/client/README.md#translations"
rel="noopener noreferrer"
target="_blank"
>
<T path="helpTranslate" />
</a>
</p>
<div className="form-group">
<select
value={this.props.language}
className="form-control"
onChange={this.handleLanguageChange.bind(this)}
>
<option value="en">English</option>
<option value="fr">Français</option>
<option value="oc">Occitan</option>
<option value="de">Deutsch</option>
<option value="esAR">Español (Argentina)</option>
<option value="nl">Nederlands</option>
<option value="it">Italiano</option>
<option value="ru">Русский</option>
<option value="pl">Polish</option>
<option value="zhCN">中文</option>
<option value="ja">日本語</option>
<option value="tr">Türkçe</option>
<option value="ko">한국어</option>
</select>
</div> </div>
</section> <div className="form-check">
<label className="form-check-label" htmlFor="notif-control">
{notificationIsAllowed !== false && (
<>
<input
id="notif-control"
onChange={handleNotificationToggle}
className="form-check-input"
type="checkbox"
checked={notificationIsEnabled}
disabled={notificationIsAllowed === false} // Important to keep '=== false' here
/>
<T path="desktopNotification" />
</>
)}
{notificationIsAllowed === false && <T path="desktopNotificationBlocked" />}
</label>
</div>
<div className="form-check">
<label className="form-check-label" htmlFor="persistence-control">
<input
id="persistence-control"
onChange={handlePersistenceToggle}
className="form-check-input"
type="checkbox"
checked={persistenceIsEnabled}
/>
<T path="persistence" />
</label>
</div>
</form>
</section>
<section> <section>
<h4> <h4 className="mb-3">
<T path="roomOwnerHeader" /> <T path="copyRoomHeader" />
</h4> </h4>
<p> <RoomLink roomId={roomId} translations={translations} />
<T path="roomOwnerText" /> </section>
</p>
</section> <section>
<section> <h4 className="mb-3">
<h4> <T path="languageDropdownHeader" />
<T path="lockRoomHeader" /> </h4>
</h4> <p>
<p> <a
<T path="lockRoomText" /> href="https://github.com/darkwire/darkwire.io/blob/master/client/README.md#translations"
</p> rel="noopener noreferrer"
</section> target="_blank"
<section> >
<h4> <T path="helpTranslate" />
<T path="slashCommandsHeader" /> </a>
</h4> </p>
<p> <div className="form-group">
<T path="slashCommandsText" /> <select value={language} className="form-control" onChange={handleLanguageChange}>
</p> <option value="en">English</option>
<ul> <option value="fr">Français</option>
<li> <option value="oc">Occitan</option>
/nick [username]{' '} <option value="de">Deutsch</option>
<span className="text-muted"> <option value="esAR">Español (Argentina)</option>
<T path="slashCommandsBullets.0" /> <option value="nl">Nederlands</option>
</span> <option value="it">Italiano</option>
</li> <option value="ru">Русский</option>
<li> <option value="pl">Polish</option>
/me [action]{' '} <option value="zhCN">中文</option>
<span className="text-muted"> <option value="ja">日本語</option>
<T path="slashCommandsBullets.1" /> <option value="tr">Türkçe</option>
</span> <option value="ko">한국어</option>
</li> </select>
<li> </div>
/clear{' '} </section>
<span className="text-muted">
<T path="slashCommandsBullets.2" /> <section>
</span> <h4>
</li> <T path="roomOwnerHeader" />
<li> </h4>
/help{' '} <p>
<span className="text-muted"> <T path="roomOwnerText" />
<T path="slashCommandsBullets.3" /> </p>
</span> </section>
</li> <section>
</ul> <h4>
</section> <T path="lockRoomHeader" />
</div> </h4>
); <p>
} <T path="lockRoomText" />
} </p>
</section>
<section>
<h4>
<T path="slashCommandsHeader" />
</h4>
<p>
<T path="slashCommandsText" />
</p>
<ul>
<li>
/nick [username]{' '}
<span className="text-muted">
<T path="slashCommandsBullets.0" />
</span>
</li>
<li>
/me [action]{' '}
<span className="text-muted">
<T path="slashCommandsBullets.1" />
</span>
</li>
<li>
/clear{' '}
<span className="text-muted">
<T path="slashCommandsBullets.2" />
</span>
</li>
<li>
/help{' '}
<span className="text-muted">
<T path="slashCommandsBullets.3" />
</span>
</li>
</ul>
</section>
</div>
);
};
Settings.propTypes = { Settings.propTypes = {
soundIsEnabled: PropTypes.bool.isRequired, soundIsEnabled: PropTypes.bool.isRequired,
persistenceIsEnabled: PropTypes.bool.isRequired, persistenceIsEnabled: PropTypes.bool.isRequired,
toggleSoundEnabled: PropTypes.func.isRequired, toggleSoundEnabled: PropTypes.func.isRequired,
togglePersistenceEnabled: PropTypes.func.isRequired,
notificationIsEnabled: PropTypes.bool.isRequired, notificationIsEnabled: PropTypes.bool.isRequired,
notificationIsAllowed: PropTypes.bool, notificationIsAllowed: PropTypes.bool,
toggleNotificationEnabled: PropTypes.func.isRequired, toggleNotificationEnabled: PropTypes.func.isRequired,
toggleNotificationAllowed: PropTypes.func.isRequired, toggleNotificationAllowed: PropTypes.func.isRequired,
roomId: PropTypes.string.isRequired, roomId: PropTypes.string.isRequired,
setLanguage: PropTypes.func.isRequired, setLanguage: PropTypes.func.isRequired,
language: PropTypes.string.isRequired,
translations: PropTypes.object.isRequired, translations: PropTypes.object.isRequired,
}; };