From d4347232447ff78f546eb4ce22e9a7bcb068e268 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Sat, 9 Jan 2021 13:14:39 +0000 Subject: [PATCH] Desktop: Add way to install plugin from file --- .../gui/ConfigScreen/ConfigScreen.tsx | 20 +++++ .../controls/plugins/PluginBox.tsx | 1 + .../controls/plugins/PluginsStates.tsx | 76 ++++++++++--------- .../controls/plugins/SearchPlugins.tsx | 3 +- 4 files changed, 65 insertions(+), 35 deletions(-) diff --git a/packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx b/packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx index caf790c9b..f1e893bdf 100644 --- a/packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx +++ b/packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx @@ -50,6 +50,7 @@ class ConfigScreenComponent extends React.Component { this.onApplyClick = this.onApplyClick.bind(this); this.renderLabel = this.renderLabel.bind(this); this.renderDescription = this.renderDescription.bind(this); + this.renderHeader = this.renderHeader.bind(this); } async checkSyncConfig_() { @@ -304,6 +305,24 @@ class ConfigScreenComponent extends React.Component { ); } + private renderHeader(themeId: number, label: string) { + const theme = themeStyle(themeId); + + const labelStyle = Object.assign({}, theme.textStyle, { + display: 'block', + color: theme.color, + fontSize: theme.fontSize * 1.25, + fontWeight: 500, + marginBottom: theme.mainPadding, + }); + + return ( +
+ +
+ ); + } + private renderDescription(themeId: number, description: string) { return description ?
{description}
: null; } @@ -384,6 +403,7 @@ class ConfigScreenComponent extends React.Component { }} renderLabel={this.renderLabel} renderDescription={this.renderDescription} + renderHeader={this.renderHeader} /> ); diff --git a/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.tsx b/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.tsx index 372799c4d..05e4bf664 100644 --- a/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.tsx +++ b/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.tsx @@ -43,6 +43,7 @@ export interface PluginItem { const CellRoot = styled.div` display: flex; + box-sizing: border-box; background-color: ${props => props.theme.backgroundColor}; flex-direction: column; align-items: flex-start; diff --git a/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.tsx b/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.tsx index fb8b253ac..b7364e2b2 100644 --- a/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.tsx +++ b/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.tsx @@ -5,13 +5,15 @@ import { _ } from '@joplin/lib/locale'; import styled from 'styled-components'; import SearchPlugins from './SearchPlugins'; import PluginBox from './PluginBox'; -// import Button, { ButtonLevel } from '../../../Button/Button'; +import Button, { ButtonLevel } from '../../../Button/Button'; import bridge from '../../../../services/bridge'; import produce from 'immer'; import { OnChangeEvent } from '../../../lib/SearchInput/SearchInput'; import { PluginItem } from './PluginBox'; const { space } = require('styled-system'); +const maxWidth: number = 250; + const Root = styled.div` display: flex; flex-direction: column; @@ -23,7 +25,9 @@ const UserPluginsRoot = styled.div` flex-wrap: wrap; `; -// const InstallButton = styled(Button)``; +const ToolsButton = styled(Button)` + margin-right: 2px; +`; interface Props { value: any; @@ -31,6 +35,7 @@ interface Props { onChange: Function; renderLabel: Function; renderDescription: Function; + renderHeader: Function; } function usePluginItems(plugins: Plugins, settings: PluginSettings): PluginItem[] { @@ -96,22 +101,34 @@ export default function(props: Props) { props.onChange({ value: pluginService.serializePluginSettings(newSettings) }); }, [pluginSettings, props.onChange]); - // const onInstall = useCallback(async () => { - // const result = bridge().showOpenDialog({ - // filters: [{ name: 'Joplin Plugin Archive', extensions: ['jpl'] }], - // }); + const onInstall = useCallback(async () => { + const result = bridge().showOpenDialog({ + filters: [{ name: 'Joplin Plugin Archive', extensions: ['jpl'] }], + }); - // const filePath = result && result.length ? result[0] : null; - // if (!filePath) return; + const filePath = result && result.length ? result[0] : null; + if (!filePath) return; - // const plugin = await pluginService.installPlugin(filePath); + const plugin = await pluginService.installPlugin(filePath); - // const newSettings = produce(pluginSettings, (draft: PluginSettings) => { - // draft[plugin.manifest.id] = defaultPluginSetting(); - // }); + const newSettings = produce(pluginSettings, (draft: PluginSettings) => { + draft[plugin.manifest.id] = defaultPluginSetting(); + }); - // props.onChange({ value: pluginService.serializePluginSettings(newSettings) }); - // }, [pluginSettings, props.onChange]); + props.onChange({ value: pluginService.serializePluginSettings(newSettings) }); + }, [pluginSettings, props.onChange]); + + const onToolsClick = useCallback(async () => { + const template = []; + + template.push({ + label: _('Install from file'), + click: onInstall, + }); + + const menu = bridge().Menu.buildFromTemplate(template); + menu.popup(bridge().window()); + }, [onInstall]); const onSearchQueryChange = useCallback((event: OnChangeEvent) => { setSearchQuery(event.value); @@ -157,28 +174,14 @@ export default function(props: Props) { } } - function renderInstallFromFile(): any { - return null; - - // Disabled for now since there are already options for developments, - // and installing from file can be done by dropping the file in /plugins - - // return ( - //
- // {props.renderLabel(props.themeId, _('Install plugin from file'))} - // - //
- //
- // ); - } - const pluginItems = usePluginItems(pluginService.plugins, pluginSettings); return (
- {props.renderLabel(props.themeId, _('Search for plugins'))} + {props.renderHeader(props.themeId, _('Search for plugins'))}
- {props.renderLabel(props.themeId, _('Manage your plugins'))} - {renderUserPlugins(pluginItems)} - - {renderInstallFromFile()} +
+
+
+ {props.renderHeader(props.themeId, _('Manage your plugins'))} +
+ +
+ {renderUserPlugins(pluginItems)} +
); } diff --git a/packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.tsx b/packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.tsx index aff7eab23..4e1332225 100644 --- a/packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.tsx +++ b/packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.tsx @@ -26,6 +26,7 @@ interface Props { pluginSettings: PluginSettings; onPluginSettingsChange(event: any): void; renderDescription: Function; + maxWidth: number; } let repoApi_: RepositoryApi = null; @@ -99,7 +100,7 @@ export default function(props: Props) { return ( -
+