Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-1967 Themes Panel Update #510

Merged
merged 7 commits into from Apr 14, 2020
@@ -1817,8 +1817,17 @@
"subscribe_pitch_sign_in": {
"message": "Already subscribed? Sign in"
},
"subscription_midnight_theme": {
"message": "Midnight Theme"
"subscription_default_theme": {
"message": "Default"
},
"subscription_dark_blue_theme": {
"message": "Dark Blue Theme"
},
"subscription_palm_theme": {
"message": "Palm Theme"
},
"subscription_leaf_theme": {
"message": "Leaf Theme"
},
"subscription_status": {
"message": "Status"
@@ -0,0 +1,6 @@
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(1)" fill="none" fill-rule="evenodd">
<circle stroke="#2092bf" cx="7" cy="8" r="7"/>
<path d="M5.86 4.756c0-.582.326-.873.974-.873.648 0 .973.29.973.873 0 .277-.08.493-.244.647-.162.155-.405.232-.73.232-.647 0-.972-.293-.972-.88zM7.726 13H5.938V6.45h1.787V13z" fill="#2092bf"/>
</g>
</svg>
@@ -0,0 +1,46 @@
/**
* Radio Button Component
*
* Ghostery Browser Extension
* https://www.ghostery.com/
*
* Copyright 2019 Ghostery, Inc. All rights reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/

/* eslint jsx-a11y/label-has-associated-control: 0 */

import React from 'react';
import PropTypes from 'prop-types';
import ClassNames from 'classnames';

/**
* @class Implements a single radio button to be used inside the RadioButtonGroup component
* @memberof PanelBuildingBlocks
*/

const RadioButton = (props) => {
const OuterCircleClassNames = ClassNames('RadioButton__outerCircle', {
checked: props.checked,
});
const InnerCircleClassNames = ClassNames('RadioButton__innerCircle', {
checked: props.checked,
});
return (
<span>
<span className={OuterCircleClassNames} onClick={props.handleClick}>
<span className={InnerCircleClassNames} />
</span>
</span>
);
};

// PropTypes ensure we pass required props of the correct type
RadioButton.propTypes = {
handleClick: PropTypes.func.isRequired,
};

export default RadioButton;
@@ -0,0 +1,51 @@
/**
* Radio Button Group Component
*
* Ghostery Browser Extension
* https://www.ghostery.com/
*
* Copyright 2019 Ghostery, Inc. All rights reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/

/* eslint jsx-a11y/label-has-associated-control: 0 */

import React from 'react';
import PropTypes from 'prop-types';
import RadioButton from './RadioButton';

/**
* @class Implements a radio button group
* @memberof PanelBuildingBlocks
*/
const RadioButtonGroup = (props) => {
const { indexClicked, handleItemClick } = props;
return (
props.items.map((item, index) => (
<div className="flex-container align-justify RadioButtonGroup__container" key={`${index * 2}`}>
<span className="RadioButtonGroup__label">
{t(item.text)}
</span>
<div>
<RadioButton
checked={index === indexClicked}
handleClick={() => handleItemClick(index)}
/>
</div>
</div>
))
);
};

// PropTypes ensure we pass required props of the correct type
RadioButtonGroup.propTypes = {
items: PropTypes.arrayOf(PropTypes.object).isRequired, // Number of objects in array is the number of radio buttons
handleItemClick: PropTypes.func.isRequired,
indexClicked: PropTypes.number.isRequired
};


export default RadioButtonGroup;
@@ -21,6 +21,8 @@ import GhosteryFeature from './GhosteryFeature';
import NotScanned from './NotScanned';
import PauseButton from './PauseButton';
import ToggleSlider from './ToggleSlider';
import RadioButtonGroup from './RadioButtonGroup';
import RadioButton from './RadioButton';
import ModalExitButton from './ModalExitButton';

export {
@@ -31,5 +33,7 @@ export {
NotScanned,
PauseButton,
ToggleSlider,
RadioButtonGroup,
RadioButton,
ModalExitButton
};
@@ -28,7 +28,9 @@ import PrioritySupport from './Subscription/PrioritySupport';
class Subscription extends React.Component {
constructor(props) {
super(props);
this.state = { isChecked: (props.current_theme !== 'default') };
this.state = {
theme: this.props.current_theme
};
}

/**
@@ -75,18 +77,16 @@ class Subscription extends React.Component {
return { loading: true };
}

toggleThemes = () => {
const newChecked = !this.state.isChecked;
this.setState({ isChecked: newChecked });
const updated_theme = newChecked ? 'midnight-theme' : 'default';
changeTheme = (updated_theme) => {
this.setState({ theme: updated_theme });
this.props.actions.getTheme(updated_theme).then(() => {
sendMessage('ping', 'theme_change');
});
}

SubscriptionInfoComponent = () => (<SubscriptionInfo subscriptionData={this.parseSubscriptionData()} />);

SubscriptionThemesComponent = () => (<SubscriptionThemes isChecked={this.state.isChecked} toggleThemes={this.toggleThemes} />);
SubscriptionThemesComponent = () => (<SubscriptionThemes theme={this.state.theme} changeTheme={this.changeTheme} />);

PrioritySupportComponent = () => (<PrioritySupport />);

@@ -74,7 +74,7 @@ const SubscriptionInfo = (props) => {
</div>
<div className="list-row">
<ul>
<li className="list-item">{t('subscription_midnight_theme')}</li>
<li className="list-item">{t('subscription_dark_blue_theme')}</li>
<li className="list-item">{t('historical_stats')}</li>
<li className="list-item">{t('priority_support')}</li>
</ul>
@@ -12,36 +12,68 @@
*/

import React from 'react';
import { ToggleSlider } from '../BuildingBlocks';
import PropTypes from 'prop-types';
import { RadioButtonGroup } from '../BuildingBlocks';

/**
* @class Implement Themes subview as a React component.
* The view opens from the left-side menu of the main Subscription view.
* It allows to switch between available Ghostery themes. Right now it handles just one theme. Hence - slider.
* It allows to switch between available Ghostery themes.
* @memberOf SettingsComponents
*/
const SubscriptionThemes = props => (
<div className="content-subscription s-tabs-panel">
<div className="row">
<div className="columns column-subscription">
<h1>{ t('subscription_themes_title') }</h1>
<div>
<span className="flex-container align-middle themes-slider-container">
<span className="themes-slider-label">
{t('subscription_midnight_theme')}
</span>
<ToggleSlider
className="themes-slider"
isChecked={props.isChecked}
onChange={props.toggleThemes}
/>
<div className="s-tooltip-down" data-g-tooltip={t('subscription_themes_tooltip')}>
<img src="../../app/images/panel/icon-information-tooltip.svg" className="s-question" />
</div>
*/
const SubscriptionThemes = (props) => {
const themes = [
{
name: 'default',
text: 'subscription_default_theme',
},
{
name: 'midnight-theme',
text: 'subscription_dark_blue_theme',
},
{
name: 'palm',
text: 'subscription_palm_theme',
},
{
name: 'leaf',
text: 'subscription_leaf_theme',
}
];

const getIndexClicked = () => {
const index = themes.findIndex(theme => theme.name === props.theme);
return index;
};

const handleThemeClick = (index) => {
const theme = themes[index];
props.changeTheme(theme.name);
};

return (
<div className="content-subscription s-tabs-panel">
<div className="row">
<div className="columns column-subscription">
<h1 className="subscription-title">{t('subscription_themes_title')}</h1>
<span className="tooltip-icon s-tooltip-down-right" data-g-tooltip={t('subscription_themes_tooltip')}>
<img src="../../app/images/panel/icon-information-tooltip-blue.svg" className="s-question" />
</span>
<RadioButtonGroup
items={themes}
handleItemClick={handleThemeClick}
indexClicked={getIndexClicked(props.theme)}
/>
</div>
</div>
</div>
</div>
);
);
};

// PropTypes ensure we pass required props of the correct type
SubscriptionThemes.propTypes = {
changeTheme: PropTypes.func.isRequired,
theme: PropTypes.string.isRequired,
};

export default SubscriptionThemes;
@@ -65,6 +65,7 @@ html body {
@import './partials/_account';
@import './partials/_drawer';
@import './partials/_toggle_slider';
@import './partials/_radio_button';
@import './partials/_pause_button';
@import './partials/_donut_graph';
@import './partials/_ghostery_feature';
@@ -0,0 +1,42 @@
/**
* Radio Button Sass
*
* Ghostery Browser Extension
* https://www.ghostery.com/
*
* Copyright 2019 Ghostery, Inc. All rights reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/

.RadioButtonGroup__label {
margin-right: 10px;
font-weight: bolder;
}
.RadioButtonGroup__container {
margin: 16px 0;
width: 138px;
}
.RadioButton__outerCircle {
border: 1px solid #4a4a4a;
height: 16px;
width: 16px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
&.checked {
border: 2px solid #2092bf;
}
}
.RadioButton__innerCircle {
&.checked {
height: 8px;
width: 8px;
background-color: #2092bf;
border-radius: 50%;
}
}
@@ -5,7 +5,7 @@
* https://www.ghostery.com/
*
* Copyright 2019 Ghostery, Inc. All rights reserved.
*
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0
@@ -58,7 +58,6 @@
text-align: left;
}
}

.s-tab-title {
font-weight: 400;
font-size: 18px;
@@ -195,12 +194,11 @@
line-height: 1.4;
}
img.s-question {
top: -5px;
width: 14px;
width: 16px;
height: auto;
cursor: default;
vertical-align: top;
opacity: 1.0;
margin: -6px 0 0 10px;
}
.s-option-group {
margin-bottom: 12px;
@@ -279,7 +277,7 @@
border-color: #CCCCCC;
background-size: 8px 5px;
-moz-appearance: none;
-webkit-appearance:none;
-webkit-appearance: none;
}
}
#select-file {
@@ -458,4 +456,4 @@
.blocking-trackers {
margin-left: 25px;
}
}
}
@@ -83,17 +83,16 @@
-webkit-font-smoothing: antialiased;
text-align: left;
}
.themes-slider-label {
@extend .field-label;
padding-right: 20px !important;
}
.themes-slider-container {
padding-top: 10px !important;
}
.column-subscription {
padding-left: 30px !important;
padding-right: 30px !important;
}
.subscription-title {
display: inline;
}
.tooltip-icon {
margin-left: 5px !important;
}
.status-label {
@extend .field-label;
padding-right: 7px !important;
ProTip! Use n and p to navigate between commits in a pull request.