mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
feat: intelligent toggle
This commit is contained in:
parent
a2b640b31e
commit
1514c3e7fe
6 changed files with 87 additions and 33 deletions
|
|
@ -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()}
|
||||
/>
|
||||
{option.label}
|
||||
<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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -409,6 +409,10 @@
|
|||
}
|
||||
&-section {
|
||||
padding-bottom: 16px;
|
||||
|
||||
.description:hover {
|
||||
cursor: help;
|
||||
}
|
||||
}
|
||||
|
||||
/* inputs for access token & shortcut were too wide */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue