feat: intelligent toggle

This commit is contained in:
EnixCoda 2019-09-22 12:41:59 +08:00
parent a2b640b31e
commit 1514c3e7fe
No known key found for this signature in database
GPG key ID: 0C1A07377913A1DD
6 changed files with 87 additions and 33 deletions

View file

@ -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<HTMLInputElement>) => Promise<void> | void
getValue: () => boolean
wikiLink: string
wikiLink?: string
description?: string
}[]
}
@ -71,14 +73,14 @@ export default class SettingsBar extends React.PureComponent<Props, State> {
},
{
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<Props, State> {
getValue: () => this.props.copySnippetButton,
wikiLink: wikiLinks.copySnippet,
},
{
key: 'intelligent-toggle',
label: 'Intelligent Toggle',
onChange: async (e: React.FormEvent<HTMLInputElement>) => {
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<Props, State> {
checked={option.getValue()}
/>
&nbsp;{option.label}&nbsp;
<a href={option.wikiLink} target={'_blank'}>
(?)
</a>
{option.wikiLink ? (
<a href={option.wikiLink} target={'_blank'}>
(?)
</a>
) : (
option.description && (
<span className={'description'} title={option.description}>
(?)
</span>
)
)}
</label>
<br />
</React.Fragment>

View file

@ -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<Props & ConnectorState> {
compressSingletonFolder,
copyFileButton,
copySnippetButton,
intelligentToggle,
toggleShowSideBarShortcut,
logoContainerElement,
toggleShowSideBar,
@ -109,6 +110,7 @@ class Gitako extends React.PureComponent<Props & ConnectorState> {
setCompressSingleton,
setCopyFile,
setCopySnippet,
setIntelligentToggle,
} = this.props
return (
<div className={'gitako-side-bar'}>
@ -132,9 +134,11 @@ class Gitako extends React.PureComponent<Props & ConnectorState> {
compressSingletonFolder={compressSingletonFolder}
copyFileButton={copyFileButton}
copySnippetButton={copySnippetButton}
intelligentToggle={intelligentToggle}
setCompressSingleton={setCompressSingleton}
setCopyFile={setCopyFile}
setCopySnippet={setCopySnippet}
setIntelligentToggle={setIntelligentToggle}
/>
</div>
</Resizable>

View file

@ -409,6 +409,10 @@
}
&-section {
padding-bottom: 16px;
.description:hover {
cursor: help;
}
}
/* inputs for access token & shortcut were too wide */

View file

@ -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<typeof setCopyFile>
setCopySnippet: GetCreatedMethod<typeof setCopySnippet>
setCompressSingleton: GetCreatedMethod<typeof setCompressSingleton>
setIntelligentToggle: GetCreatedMethod<typeof setIntelligentToggle>
} & {
baseSize: number
toggleShowSideBarShortcut?: string
accessToken?: string
} & Pick<
Config,
'compressSingletonFolder' | 'copyFileButton' | 'copySnippetButton' | 'sideBarOpenStatus'
'compressSingletonFolder' | 'copyFileButton' | 'copySnippetButton' | 'intelligentToggle'
>
type BoundMethodCreator<Args extends any[] = []> = MethodCreator<Props, ConnectorState, Args>
@ -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,

View file

@ -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)

View file

@ -5,7 +5,6 @@ function get(mapping: string | string[] | object): Promise<any> {
}
function set(value: any): Promise<void> {
// it's ok
return new Promise(resolve => localStorage.set(value, resolve))
}