feat(plugins): Move uninstall from theme picker to plugins tab

Summary: Move uninstall functionality to the plugins tab in preferences.

Test Plan: Tested locally.

Reviewers: bengotow, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D2716
This commit is contained in:
Jackie Luo 2016-03-10 14:10:48 -08:00
parent f12896d54f
commit 4d7f515090
10 changed files with 29 additions and 81 deletions

View file

@ -22,7 +22,7 @@ class Package extends React.Component
if @props.package.installed
if @props.package.category in ['user' ,'dev', 'example']
if @props.package.category in ['user' ,'dev', 'example'] and not @props.package.theme
if @props.package.enabled
actions.push <Switch onChange={@_onDisablePackage} checked=true>Disable</Switch>
else

View file

@ -140,7 +140,6 @@ PackagesStore = Reflux.createStore
_onPackagesChanged: ->
@_apm.getInstalled().then (packages) =>
for category in ['dev', 'user']
packages[category] = packages[category].filter ({theme}) -> not theme
packages[category].forEach (pkg) =>
pkg.category = category
delete @_installing[pkg.name]

View file

@ -2,7 +2,7 @@ import React from 'react';
import fs from 'fs-plus';
import path from 'path';
import {EventedIFrame, RetinaImg} from 'nylas-component-kit';
import {EventedIFrame} from 'nylas-component-kit';
import LessCompileCache from '../../../src/less-compile-cache'
@ -11,7 +11,6 @@ class ThemeOption extends React.Component {
theme: React.PropTypes.object.isRequired,
active: React.PropTypes.bool.isRequired,
onSelect: React.PropTypes.func.isRequired,
onUninstall: React.PropTypes.func.isRequired,
}
constructor(props) {
@ -95,25 +94,15 @@ class ThemeOption extends React.Component {
}
render() {
const uninstallButton = this.props.theme.path.indexOf("/n1/internal_packages") === -1 ? (
<RetinaImg
className="theme-uninstall-x"
name="uninstall-x.png"
mode={RetinaImg.Mode.ContentDark}
style={{width: "14", height: "14"}}
onMouseDown={this.props.onUninstall} />) : null;
return (
<div>
{uninstallButton}
<div className="clickable-theme-option" onMouseDown={this.props.onSelect}>
<EventedIFrame
ref="iframe"
className={`theme-preview-${this.props.theme.name}`}
frameBorder="0"
width="105px"
height="65px"
flex="1" />
</div>
<div className="clickable-theme-option" onMouseDown={this.props.onSelect}>
<EventedIFrame
ref="iframe"
className={`theme-preview-${this.props.theme.name}`}
frameBorder="0"
width="105px"
height="65px"
flex="1" />
</div>
);
}

View file

@ -1,12 +0,0 @@
/** @babel */
import Reflux from 'reflux';
ThemePickerActions = Reflux.createActions([
"uninstallTheme",
]);
for (key in ThemePickerActions) {
ThemePickerActions[key].sync = true;
}
export default ThemePickerActions;

View file

@ -1,10 +1,8 @@
import React from 'react';
import Actions from '../../../src/flux/actions';
import NylasStore from 'nylas-store';
import {APMWrapper} from 'nylas-exports';
import ThemePicker from './theme-picker';
import ThemePickerActions from './theme-picker-actions';
class ThemePickerStore extends NylasStore {
@ -14,8 +12,6 @@ class ThemePickerStore extends NylasStore {
}
activate = ()=> {
this._apm = new APMWrapper();
this.unlisten = ThemePickerActions.uninstallTheme.listen(this.uninstallTheme);
this.disposable = NylasEnv.commands.add("body", "window:launch-theme-picker", () => {
Actions.openModal({
component: (<ThemePicker />),
@ -25,16 +21,7 @@ class ThemePickerStore extends NylasStore {
});
}
uninstallTheme = (theme)=> {
if (NylasEnv.packages.isPackageLoaded(theme.name)) {
NylasEnv.packages.disablePackage(theme.name);
NylasEnv.packages.unloadPackage(theme.name);
}
this._apm.uninstall(theme);
}
deactivate = ()=> {
this.unlisten();
this.disposable.dispose();
}

View file

@ -2,7 +2,6 @@ import React from 'react';
import Actions from '../../../src/flux/actions'
import {Flexbox, RetinaImg} from 'nylas-component-kit';
import ThemePickerActions from './theme-picker-actions';
import ThemeOption from './theme-option';
@ -47,19 +46,13 @@ class ThemePicker extends React.Component {
activeElement.className = "theme-option active-true";
}
_onUninstallTheme(theme) {
ThemePickerActions.uninstallTheme(theme);
this.setState({themes: this.themes.getLoadedThemes()});
}
_renderThemeOptions() {
return this.state.themes.map((theme) =>
<ThemeOption
key={theme.name}
theme={theme}
active={this.state.activeTheme === theme.name}
onSelect={() => this._setActiveTheme(theme.name)}
onUninstall={() => this._onUninstallTheme(theme)} />
onSelect={() => this._setActiveTheme(theme.name)} />
);
}
@ -80,6 +73,9 @@ class ThemePicker extends React.Component {
height="auto"
style={{alignItems: "flex-start", flexWrap: "wrap"}}>
{this._renderThemeOptions()}
<div className="create-theme">
<a href="https://github.com/nylas/N1-theme-starter">Create a Theme</a>
</div>
</Flexbox>
</div>
</Flexbox>

View file

@ -7,13 +7,10 @@ import ThemePicker from '../lib/theme-picker';
const {resourcePath} = NylasEnv.getLoadSettings();
const light = new ThemePackage(resourcePath + '/internal_packages/ui-light');
const dark = new ThemePackage(resourcePath + '/internal_packages/ui-dark');
const thirdPartyTheme = new ThemePackage(resourcePath + '/internal_packages/ui-light');
thirdPartyTheme.name = 'third-party-theme'
thirdPartyTheme.path = ''
describe('ThemePicker', ()=> {
beforeEach(()=> {
spyOn(NylasEnv.themes, 'getLoadedThemes').andReturn([light, dark, thirdPartyTheme]);
spyOn(NylasEnv.themes, 'getLoadedThemes').andReturn([light, dark]);
spyOn(NylasEnv.themes, 'getActiveTheme').andReturn(light);
this.component = ReactTestUtils.renderIntoDocument(<ThemePicker />);
});
@ -25,13 +22,4 @@ describe('ThemePicker', ()=> {
ReactTestUtils.Simulate.mouseDown(themeOption);
expect(ThemePicker.prototype._setActiveTheme).toHaveBeenCalled();
});
it('uninstalls themes on click', ()=> {
spyOn(ThemePicker.prototype, '_onUninstallTheme').andCallThrough();
spyOn(ThemePicker.prototype, 'setState').andCallThrough();
const uninstallButton = React.findDOMNode(ReactTestUtils.scryRenderedDOMComponentsWithClass(this.component, 'theme-uninstall-x')[0]);
ReactTestUtils.Simulate.mouseDown(uninstallButton);
expect(ThemePicker.prototype._onUninstallTheme).toHaveBeenCalled();
expect(ThemePicker.prototype.setState).toHaveBeenCalled();
});
});

View file

@ -3,23 +3,24 @@
.theme-picker {
text-align: center;
cursor: default;
iframe {
pointer-events: none;
position: relative;
z-index: 0;
}
.theme-uninstall-x {
float: right;
position: relative;
z-index: 1;
margin-bottom: -40px;
margin-right: 10px;
-webkit-filter: none;
.create-theme {
width: 100%;
text-align: center;
margin-bottom: 5px;
a {
color: #3187e1;
text-decoration: none;
cursor: default;
}
}
.clickable-theme-option {
cursor: pointer;
width: 115px;
margin: 2px;
top: -10px;
iframe {
pointer-events: none;
position: relative;
z-index: 0;
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB