From 1514c3e7fe538e61f329452b78b2ac708fe717c5 Mon Sep 17 00:00:00 2001 From: EnixCoda Date: Sun, 22 Sep 2019 12:41:59 +0800 Subject: [PATCH] feat: intelligent toggle --- src/components/SettingsBar.tsx | 56 +++++++++++++++++++++++----------- src/components/SideBar.tsx | 16 ++++++---- src/content.less | 4 +++ src/driver/core/SideBar.ts | 36 +++++++++++++++++----- src/utils/configHelper.ts | 7 +++-- src/utils/storageHelper.ts | 1 - 6 files changed, 87 insertions(+), 33 deletions(-) diff --git a/src/components/SettingsBar.tsx b/src/components/SettingsBar.tsx index 036fbaa..4c09ccc 100644 --- a/src/components/SettingsBar.tsx +++ b/src/components/SettingsBar.tsx @@ -1,17 +1,17 @@ import Icon from 'components/Icon' import * as React from 'react' -import configHelper, { configKeys } from 'utils/configHelper' +import configHelper, { Config, configKeys } from 'utils/configHelper' import { friendlyFormatShortcut, JSONRequest, parseURLSearch } from 'utils/general' import keyHelper from 'utils/keyHelper' import { version } from '../../package.json' +const WIKI_HOME_LINK = 'https://github.com/EnixCoda/Gitako/wiki' const wikiLinks = { - compressSingletonFolder: 'https://github.com/EnixCoda/Gitako/wiki/Compress-Singleton-Folder', - changeLog: 'https://github.com/EnixCoda/Gitako/wiki/Change-Log', - copyFileButton: 'https://github.com/EnixCoda/Gitako/wiki/Copy-file-and-snippet', - copySnippet: 'https://github.com/EnixCoda/Gitako/wiki/Copy-file-and-snippet', - createAccessToken: - 'https://github.com/EnixCoda/Gitako/wiki/How-to-create-access-token-for-Gitako%3F', + compressSingletonFolder: `${WIKI_HOME_LINK}/Compress-Singleton-Folder`, + changeLog: `${WIKI_HOME_LINK}/Change-Log`, + copyFileButton: `${WIKI_HOME_LINK}/Copy-file-and-snippet`, + copySnippet: `${WIKI_HOME_LINK}/Copy-file-and-snippet`, + createAccessToken: `${WIKI_HOME_LINK}/How-to-create-access-token-for-Gitako%3F`, } const oauth = { @@ -26,15 +26,16 @@ type Props = { activated: boolean onAccessTokenChange: (accessToken: string) => void onShortcutChange: (shortcut: string) => void - compressSingletonFolder: boolean - copyFileButton: boolean - copySnippetButton: boolean setCopyFile: (copyFileButton: Props['copyFileButton']) => void setCopySnippet: (copySnippetButton: Props['copySnippetButton']) => void setCompressSingleton: (compressSingletonFolder: Props['compressSingletonFolder']) => void + setIntelligentToggle: (intelligentToggle: Props['intelligentToggle']) => void toggleShowSettings: () => void toggleShowSideBarShortcut?: string -} +} & Pick< + Config, + 'compressSingletonFolder' | 'copyFileButton' | 'copySnippetButton' | 'intelligentToggle' +> type State = { accessToken?: string @@ -47,7 +48,8 @@ type State = { label: string onChange: (e: React.FormEvent) => Promise | void getValue: () => boolean - wikiLink: string + wikiLink?: string + description?: string }[] } @@ -71,14 +73,14 @@ export default class SettingsBar extends React.PureComponent { }, { key: 'copy-file', - label: 'Copy File', + label: 'Copy File Shortcut', onChange: this.createOnToggleChecked(configKeys.copyFileButton, this.props.setCopyFile), getValue: () => this.props.copyFileButton, wikiLink: wikiLinks.copyFileButton, }, { key: 'copy-snippet', - label: 'Copy Snippet', + label: 'Copy Snippet Shortcut', onChange: this.createOnToggleChecked( configKeys.copySnippetButton, this.props.setCopySnippet, @@ -86,6 +88,18 @@ export default class SettingsBar extends React.PureComponent { getValue: () => this.props.copySnippetButton, wikiLink: wikiLinks.copySnippet, }, + { + key: 'intelligent-toggle', + label: 'Intelligent Toggle', + onChange: async (e: React.FormEvent) => { + const { checked } = e.currentTarget + const intelligentToggle = checked ? null : true + await configHelper.setOne(configKeys.intelligentToggle, intelligentToggle) + this.props.setIntelligentToggle(intelligentToggle) + }, + getValue: () => this.props.intelligentToggle === null, + description: `Gitako will open/close automatically according to page content when this is enabled.`, + }, ], } @@ -300,9 +314,17 @@ export default class SettingsBar extends React.PureComponent { checked={option.getValue()} />  {option.label}  - - (?) - + {option.wikiLink ? ( + + (?) + + ) : ( + option.description && ( + + (?) + + ) + )}
diff --git a/src/components/SideBar.tsx b/src/components/SideBar.tsx index 5066416..781ac8d 100644 --- a/src/components/SideBar.tsx +++ b/src/components/SideBar.tsx @@ -1,14 +1,14 @@ -import * as React from 'react' -import { SideBar as SideBarCore } from 'driver/core' -import connect from 'driver/connect' import FileExplorer from 'components/FileExplorer' -import ToggleShowButton from 'components/ToggleShowButton' import MetaBar from 'components/MetaBar' -import SettingsBar from 'components/SettingsBar' import Portal from 'components/Portal' import Resizable from 'components/Resizable' -import cx from 'utils/cx' +import SettingsBar from 'components/SettingsBar' +import ToggleShowButton from 'components/ToggleShowButton' +import connect from 'driver/connect' +import { SideBar as SideBarCore } from 'driver/core' import { ConnectorState } from 'driver/core/SideBar' +import * as React from 'react' +import cx from 'utils/cx' export type Props = {} @@ -100,6 +100,7 @@ class Gitako extends React.PureComponent { compressSingletonFolder, copyFileButton, copySnippetButton, + intelligentToggle, toggleShowSideBarShortcut, logoContainerElement, toggleShowSideBar, @@ -109,6 +110,7 @@ class Gitako extends React.PureComponent { setCompressSingleton, setCopyFile, setCopySnippet, + setIntelligentToggle, } = this.props return (
@@ -132,9 +134,11 @@ class Gitako extends React.PureComponent { compressSingletonFolder={compressSingletonFolder} copyFileButton={copyFileButton} copySnippetButton={copySnippetButton} + intelligentToggle={intelligentToggle} setCompressSingleton={setCompressSingleton} setCopyFile={setCopyFile} setCopySnippet={setCopySnippet} + setIntelligentToggle={setIntelligentToggle} />
diff --git a/src/content.less b/src/content.less index dac3872..195ac4c 100644 --- a/src/content.less +++ b/src/content.less @@ -409,6 +409,10 @@ } &-section { padding-bottom: 16px; + + .description:hover { + cursor: help; + } } /* inputs for access token & shortcut were too wide */ diff --git a/src/driver/core/SideBar.ts b/src/driver/core/SideBar.ts index c75dace..d738340 100644 --- a/src/driver/core/SideBar.ts +++ b/src/driver/core/SideBar.ts @@ -1,6 +1,6 @@ import { Props } from 'components/SideBar' import { GetCreatedMethod, MethodCreator } from 'driver/connect' -import configHelper, { Config } from 'utils/configHelper' +import configHelper, { Config, configKeys } from 'utils/configHelper' import DOMHelper from 'utils/DOMHelper' import GitHubHelper, { API_RATE_LIMIT, @@ -42,13 +42,14 @@ export type ConnectorState = { setCopyFile: GetCreatedMethod setCopySnippet: GetCreatedMethod setCompressSingleton: GetCreatedMethod + setIntelligentToggle: GetCreatedMethod } & { baseSize: number toggleShowSideBarShortcut?: string accessToken?: string } & Pick< Config, - 'compressSingletonFolder' | 'copyFileButton' | 'copySnippetButton' | 'sideBarOpenStatus' + 'compressSingletonFolder' | 'copyFileButton' | 'copySnippetButton' | 'intelligentToggle' > type BoundMethodCreator = MethodCreator @@ -88,6 +89,7 @@ const init: BoundMethodCreator = dispatch => async () => { compressSingletonFolder, copyFileButton, copySnippetButton, + intelligentToggle, } = await configHelper.getAll() DOMHelper.decorateGitHubPageContent({ copyFileButton, copySnippetButton }) dispatch.set({ @@ -97,6 +99,7 @@ const init: BoundMethodCreator = dispatch => async () => { compressSingletonFolder, copyFileButton, copySnippetButton, + intelligentToggle, }) if (!metaData.branchName || !metaData.userName) return @@ -145,7 +148,8 @@ const init: BoundMethodCreator = dispatch => async () => { .catch(err => dispatch.call(handleError, err)) Object.assign(metaData, { api: metaDataFromAPI }) dispatch.call(setMetaData, metaData) - const shouldShow = URLHelper.isInCodePage(metaData) + const shouldShow = + intelligentToggle === null ? URLHelper.isInCodePage(metaData) : intelligentToggle dispatch.call(setShouldShow, shouldShow) DOMHelper.markGitakoReadyState() } catch (err) { @@ -176,12 +180,15 @@ const handleError: BoundMethodCreator<[Error]> = dispatch => async err => { } const onPJAXEnd: BoundMethodCreator = dispatch => () => { - const { metaData, copyFileButton, copySnippetButton } = dispatch.get() + const { metaData, copyFileButton, copySnippetButton, intelligentToggle } = dispatch.get() DOMHelper.unmountTopProgressBar() DOMHelper.decorateGitHubPageContent({ copyFileButton, copySnippetButton }) const mergedMetaData = { ...metaData, ...URLHelper.parse() } - dispatch.call(setShouldShow, URLHelper.isInCodePage(mergedMetaData)) dispatch.call(setMetaData, mergedMetaData) + + if (intelligentToggle === null) { + dispatch.call(setShouldShow, URLHelper.isInCodePage(mergedMetaData)) + } } const onKeyDown: BoundMethodCreator<[KeyboardEvent]> = dispatch => e => { @@ -194,8 +201,15 @@ const onKeyDown: BoundMethodCreator<[KeyboardEvent]> = dispatch => e => { } } -const toggleShowSideBar: BoundMethodCreator = dispatch => () => - dispatch.call(setShouldShow, !dispatch.get().shouldShow) +const toggleShowSideBar: BoundMethodCreator = dispatch => () => { + const { intelligentToggle } = dispatch.get() + const shouldShow = !dispatch.get().shouldShow + dispatch.call(setShouldShow, shouldShow) + + if (intelligentToggle !== null) { + dispatch.call(setIntelligentToggle, shouldShow) + } +} const setShouldShow: BoundMethodCreator< [ConnectorState['shouldShow']] @@ -247,6 +261,13 @@ const setCopySnippet: BoundMethodCreator< [ConnectorState['copySnippetButton']] > = dispatch => copySnippetButton => dispatch.set({ copySnippetButton }) +const setIntelligentToggle: BoundMethodCreator< + [ConnectorState['intelligentToggle']] +> = dispatch => intelligentToggle => { + configHelper.setOne(configKeys.intelligentToggle, intelligentToggle) + dispatch.set({ intelligentToggle }) +} + const useListeners: BoundMethodCreator<[boolean]> = dispatch => { const $onPJAXEnd = () => dispatch.call(onPJAXEnd) const $onKeyDown = (e: KeyboardEvent) => dispatch.call(onKeyDown, e) @@ -276,6 +297,7 @@ export default { setCompressSingleton, setCopyFile, setCopySnippet, + setIntelligentToggle, setError, handleError, useListeners, diff --git a/src/utils/configHelper.ts b/src/utils/configHelper.ts index 076ce58..b738848 100644 --- a/src/utils/configHelper.ts +++ b/src/utils/configHelper.ts @@ -1,13 +1,14 @@ -import storageHelper from 'utils/storageHelper' import { pick } from 'utils/general' +import storageHelper from 'utils/storageHelper' -type Config = { +export type Config = { sideBarWidth: number shortcut: string | undefined access_token: string | undefined compressSingletonFolder: boolean copyFileButton: boolean copySnippetButton: boolean + intelligentToggle: boolean | null // `null` stands for intelligent, boolean for sidebar open status } export enum configKeys { @@ -17,6 +18,7 @@ export enum configKeys { compressSingletonFolder = 'compressSingletonFolder', copyFileButton = 'copyFileButton', copySnippetButton = 'copySnippetButton', + intelligentToggle = 'intelligentToggle', } const defaultConfigs: Config = { @@ -26,6 +28,7 @@ const defaultConfigs: Config = { compressSingletonFolder: true, copyFileButton: true, copySnippetButton: true, + intelligentToggle: null, } const configKeyArray = Object.values(configKeys) diff --git a/src/utils/storageHelper.ts b/src/utils/storageHelper.ts index 0b67a72..609b3c2 100644 --- a/src/utils/storageHelper.ts +++ b/src/utils/storageHelper.ts @@ -5,7 +5,6 @@ function get(mapping: string | string[] | object): Promise { } function set(value: any): Promise { - // it's ok return new Promise(resolve => localStorage.set(value, resolve)) }