From 682cab762c9353953acae3eb3c7d166e2bae80f0 Mon Sep 17 00:00:00 2001 From: EnixCoda Date: Tue, 27 Aug 2019 22:42:39 +0800 Subject: [PATCH] refactor: type GetCreatedMethod --- src/driver/connect.ts | 5 + src/driver/core/FileExplorer.ts | 237 ++++++++++++++++---------------- src/driver/core/SideBar.ts | 59 ++++---- 3 files changed, 152 insertions(+), 149 deletions(-) diff --git a/src/driver/connect.ts b/src/driver/connect.ts index b80b27b..93cfa11 100644 --- a/src/driver/connect.ts +++ b/src/driver/connect.ts @@ -115,3 +115,8 @@ export default function connect(mapping: Sources) } } +export type GetCreatedMethod = MC extends MethodCreator + ? Args extends any[] + ? ((...args: Args) => void) + : never + : never diff --git a/src/driver/core/FileExplorer.ts b/src/driver/core/FileExplorer.ts index b6f940c..d67423e 100644 --- a/src/driver/core/FileExplorer.ts +++ b/src/driver/core/FileExplorer.ts @@ -4,11 +4,10 @@ import DOMHelper from 'utils/DOMHelper' import treeParser from 'utils/treeParser' import URLHelper from 'utils/URLHelper' import VisibleNodesGenerator, { TreeNode, VisibleNodes } from 'utils/VisibleNodesGenerator' -import GitHubHelper, { BlobData, TreeData } from 'utils/GitHubHelper' +import GitHubHelper, { BlobData } from 'utils/GitHubHelper' import { findNode } from 'utils/general' -import { MethodCreator } from 'driver/connect' +import { MethodCreator, GetCreatedMethod } from 'driver/connect' import { Props } from 'components/FileExplorer' -import Node from 'components/Node' import { raiseError } from 'analytics' export type ConnectorState = { @@ -17,14 +16,14 @@ export type ConnectorState = { searchKey: string searched: boolean - init: () => void - execAfterRender: () => void - handleKeyDown: React.KeyboardEventHandler - handleSearchKeyChange: React.FormEventHandler - onNodeClick: Node['props']['onClick'] - onFocusSearchBar: React.FocusEventHandler - setUpTree: (treeData?: TreeData) => void - goTo: (path: string[]) => void + init: GetCreatedMethod + execAfterRender: GetCreatedMethod + handleKeyDown: GetCreatedMethod + handleSearchKeyChange: GetCreatedMethod + onNodeClick: GetCreatedMethod + onFocusSearchBar: GetCreatedMethod + setUpTree: GetCreatedMethod + goTo: GetCreatedMethod } type DepthMap = Map @@ -130,32 +129,32 @@ const setUpTree: MethodCreator< ConnectorState, [Pick] > = dispatch => async ({ treeData, metaData, compressSingletonFolder, accessToken }) => { - if (!treeData) return - dispatch.call(setStateText, 'Rendering File List...') - const { root, gitModules } = treeParser.parse(treeData, metaData) + if (!treeData) return + dispatch.call(setStateText, 'Rendering File List...') + const { root, gitModules } = treeParser.parse(treeData, metaData) - if (gitModules) { - if (metaData.userName && metaData.repoName && gitModules.sha) { - const blobData = await GitHubHelper.getBlobData({ - userName: metaData.userName, - repoName: metaData.repoName, - sha: gitModules.sha, - accessToken, - }) + if (gitModules) { + if (metaData.userName && metaData.repoName && gitModules.sha) { + const blobData = await GitHubHelper.getBlobData({ + userName: metaData.userName, + repoName: metaData.repoName, + sha: gitModules.sha, + accessToken, + }) - resolveGitModules(root as TreeNode, blobData) - } + resolveGitModules(root as TreeNode, blobData) } + } - visibleNodesGenerator = new VisibleNodesGenerator(root as TreeNode, { - compress: compressSingletonFolder, - }) + visibleNodesGenerator = new VisibleNodesGenerator(root as TreeNode, { + compress: compressSingletonFolder, + }) - await visibleNodesGenerator.init() + await visibleNodesGenerator.init() - tasksAfterRender.push(DOMHelper.focusSearchInput) - dispatch.call(setStateText, '') - dispatch.call(goTo, URLHelper.getCurrentPath(metaData.branchName)) + tasksAfterRender.push(DOMHelper.focusSearchInput) + dispatch.call(setStateText, '') + dispatch.call(goTo, URLHelper.getCurrentPath(metaData.branchName)) } const execAfterRender: MethodCreator = dispatch => () => { @@ -180,80 +179,98 @@ const handleKeyDown: MethodCreator< [React.KeyboardEvent] > = dispatch => event => { const { searched, visibleNodes } = dispatch.get() - if (!visibleNodes) return - const { nodes, focusedNode, expandedNodes, depths } = visibleNodes - function handleVerticalMove(index: number) { - if (0 <= index && index < nodes.length) { - DOMHelper.focusFileExplorer() - dispatch.call(focusNode, nodes[index], false) - } else { - DOMHelper.focusSearchInput() - dispatch.call(focusNode, null, false) - } + if (!visibleNodes) return + const { nodes, focusedNode, expandedNodes, depths } = visibleNodes + function handleVerticalMove(index: number) { + if (0 <= index && index < nodes.length) { + DOMHelper.focusFileExplorer() + dispatch.call(focusNode, nodes[index], false) + } else { + DOMHelper.focusSearchInput() + dispatch.call(focusNode, null, false) } + } - const { key } = event - // prevent document body scrolling if the keypress results in Gitako action - let muteEvent = true - if (focusedNode) { - const focusedNodeIndex = nodes.indexOf(focusedNode) - switch (key) { - case 'ArrowUp': - // focus on previous node - handleVerticalMove(focusedNodeIndex - 1) - break + const { key } = event + // prevent document body scrolling if the keypress results in Gitako action + let muteEvent = true + if (focusedNode) { + const focusedNodeIndex = nodes.indexOf(focusedNode) + switch (key) { + case 'ArrowUp': + // focus on previous node + handleVerticalMove(focusedNodeIndex - 1) + break - case 'ArrowDown': - // focus on next node - handleVerticalMove(focusedNodeIndex + 1) - break + case 'ArrowDown': + // focus on next node + handleVerticalMove(focusedNodeIndex + 1) + break - case 'ArrowLeft': + case 'ArrowLeft': + if (expandedNodes.has(focusedNode)) { + dispatch.call(setExpand, focusedNode, false) + } else { + // go forward to the start of the list, find the closest node with lower depth + const parentNode = getVisibleParentNode(nodes, focusedNode, depths) + if (parentNode) { + dispatch.call(focusNode, parentNode, false) + } + } + break + + // consider the two keys as 'confirm' key + case 'ArrowRight': + // expand node or focus on first content node or redirect to file page + if (focusedNode.type === 'tree') { if (expandedNodes.has(focusedNode)) { - dispatch.call(setExpand, focusedNode, false) + const nextNode = nodes[focusedNodeIndex + 1] + const d1 = depths.get(nextNode) + const d2 = depths.get(focusedNode) + if (d1 !== undefined && d2 !== undefined && d1 > d2) { + dispatch.call(focusNode, nextNode, false) + } } else { - // go forward to the start of the list, find the closest node with lower depth - const parentNode = getVisibleParentNode(nodes, focusedNode, depths) - if (parentNode) { - dispatch.call(focusNode, parentNode, false) - } + dispatch.call(setExpand, focusedNode, true) } + } else if (focusedNode.type === 'blob') { + if (focusedNode.url) DOMHelper.loadWithPJAX(focusedNode.url) + } else if (focusedNode.type === 'commit') { + window.open(focusedNode.url) + } + break + case 'Enter': + // expand node or redirect to file page + if (focusedNode.type === 'tree') { + if (searched) { + dispatch.call(goTo, focusedNode.path.split('/')) + } else { + dispatch.call(setExpand, focusedNode, true) + } + } else if (focusedNode.type === 'blob') { + if (searched) dispatch.call(goTo, focusedNode.path.split('/')) + else if (focusedNode.url) DOMHelper.loadWithPJAX(focusedNode.url) + } else if (focusedNode.type === 'commit') { + window.open(focusedNode.url) + } + break + default: + muteEvent = false + } + if (muteEvent) { + event.preventDefault() + } + } else { + // now search input is focused + if (nodes.length) { + switch (key) { + case 'ArrowDown': + DOMHelper.focusFileExplorer() + dispatch.call(focusNode, nodes[0], false) break - - // consider the two keys as 'confirm' key - case 'ArrowRight': - // expand node or focus on first content node or redirect to file page - if (focusedNode.type === 'tree') { - if (expandedNodes.has(focusedNode)) { - const nextNode = nodes[focusedNodeIndex + 1] - const d1 = depths.get(nextNode) - const d2 = depths.get(focusedNode) - if (d1 !== undefined && d2 !== undefined && d1 > d2) { - dispatch.call(focusNode, nextNode, false) - } - } else { - dispatch.call(setExpand, focusedNode, true) - } - } else if (focusedNode.type === 'blob') { - if (focusedNode.url) DOMHelper.loadWithPJAX(focusedNode.url) - } else if (focusedNode.type === 'commit') { - window.open(focusedNode.url) - } - break - case 'Enter': - // expand node or redirect to file page - if (focusedNode.type === 'tree') { - if (searched) { - dispatch.call(goTo, focusedNode.path.split('/')) - } else { - dispatch.call(setExpand, focusedNode, true) - } - } else if (focusedNode.type === 'blob') { - if (searched) dispatch.call(goTo, focusedNode.path.split('/')) - else if (focusedNode.url) DOMHelper.loadWithPJAX(focusedNode.url) - } else if (focusedNode.type === 'commit') { - window.open(focusedNode.url) - } + case 'ArrowUp': + DOMHelper.focusFileExplorer() + dispatch.call(focusNode, nodes[nodes.length - 1], false) break default: muteEvent = false @@ -261,26 +278,8 @@ const handleKeyDown: MethodCreator< if (muteEvent) { event.preventDefault() } - } else { - // now search input is focused - if (nodes.length) { - switch (key) { - case 'ArrowDown': - DOMHelper.focusFileExplorer() - dispatch.call(focusNode, nodes[0], false) - break - case 'ArrowUp': - DOMHelper.focusFileExplorer() - dispatch.call(focusNode, nodes[nodes.length - 1], false) - break - default: - muteEvent = false - } - if (muteEvent) { - event.preventDefault() - } - } } + } } const onFocusSearchBar: MethodCreator = dispatch => () => @@ -342,9 +341,9 @@ const focusNode: MethodCreator { const { visibleNodes } = dispatch.get() - if (!visibleNodes) return - visibleNodesGenerator.focusNode(node) - dispatch.call(updateVisibleNodes) + if (!visibleNodes) return + visibleNodesGenerator.focusNode(node) + dispatch.call(updateVisibleNodes) } const onNodeClick: MethodCreator = dispatch => node => { diff --git a/src/driver/core/SideBar.ts b/src/driver/core/SideBar.ts index 66c4adf..2631dde 100644 --- a/src/driver/core/SideBar.ts +++ b/src/driver/core/SideBar.ts @@ -11,9 +11,8 @@ import GitHubHelper, { import configHelper from 'utils/configHelper' import URLHelper from 'utils/URLHelper' import keyHelper from 'utils/keyHelper' -import { MethodCreator, promisifyGetState } from 'driver/connect' +import { MethodCreator, GetCreatedMethod } from 'driver/connect' import { Props } from 'components/SideBar' -import SettingsBar from 'components/SettingsBar' export type ConnectorState = { // initial width of side bar @@ -42,17 +41,17 @@ export type ConnectorState = { disabled: boolean initializingPromise: Promise | null - init: () => void - onPJAXEnd: () => void - onKeyDown: (e: KeyboardEvent) => string - toggleShowSideBar: () => void - toggleShowSettings: () => void - useListeners: (on: boolean) => void - onAccessTokenChange: SettingsBar['props']['onAccessTokenChange'] - onShortcutChange: SettingsBar['props']['onShortcutChange'] - setCopyFile: SettingsBar['props']['setCopyFile'] - setCopySnippet: SettingsBar['props']['setCopySnippet'] - setCompressSingleton: SettingsBar['props']['setCompressSingleton'] + init: GetCreatedMethod + onPJAXEnd: GetCreatedMethod + onKeyDown: GetCreatedMethod + toggleShowSideBar: GetCreatedMethod + toggleShowSettings: GetCreatedMethod + useListeners: GetCreatedMethod + onAccessTokenChange: GetCreatedMethod + onShortcutChange: GetCreatedMethod + setCopyFile: GetCreatedMethod + setCopySnippet: GetCreatedMethod + setCompressSingleton: GetCreatedMethod } const init: MethodCreator = dispatch => async () => { @@ -179,21 +178,21 @@ const handleError: MethodCreator = dispatch => a const onPJAXEnd: MethodCreator = dispatch => () => { const { metaData, copyFileButton, copySnippetButton } = dispatch.get() - DOMHelper.unmountTopProgressBar() - DOMHelper.decorateGitHubPageContent({ copyFileButton, copySnippetButton }) - const mergedMetaData = { ...metaData, ...URLHelper.parse() } - dispatch.call(setShouldShow, URLHelper.isInCodePage(mergedMetaData)) - dispatch.call(setMetaData, mergedMetaData) + DOMHelper.unmountTopProgressBar() + DOMHelper.decorateGitHubPageContent({ copyFileButton, copySnippetButton }) + const mergedMetaData = { ...metaData, ...URLHelper.parse() } + dispatch.call(setShouldShow, URLHelper.isInCodePage(mergedMetaData)) + dispatch.call(setMetaData, mergedMetaData) } const onKeyDown: MethodCreator = dispatch => e => { const { toggleShowSideBarShortcut } = dispatch.get() - if (toggleShowSideBarShortcut) { - const keys = keyHelper.parseEvent(e) - if (keys === toggleShowSideBarShortcut) { - dispatch.call(toggleShowSideBar) - } + if (toggleShowSideBarShortcut) { + const keys = keyHelper.parseEvent(e) + if (keys === toggleShowSideBarShortcut) { + dispatch.call(toggleShowSideBar) } + } } const toggleShowSideBar: MethodCreator = dispatch => () => @@ -275,13 +274,13 @@ const useListeners: MethodCreator = dispatch = const $onKeyDown = dispatch.call.bind(dispatch, onKeyDown) return on => { const { disabled } = dispatch.get() - if (on && !disabled) { - window.addEventListener('pjax:complete', $onPJAXEnd) - window.addEventListener('keydown', $onKeyDown) - } else { - window.removeEventListener('pjax:complete', $onPJAXEnd) - window.removeEventListener('keydown', $onKeyDown) - } + if (on && !disabled) { + window.addEventListener('pjax:complete', $onPJAXEnd) + window.addEventListener('keydown', $onKeyDown) + } else { + window.removeEventListener('pjax:complete', $onPJAXEnd) + window.removeEventListener('keydown', $onKeyDown) + } } }