refactor: abandon default export

This commit is contained in:
EnixCoda 2019-11-09 01:38:02 +08:00
parent d9aaf72b03
commit 8ed78e2a98
No known key found for this signature in database
GPG key ID: 0C1A07377913A1DD
28 changed files with 142 additions and 214 deletions

View file

@ -1,17 +1,17 @@
import LoadingIndicator from 'components/LoadingIndicator'
import Node from 'components/Node'
import SearchBar from 'components/SearchBar'
import connect from 'driver/connect'
import { FileExplorer as FileExplorerCore } from 'driver/core'
import { LoadingIndicator } from 'components/LoadingIndicator'
import { Node } from 'components/Node'
import { SearchBar } from 'components/SearchBar'
import { connect } from 'driver/connect'
import { FileExplorerCore } from 'driver/core'
import { ConnectorState } from 'driver/core/FileExplorer'
import * as React from 'react'
import { FixedSizeList as List, ListChildComponentProps } from 'react-window'
import cx from 'utils/cx'
import { cx } from 'utils/cx'
import { MetaData, TreeData } from 'utils/GitHubHelper'
import { usePrevious } from 'utils/hooks'
import { TreeNode, VisibleNodes } from 'utils/VisibleNodesGenerator'
import Icon from './Icon'
import SizeObserver from './SizeObserver'
import { Icon } from './Icon'
import { SizeObserver } from './SizeObserver'
export type Props = {
treeData?: TreeData
@ -22,7 +22,7 @@ export type Props = {
toggleShowSettings: React.MouseEventHandler
}
class FileExplorer extends React.Component<Props & ConnectorState> {
class RawFileExplorer extends React.Component<Props & ConnectorState> {
static defaultProps: Partial<Props & ConnectorState> = {
freeze: false,
searchKey: '',
@ -183,4 +183,4 @@ class FileExplorer extends React.Component<Props & ConnectorState> {
}
}
export default connect<Props, ConnectorState>(FileExplorerCore)(FileExplorer)
export const FileExplorer = connect<Props, ConnectorState>(FileExplorerCore)(RawFileExplorer)

View file

@ -1,8 +1,8 @@
import { raiseError } from 'analytics'
import SideBar from 'components/SideBar'
import { SideBar } from 'components/SideBar'
import * as React from 'react'
export default class Gitako extends React.PureComponent {
export class Gitako extends React.PureComponent {
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
raiseError(error, errorInfo)
}

View file

@ -16,7 +16,7 @@ import Octicon, {
X,
} from '@primer/octicons-react'
import * as React from 'react'
import cx from 'utils/cx'
import { cx } from 'utils/cx'
function getSVGIconComponent(
type: string,
@ -123,7 +123,7 @@ type Props = {
onClick?: (event: React.MouseEvent<HTMLElement>) => void
}
const Icon: React.SFC<Props> = function Icon({ type, className = undefined, ...otherProps }) {
export function Icon({ type, className = undefined, ...otherProps }: Props) {
const { name, IconComponent } = getSVGIconComponent(type)
const mergedClassName = cx('octicon', name)
return (
@ -135,5 +135,3 @@ const Icon: React.SFC<Props> = function Icon({ type, className = undefined, ...o
</div>
)
}
export default Icon

View file

@ -1,10 +1,10 @@
import Icon from 'components/Icon'
import { Icon } from 'components/Icon'
import * as React from 'react'
type Props = {
text: React.ReactNode
}
export default function LoadingIndicator({ text }: Props) {
export function LoadingIndicator({ text }: Props) {
return (
<div className={'loading-indicator-container'}>
<div className={'loading-indicator'}>

View file

@ -1,12 +1,12 @@
import * as React from 'react'
import { MetaData } from 'utils/GitHubHelper'
import { safeTouch } from 'safe-touch'
import { MetaData } from 'utils/GitHubHelper'
type Props = {
metaData: MetaData
}
export default function MetaBar({ metaData }: Props) {
export function MetaBar({ metaData }: Props) {
const userUrl = safeTouch(metaData).api.owner.html_url()
const repoUrl = safeTouch(metaData).api.html_url()
return (

View file

@ -1,6 +1,6 @@
import Icon from 'components/Icon'
import { Icon } from 'components/Icon'
import * as React from 'react'
import cx from 'utils/cx'
import { cx } from 'utils/cx'
import { OperatingSystems, os } from 'utils/general'
import { TreeNode } from 'utils/VisibleNodesGenerator'
@ -24,7 +24,7 @@ type Props = {
renderActions?(node: TreeNode): React.ReactNode
style?: React.CSSProperties
}
export default class Node extends React.PureComponent<Props> {
export class Node extends React.PureComponent<Props> {
onClick: React.MouseEventHandler = event => {
if (
(os === OperatingSystems.macOS && event.metaKey) ||

View file

@ -6,7 +6,7 @@ type Props<P> = {
children: React.ReactElement<P>
}
export default function PJAXLink<P>({ to, children }: Props<P>) {
export function PJAXLink<P>({ to, children }: Props<P>) {
return React.cloneElement(children, {
...children.props,
onClick: () => DOMHelper.loadWithPJAX(to),

View file

@ -5,12 +5,10 @@ type Props = {
into: Element | null
}
class Portal extends React.PureComponent<Props> {
export class Portal extends React.PureComponent<Props> {
render() {
const { into, children } = this.props
if (!(into instanceof Element)) return null
return ReactDOM.createPortal(children, into)
}
}
export default Portal

View file

@ -1,10 +1,10 @@
import { HorizontalResizeHandler } from 'components/ResizeHandler'
import * as React from 'react'
import HorizontalResizeHandler from 'components/ResizeHandler'
import cx from 'utils/cx'
import { useWindowSize, useMediaStyleSheet } from 'utils/hooks'
import { configKeys, setOne } from 'utils/configHelper'
import { cx } from 'utils/cx'
import { bodySpacingClassName } from 'utils/DOMHelper'
import configHelper, { configKeys } from 'utils/configHelper'
import * as features from 'utils/features'
import { useMediaStyleSheet, useWindowSize } from 'utils/hooks'
export type Size = number
type Props = {
@ -15,11 +15,7 @@ type Props = {
const MINIMAL_CONTENT_VIEWPORT_WIDTH = 100
const GITHUB_WIDTH = 1020
export default function Resizable({
baseSize,
className,
children,
}: React.PropsWithChildren<Props>) {
export function Resizable({ baseSize, className, children }: React.PropsWithChildren<Props>) {
const [size, setSize] = React.useState(baseSize)
React.useEffect(() => {
@ -36,7 +32,7 @@ export default function Resizable({
React.useEffect(() => {
document.documentElement.style.setProperty('--gitako-width', size + 'px')
configHelper.setOne(configKeys.sideBarWidth, size)
setOne(configKeys.sideBarWidth, size)
}, [size])
useMediaStyleSheet(

View file

@ -1,4 +1,4 @@
import Icon from 'components/Icon'
import { Icon } from 'components/Icon'
import * as React from 'react'
import { Size } from './Resizable'
@ -8,7 +8,7 @@ type Props = {
style?: React.CSSProperties
}
export default class HorizontalResizeHandler extends React.PureComponent<Props> {
export class HorizontalResizeHandler extends React.PureComponent<Props> {
pointerDown = false
startX = 0
baseSize = this.props.size

View file

@ -1,5 +1,5 @@
import * as React from 'react'
import cx from 'utils/cx'
import { cx } from 'utils/cx'
type Props = {
onSearch: (searchKey: string) => void
@ -7,7 +7,7 @@ type Props = {
searchKey: string
}
export default function SearchBar({ onSearch, onFocus, searchKey }: Props) {
export function SearchBar({ onSearch, onFocus, searchKey }: Props) {
return (
<div className={'search-input-wrapper'}>
<input

View file

@ -1,10 +1,10 @@
import { raiseError } from 'analytics'
import Icon from 'components/Icon'
import { Icon } from 'components/Icon'
import { oauth } from 'env'
import * as React from 'react'
import configHelper, { Config, configKeys } from 'utils/configHelper'
import { Config, configKeys, setOne } from 'utils/configHelper'
import { friendlyFormatShortcut, JSONRequest, parseURLSearch } from 'utils/general'
import keyHelper from 'utils/keyHelper'
import * as keyHelper from 'utils/keyHelper'
import { version } from '../../package.json'
const WIKI_HOME_LINK = 'https://github.com/EnixCoda/Gitako/wiki'
@ -50,7 +50,7 @@ type State = {
}[]
}
export default class SettingsBar extends React.PureComponent<Props, State> {
export class SettingsBar extends React.PureComponent<Props, State> {
state = {
accessToken: '',
accessTokenHint: '',
@ -91,7 +91,7 @@ export default class SettingsBar extends React.PureComponent<Props, State> {
onChange: async (e: React.FormEvent<HTMLInputElement>) => {
const { checked } = e.currentTarget
const intelligentToggle = checked ? null : true
await configHelper.setOne(configKeys.intelligentToggle, intelligentToggle)
await setOne(configKeys.intelligentToggle, intelligentToggle)
this.props.setIntelligentToggle(intelligentToggle)
},
getValue: () => this.props.intelligentToggle === null,
@ -159,7 +159,7 @@ export default class SettingsBar extends React.PureComponent<Props, State> {
const { onAccessTokenChange } = this.props
const { accessToken } = this.state
if (accessToken) {
await configHelper.setOne(configKeys.accessToken, accessToken)
await setOne(configKeys.accessToken, accessToken)
onAccessTokenChange(accessToken)
this.setState({
accessToken: '',
@ -170,7 +170,7 @@ export default class SettingsBar extends React.PureComponent<Props, State> {
clearToken = async () => {
const { onAccessTokenChange } = this.props
await configHelper.setOne(configKeys.accessToken, '')
await setOne(configKeys.accessToken, '')
onAccessTokenChange('')
this.setState({ accessToken: '' })
}
@ -178,7 +178,7 @@ export default class SettingsBar extends React.PureComponent<Props, State> {
saveShortcut = async () => {
const { onShortcutChange } = this.props
const { toggleShowSideBarShortcut } = this.state
await configHelper.setOne(configKeys.shortcut, toggleShowSideBarShortcut)
await setOne(configKeys.shortcut, toggleShowSideBarShortcut)
if (typeof toggleShowSideBarShortcut === 'string') {
onShortcutChange(toggleShowSideBarShortcut)
this.setState({
@ -214,7 +214,7 @@ export default class SettingsBar extends React.PureComponent<Props, State> {
): (e: React.FormEvent<HTMLInputElement>) => Promise<void> {
return async e => {
const enabled = e.currentTarget.checked
await configHelper.setOne(configKey, enabled)
await setOne(configKey, enabled)
set(enabled)
this.showReloadHint()
}

View file

@ -1,18 +1,18 @@
import FileExplorer from 'components/FileExplorer'
import MetaBar from 'components/MetaBar'
import Portal from 'components/Portal'
import Resizable from 'components/Resizable'
import SettingsBar from 'components/SettingsBar'
import ToggleShowButton from 'components/ToggleShowButton'
import connect from 'driver/connect'
import { SideBar as SideBarCore } from 'driver/core'
import { FileExplorer } from 'components/FileExplorer'
import { MetaBar } from 'components/MetaBar'
import { Portal } from 'components/Portal'
import { Resizable } from 'components/Resizable'
import { SettingsBar } from 'components/SettingsBar'
import { ToggleShowButton } from 'components/ToggleShowButton'
import { connect } from 'driver/connect'
import { SideBarCore } from 'driver/core'
import { ConnectorState } from 'driver/core/SideBar'
import * as React from 'react'
import cx from 'utils/cx'
import { cx } from 'utils/cx'
export type Props = {}
class Gitako extends React.PureComponent<Props & ConnectorState> {
class RawGitako extends React.PureComponent<Props & ConnectorState> {
static defaultProps: Partial<Props & ConnectorState> = {
baseSize: 260,
shouldShow: false,
@ -147,4 +147,4 @@ class Gitako extends React.PureComponent<Props & ConnectorState> {
}
}
export default connect<Props, ConnectorState>(SideBarCore)(Gitako)
export const SideBar = connect<Props, ConnectorState>(SideBarCore)(RawGitako)

View file

@ -11,7 +11,7 @@ type Props = {
children(size: Partial<Size>): React.ReactNode
} & React.HTMLAttributes<HTMLElement>
export default function SizeObserver({ type = 'div', children, ...rest }: Props) {
export function SizeObserver({ type = 'div', children, ...rest }: Props) {
const ref = React.useRef<any>()
const [size, setSize] = React.useState<Partial<Size>>({

View file

@ -1,13 +1,14 @@
import { Icon } from 'components/Icon'
import * as React from 'react'
import Icon from 'components/Icon'
import cx from 'utils/cx'
import { cx } from 'utils/cx'
type Props = {
error?: string
shouldShow: boolean
toggleShowSideBar: React.MouseEventHandler
}
export default function Logo({ error, shouldShow, toggleShowSideBar }: Props) {
export function ToggleShowButton({ error, shouldShow, toggleShowSideBar }: Props) {
return (
<div
className={cx('gitako-toggle-show-button-wrapper', {

View file

@ -1,5 +1,5 @@
import { withErrorLog } from 'analytics'
import Gitako from 'components/Gitako'
import { Gitako } from 'components/Gitako'
import { addMiddleware } from 'driver/connect'
import * as React from 'react'
import * as ReactDOM from 'react-dom'

View file

@ -93,7 +93,7 @@ function link<P, S>(instance: React.Component<P, S>, sources: Sources<P, S>): Wr
return wrappedMethods
}
export default function connect<BaseP, ExtraP>(mapping: Sources<BaseP, ExtraP>) {
export function connect<BaseP, ExtraP>(mapping: Sources<BaseP, ExtraP>) {
return function linkComponent<S>(
ComponentClass: React.ComponentClass<BaseP & ExtraP, S>,
): React.ComponentClass<BaseP, ExtraP> {

View file

@ -4,10 +4,11 @@ import * as ini from 'ini'
import { Base64 } from 'js-base64'
import * as DOMHelper from 'utils/DOMHelper'
import { findNode, searchKeyToRegexps } from 'utils/general'
import GitHubHelper, { BlobData } from 'utils/GitHubHelper'
import treeParser from 'utils/treeParser'
import URLHelper from 'utils/URLHelper'
import VisibleNodesGenerator, { TreeNode, VisibleNodes } from 'utils/VisibleNodesGenerator'
import * as GitHubHelper from 'utils/GitHubHelper'
import { BlobData } from 'utils/GitHubHelper'
import * as treeParser from 'utils/treeParser'
import * as URLHelper from 'utils/URLHelper'
import { TreeNode, VisibleNodes, VisibleNodesGenerator } from 'utils/VisibleNodesGenerator'
export type ConnectorState = {
stateText: string
@ -49,7 +50,7 @@ let visibleNodesGenerator: VisibleNodesGenerator
type BoundMethodCreator<Args extends any[] = []> = MethodCreator<Props, ConnectorState, Args>
const init: BoundMethodCreator = dispatch => () =>
export const init: BoundMethodCreator = dispatch => () =>
dispatch.call(setStateText, 'Fetching File List...')
const githubSubModuleURLRegex = {
@ -127,7 +128,7 @@ function handleParsed(root: TreeNode, parsed: Parsed) {
})
}
const setUpTree: BoundMethodCreator<
export const setUpTree: BoundMethodCreator<
[Pick<Props, 'treeData' | 'metaData' | 'compressSingletonFolder' | 'accessToken'>]
> = dispatch => async ({ treeData, metaData, compressSingletonFolder, accessToken }) => {
if (!treeData) return
@ -158,21 +159,21 @@ const setUpTree: BoundMethodCreator<
dispatch.call(goTo, URLHelper.getCurrentPath(metaData.branchName))
}
const execAfterRender: BoundMethodCreator = dispatch => () => {
export const execAfterRender: BoundMethodCreator = dispatch => () => {
for (const task of tasksAfterRender) {
task()
}
tasksAfterRender.length = 0
}
const setStateText: BoundMethodCreator<[ConnectorState['stateText']]> = dispatch => (
export const setStateText: BoundMethodCreator<[ConnectorState['stateText']]> = dispatch => (
text: string,
) =>
dispatch.set({
stateText: text,
})
const handleKeyDown: BoundMethodCreator<[React.KeyboardEvent]> = dispatch => event => {
export const handleKeyDown: BoundMethodCreator<[React.KeyboardEvent]> = dispatch => event => {
const { searched, visibleNodes } = dispatch.get()
if (!visibleNodes) return
const { nodes, focusedNode, expandedNodes, depths } = visibleNodes
@ -277,16 +278,17 @@ const handleKeyDown: BoundMethodCreator<[React.KeyboardEvent]> = dispatch => eve
}
}
const onFocusSearchBar: BoundMethodCreator = dispatch => () => dispatch.call(focusNode, null, false)
export const onFocusSearchBar: BoundMethodCreator = dispatch => () =>
dispatch.call(focusNode, null, false)
const search: BoundMethodCreator<[string]> = dispatch => searchKey => {
export const search: BoundMethodCreator<[string]> = dispatch => searchKey => {
dispatch.set({ searchKey, searched: searchKey !== '' })
const regexps = searchKeyToRegexps(searchKey)
visibleNodesGenerator.search(regexps)
dispatch.call(updateVisibleNodes)
}
const goTo: BoundMethodCreator<[string[]]> = dispatch => async currentPath => {
export const goTo: BoundMethodCreator<[string[]]> = dispatch => async currentPath => {
visibleNodesGenerator.search([])
tasksAfterRender.push(() => {
const nodeExpandedTo = visibleNodesGenerator.expandTo(currentPath.join('/'))
@ -298,12 +300,15 @@ const goTo: BoundMethodCreator<[string[]]> = dispatch => async currentPath => {
dispatch.set({ searchKey: '', searched: false })
}
const setExpand: BoundMethodCreator<[TreeNode, boolean]> = dispatch => (node, expand = false) => {
export const setExpand: BoundMethodCreator<[TreeNode, boolean]> = dispatch => (
node,
expand = false,
) => {
visibleNodesGenerator.setExpand(node, expand)
dispatch.call(focusNode, node, false)
}
const toggleNodeExpansion: BoundMethodCreator<[TreeNode, boolean]> = dispatch => (
export const toggleNodeExpansion: BoundMethodCreator<[TreeNode, boolean]> = dispatch => (
node,
skipScrollToNode,
) => {
@ -312,7 +317,7 @@ const toggleNodeExpansion: BoundMethodCreator<[TreeNode, boolean]> = dispatch =>
tasksAfterRender.push(DOMHelper.focusFileExplorer)
}
const focusNode: BoundMethodCreator<[TreeNode | null, boolean]> = dispatch => (
export const focusNode: BoundMethodCreator<[TreeNode | null, boolean]> = dispatch => (
node: TreeNode | null,
skipScroll = false,
) => {
@ -322,7 +327,7 @@ const focusNode: BoundMethodCreator<[TreeNode | null, boolean]> = dispatch => (
dispatch.call(updateVisibleNodes)
}
const onNodeClick: BoundMethodCreator<[TreeNode]> = dispatch => node => {
export const onNodeClick: BoundMethodCreator<[TreeNode]> = dispatch => node => {
if (node.type === 'tree') {
dispatch.call(toggleNodeExpansion, node, true)
} else if (node.type === 'blob') {
@ -335,23 +340,7 @@ const onNodeClick: BoundMethodCreator<[TreeNode]> = dispatch => node => {
}
}
const updateVisibleNodes: BoundMethodCreator = dispatch => () => {
export const updateVisibleNodes: BoundMethodCreator = dispatch => () => {
const { visibleNodes } = visibleNodesGenerator
dispatch.set({ visibleNodes })
}
export default {
init,
setUpTree,
execAfterRender,
setStateText,
handleKeyDown,
onFocusSearchBar,
search,
setExpand,
goTo,
toggleNodeExpansion,
focusNode,
onNodeClick,
updateVisibleNodes,
}

View file

@ -1,18 +1,12 @@
import { Props } from 'components/SideBar'
import { GetCreatedMethod, MethodCreator } from 'driver/connect'
import configHelper, { Config, configKeys } from 'utils/configHelper'
import * as configHelper from 'utils/configHelper'
import { Config } from 'utils/configHelper'
import * as DOMHelper from 'utils/DOMHelper'
import GitHubHelper, {
API_RATE_LIMIT,
BAD_CREDENTIALS,
BLOCKED_PROJECT,
EMPTY_PROJECT,
MetaData,
NOT_FOUND,
TreeData,
} from 'utils/GitHubHelper'
import keyHelper from 'utils/keyHelper'
import URLHelper from 'utils/URLHelper'
import * as GitHubHelper from 'utils/GitHubHelper'
import { MetaData, TreeData } from 'utils/GitHubHelper'
import * as keyHelper from 'utils/keyHelper'
import * as URLHelper from 'utils/URLHelper'
export type ConnectorState = {
// error message
@ -54,7 +48,7 @@ export type ConnectorState = {
type BoundMethodCreator<Args extends any[] = []> = MethodCreator<Props, ConnectorState, Args>
const init: BoundMethodCreator = dispatch => async () => {
export const init: BoundMethodCreator = dispatch => async () => {
const { initializingPromise } = dispatch.get()
if (initializingPromise) await initializingPromise
@ -159,15 +153,15 @@ const init: BoundMethodCreator = dispatch => async () => {
}
}
const handleError: BoundMethodCreator<[Error]> = dispatch => async err => {
if (err.message === EMPTY_PROJECT) {
export const handleError: BoundMethodCreator<[Error]> = dispatch => async err => {
if (err.message === GitHubHelper.EMPTY_PROJECT) {
dispatch.call(setError, 'This project seems to be empty.')
} else if (err.message === BLOCKED_PROJECT) {
} else if (err.message === GitHubHelper.BLOCKED_PROJECT) {
dispatch.call(setError, 'This project is blocked.')
} else if (
err.message === NOT_FOUND ||
err.message === BAD_CREDENTIALS ||
err.message === API_RATE_LIMIT
err.message === GitHubHelper.NOT_FOUND ||
err.message === GitHubHelper.BAD_CREDENTIALS ||
err.message === GitHubHelper.API_RATE_LIMIT
) {
dispatch.set({ errorDueToAuth: true })
dispatch.call(setShowSettings, true)
@ -179,7 +173,7 @@ const handleError: BoundMethodCreator<[Error]> = dispatch => async err => {
}
}
const onPJAXEnd: BoundMethodCreator = dispatch => () => {
export const onPJAXEnd: BoundMethodCreator = dispatch => () => {
const { metaData, copyFileButton, copySnippetButton, intelligentToggle } = dispatch.get()
DOMHelper.unmountTopProgressBar()
DOMHelper.decorateGitHubPageContent({ copyFileButton, copySnippetButton })
@ -191,7 +185,7 @@ const onPJAXEnd: BoundMethodCreator = dispatch => () => {
}
}
const onKeyDown: BoundMethodCreator<[KeyboardEvent]> = dispatch => e => {
export const onKeyDown: BoundMethodCreator<[KeyboardEvent]> = dispatch => e => {
const { toggleShowSideBarShortcut } = dispatch.get()
if (toggleShowSideBarShortcut) {
const keys = keyHelper.parseEvent(e)
@ -201,7 +195,7 @@ const onKeyDown: BoundMethodCreator<[KeyboardEvent]> = dispatch => e => {
}
}
const toggleShowSideBar: BoundMethodCreator = dispatch => () => {
export const toggleShowSideBar: BoundMethodCreator = dispatch => () => {
const { intelligentToggle } = dispatch.get()
const shouldShow = !dispatch.get().shouldShow
dispatch.call(setShouldShow, shouldShow)
@ -211,28 +205,28 @@ const toggleShowSideBar: BoundMethodCreator = dispatch => () => {
}
}
const setShouldShow: BoundMethodCreator<
export const setShouldShow: BoundMethodCreator<
[ConnectorState['shouldShow']]
> = dispatch => shouldShow => {
dispatch.set({ shouldShow }, shouldShow ? DOMHelper.focusFileExplorer : undefined)
DOMHelper.setBodyIndent(shouldShow)
}
const setError: BoundMethodCreator<[ConnectorState['error']]> = dispatch => error => {
export const setError: BoundMethodCreator<[ConnectorState['error']]> = dispatch => error => {
dispatch.set({ error })
dispatch.call(setShouldShow, false)
}
const toggleShowSettings: BoundMethodCreator = dispatch => () =>
export const toggleShowSettings: BoundMethodCreator = dispatch => () =>
dispatch.set(({ showSettings }) => ({
showSettings: !showSettings,
}))
const setShowSettings: BoundMethodCreator<
export const setShowSettings: BoundMethodCreator<
[ConnectorState['showSettings']]
> = dispatch => showSettings => dispatch.set({ showSettings })
const onAccessTokenChange: BoundMethodCreator<
export const onAccessTokenChange: BoundMethodCreator<
[ConnectorState['accessToken']]
> = dispatch => accessToken => {
dispatch.set({ accessToken })
@ -242,33 +236,33 @@ const onAccessTokenChange: BoundMethodCreator<
}
}
const onShortcutChange: BoundMethodCreator<
export const onShortcutChange: BoundMethodCreator<
[ConnectorState['toggleShowSideBarShortcut']]
> = dispatch => shortcut => dispatch.set({ toggleShowSideBarShortcut: shortcut })
const setMetaData: BoundMethodCreator<[ConnectorState['metaData']]> = dispatch => metaData =>
export const setMetaData: BoundMethodCreator<[ConnectorState['metaData']]> = dispatch => metaData =>
dispatch.set({ metaData })
const setCompressSingleton: BoundMethodCreator<
export const setCompressSingleton: BoundMethodCreator<
[ConnectorState['compressSingletonFolder']]
> = dispatch => compressSingletonFolder => dispatch.set({ compressSingletonFolder })
const setCopyFile: BoundMethodCreator<
export const setCopyFile: BoundMethodCreator<
[ConnectorState['copyFileButton']]
> = dispatch => copyFileButton => dispatch.set({ copyFileButton })
const setCopySnippet: BoundMethodCreator<
export const setCopySnippet: BoundMethodCreator<
[ConnectorState['copySnippetButton']]
> = dispatch => copySnippetButton => dispatch.set({ copySnippetButton })
const setIntelligentToggle: BoundMethodCreator<
export const setIntelligentToggle: BoundMethodCreator<
[ConnectorState['intelligentToggle']]
> = dispatch => intelligentToggle => {
configHelper.setOne(configKeys.intelligentToggle, intelligentToggle)
configHelper.setOne(configHelper.configKeys.intelligentToggle, intelligentToggle)
dispatch.set({ intelligentToggle })
}
const useListeners: BoundMethodCreator<[boolean]> = dispatch => {
export const useListeners: BoundMethodCreator<[boolean]> = dispatch => {
const $onPJAXEnd = () => dispatch.call(onPJAXEnd)
const $onKeyDown = (e: KeyboardEvent) => dispatch.call(onKeyDown, e)
return on => {
@ -282,23 +276,3 @@ const useListeners: BoundMethodCreator<[boolean]> = dispatch => {
}
}
}
export default {
init,
onPJAXEnd,
onKeyDown,
setShouldShow,
setShowSettings,
toggleShowSideBar,
toggleShowSettings,
onAccessTokenChange,
onShortcutChange,
setMetaData,
setCompressSingleton,
setCopyFile,
setCopySnippet,
setIntelligentToggle,
setError,
handleError,
useListeners,
}

View file

@ -1,2 +1,5 @@
export { default as SideBar } from './SideBar'
export { default as FileExplorer } from './FileExplorer'
import * as FileExplorer from './FileExplorer'
import * as SideBar from './SideBar'
export const SideBarCore = SideBar
export const FileExplorerCore = FileExplorer

View file

@ -70,7 +70,11 @@ type RepoMetaData = {
}
}
async function getRepoMeta({ userName, repoName, accessToken }: MetaData): Promise<RepoMetaData> {
export async function getRepoMeta({
userName,
repoName,
accessToken,
}: MetaData): Promise<RepoMetaData> {
const url = `https://api.github.com/repos/${userName}/${repoName}`
return await request(url, { accessToken })
}
@ -91,7 +95,7 @@ export type TreeData = {
url: string
}
async function getTreeData({
export async function getTreeData({
userName,
repoName,
branchName,
@ -109,7 +113,7 @@ export type BlobData = {
url: string
}
async function getBlobData({
export async function getBlobData({
userName,
repoName,
accessToken,
@ -121,17 +125,10 @@ async function getBlobData({
return await request(url, { accessToken })
}
function getUrlForRedirect(
export function getUrlForRedirect(
{ userName, repoName, branchName }: MetaData,
type = 'blob',
path?: string,
) {
return `https://github.com/${userName}/${repoName}/${type}/${branchName}/${path}`
}
export default {
getRepoMeta,
getTreeData,
getBlobData,
getUrlForRedirect,
}

View file

@ -1,7 +1,7 @@
import { raiseError } from 'analytics'
import { MetaData } from './GitHubHelper'
function parse(): MetaData & { path: string[] } {
export function parse(): MetaData & { path: string[] } {
const { pathname } = window.location
let [
,
@ -19,12 +19,12 @@ function parse(): MetaData & { path: string[] } {
}
}
function parseSHA() {
export function parseSHA() {
const { type, path } = parse()
return type === 'blob' || type === 'tree' ? path[0] : undefined
}
function isInRepoPage() {
export function isInRepoPage() {
const repoHeaderSelector = '.repohead'
return Boolean(document.querySelector(repoHeaderSelector))
}
@ -38,7 +38,7 @@ const TYPES = {
// TODO: record more types
}
function isInCodePage(metaData: MetaData = {}) {
export function isInCodePage(metaData: MetaData = {}) {
const mergedRepo = { ...parse(), ...metaData }
const { type, branchName } = mergedRepo
return Boolean(
@ -57,7 +57,7 @@ function isCompleteCommitSHA(sha?: string) {
return typeof sha === 'string' && /^[abcdef0-9]{40}$/i.test(sha)
}
function getCurrentPath(branchName = '') {
export function getCurrentPath(branchName = '') {
const { path, type } = parse()
if (type === 'blob' || type === 'tree') {
if (isCommitPath(path)) {
@ -90,11 +90,3 @@ function getCurrentPath(branchName = '') {
}
return []
}
export default {
getCurrentPath,
isInRepoPage,
isInCodePage,
parse,
parseSHA,
}

View file

@ -1,4 +1,4 @@
import storageHelper from 'utils/storageHelper'
import * as storageHelper from 'utils/storageHelper'
export type Config = {
sideBarWidth: number
@ -43,27 +43,20 @@ function applyDefaultConfigs(configs: Config) {
)
}
async function getAll(): Promise<Config> {
export async function getAll(): Promise<Config> {
return applyDefaultConfigs(await storageHelper.get(configKeyArray))
}
async function getOne(key: configKeys) {
export async function getOne(key: configKeys) {
return (await getAll())[key]
}
async function setAll(partialConfig: Partial<Config>) {
export async function setAll(partialConfig: Partial<Config>) {
return await storageHelper.set(partialConfig)
}
async function setOne(key: configKeys, value: any) {
export async function setOne(key: configKeys, value: any) {
return await setAll({
[key]: value,
})
}
export default {
getAll,
getOne,
setAll,
setOne,
}

View file

@ -1,7 +1,7 @@
/**
* cx('class1', { class2: true, class3: false }) --> 'class1 class2'
*/
export default function cx(...classNames: any[]): string {
export function cx(...classNames: any[]): string {
return classNames
.filter(Boolean)
.map(className => {

View file

@ -36,7 +36,7 @@ function parseKeyCode(code: string) {
return code.toLowerCase().replace(/^control$/, 'ctrl')
}
function parseEvent(e: KeyboardEvent | React.KeyboardEvent) {
export function parseEvent(e: KeyboardEvent | React.KeyboardEvent) {
const { altKey: alt, shiftKey: shift, metaKey: meta, ctrlKey: ctrl } = e
try {
const code = parseKeyCode(e.key)
@ -57,7 +57,3 @@ function parseEvent(e: KeyboardEvent | React.KeyboardEvent) {
throw new Error(`Error parse keyboard event: ${serializedKeyData}`)
}
}
export default {
parseEvent,
}

View file

@ -1,14 +1,9 @@
const localStorage = browser.storage.local
function get(mapping: string[] | null): Promise<any> {
export function get(mapping: string[] | null): Promise<any> {
return localStorage.get(mapping || undefined)
}
function set(value: any): Promise<void> {
export function set(value: any): Promise<void> {
return localStorage.set(value)
}
export default {
get,
set,
}

View file

@ -1,4 +1,4 @@
import GitHubHelper, { MetaData, TreeData } from 'utils/GitHubHelper'
import { getUrlForRedirect, MetaData, TreeData } from 'utils/GitHubHelper'
import { TreeNode } from './VisibleNodesGenerator'
interface RawItem {
@ -36,7 +36,7 @@ function findGitModules(root: TreeNode) {
return null
}
function parse(treeData: TreeData, metaData: MetaData) {
export function parse(treeData: TreeData, metaData: MetaData) {
const { tree } = treeData
// nodes are created from items and put onto tree
@ -70,7 +70,7 @@ function parse(treeData: TreeData, metaData: MetaData) {
name: item.path && item.path.replace(/^.*\//, ''),
url:
item.url && item.type && item.path
? GitHubHelper.getUrlForRedirect(metaData, item.type, item.path)
? getUrlForRedirect(metaData, item.type, item.path)
: null,
contents: item.type === 'tree' ? [] : null,
} as TreeNode
@ -88,7 +88,3 @@ function parse(treeData: TreeData, metaData: MetaData) {
root: sortFoldersToFront(root),
}
}
export default {
parse,
}

View file

@ -202,7 +202,7 @@ type Options = {
compress?: boolean
}
export default class VisibleNodesGenerator {
export class VisibleNodesGenerator {
l1: L1
l2: L2
l3: L3