mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
chore: reorganize utility files
This commit is contained in:
parent
78a4668a08
commit
05f670bb90
16 changed files with 105 additions and 96 deletions
|
|
@ -9,7 +9,8 @@ import * as React from 'react'
|
|||
import useEvent from 'react-use/esm/useEvent'
|
||||
import { FixedSizeList as List, ListChildComponentProps, ListProps } from 'react-window'
|
||||
import { cx } from 'utils/cx'
|
||||
import { useOnLocationChange, usePrevious } from 'utils/hooks'
|
||||
import { useOnLocationChange } from 'utils/hooks/useOnLocationChange'
|
||||
import { usePrevious } from 'utils/hooks/usePrevious'
|
||||
import { getCurrentPath } from 'utils/URLHelper'
|
||||
import { TreeNode, VisibleNodes } from 'utils/VisibleNodesGenerator'
|
||||
import { Icon } from './Icon'
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ import * as React from 'react'
|
|||
import { cx } from 'utils/cx'
|
||||
import { bodySpacingClassName } from 'utils/DOMHelper'
|
||||
import * as features from 'utils/features'
|
||||
import { useMediaStyleSheet, useWindowSize } from 'utils/hooks'
|
||||
import { useMediaStyleSheet } from 'utils/hooks/useMediaStyleSheet'
|
||||
import { useWindowSize } from 'utils/hooks/useWindowSize'
|
||||
|
||||
export type Size = number
|
||||
type Props = {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { Icon } from 'components/Icon'
|
|||
import { VERSION } from 'env'
|
||||
import * as React from 'react'
|
||||
import { Config } from 'utils/configHelper'
|
||||
import { useStates } from 'utils/hooks'
|
||||
import { useStates } from 'utils/hooks/useStates'
|
||||
import { AccessTokenSettings } from './settings/AccessTokenSettings'
|
||||
import { FileTreeIconSettings } from './settings/FileTreeIconSettings'
|
||||
import { ShortcutSettings } from './settings/ShortcutSettings'
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import useEvent from 'react-use/esm/useEvent'
|
|||
import { cx } from 'utils/cx'
|
||||
import * as DOMHelper from 'utils/DOMHelper'
|
||||
import { JSONRequest, parseURLSearch } from 'utils/general'
|
||||
import { useDidUpdate } from 'utils/hooks'
|
||||
import { useDidUpdate } from 'utils/hooks/useDidUpdate'
|
||||
import * as keyHelper from 'utils/keyHelper'
|
||||
import * as URLHelper from 'utils/URLHelper'
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { wikiLinks } from 'components/SettingsBar'
|
|||
import { useConfigs } from 'containers/ConfigsContext'
|
||||
import { oauth } from 'env'
|
||||
import * as React from 'react'
|
||||
import { useStates } from 'utils/hooks'
|
||||
import { useStates } from 'utils/hooks/useStates'
|
||||
|
||||
const ACCESS_TOKEN_REGEXP = /^[0-9a-f]{40}$/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useConfigs } from 'containers/ConfigsContext'
|
||||
import * as React from 'react'
|
||||
import { friendlyFormatShortcut } from 'utils/general'
|
||||
import { useStates } from 'utils/hooks'
|
||||
import { useStates } from 'utils/hooks/useStates'
|
||||
import * as keyHelper from 'utils/keyHelper'
|
||||
|
||||
type Props = {}
|
||||
|
|
|
|||
|
|
@ -1,90 +0,0 @@
|
|||
import * as React from 'react'
|
||||
import useLocation from 'react-use/esm/useLocation'
|
||||
import { createStyleSheet, setStyleSheetMedia } from './general'
|
||||
|
||||
export function useWindowSize(
|
||||
callback: (width: number) => void,
|
||||
deps?: ReadonlyArray<any> | undefined,
|
||||
) {
|
||||
React.useEffect(() => {
|
||||
const resizeListener: (this: Window, ev: UIEvent) => void = () => callback(window.innerWidth)
|
||||
|
||||
window.addEventListener('resize', resizeListener)
|
||||
return () => window.removeEventListener('resize', resizeListener)
|
||||
}, deps)
|
||||
}
|
||||
|
||||
export function useMediaStyleSheet(
|
||||
content: string,
|
||||
getMediaQuery: (width: number) => string[],
|
||||
size: number,
|
||||
) {
|
||||
const style = React.useRef<HTMLStyleElement>()
|
||||
|
||||
// this order may prevent first effect actually occur at first time
|
||||
React.useEffect(() => {
|
||||
setSheetMedia()
|
||||
}, [size])
|
||||
React.useEffect(() => {
|
||||
style.current = createStyleSheet(content)
|
||||
setSheetMedia()
|
||||
}, [])
|
||||
|
||||
function setSheetMedia() {
|
||||
if (style.current)
|
||||
setStyleSheetMedia(
|
||||
style.current,
|
||||
getMediaQuery(size)
|
||||
.map(query => `(${query})`)
|
||||
.join(' and '),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export function usePrevious<T>(newValue: T) {
|
||||
const previousRef = React.useRef(newValue)
|
||||
React.useEffect(() => {
|
||||
previousRef.current = newValue
|
||||
})
|
||||
return previousRef.current
|
||||
}
|
||||
|
||||
export function useStates<S>(
|
||||
initialState: S | (() => S),
|
||||
): { val: S; set: React.Dispatch<React.SetStateAction<S>> } {
|
||||
const [val, set] = React.useState(initialState)
|
||||
return { val, set }
|
||||
}
|
||||
|
||||
export function useAsyncMemo<T, D extends any[] | readonly any[]>(
|
||||
factory: (dependencies: D) => T | Promise<T>,
|
||||
deps: D,
|
||||
initialValue: T,
|
||||
): T {
|
||||
const firstTime = React.useRef(true)
|
||||
const state = useStates<T>(() => initialValue)
|
||||
React.useEffect(() => {
|
||||
if (firstTime.current) firstTime.current = false
|
||||
Promise.resolve(factory(deps)).then(consumed => state.set(() => consumed))
|
||||
}, deps)
|
||||
return state.val
|
||||
}
|
||||
|
||||
export function useDidUpdate(effect: React.EffectCallback, deps?: React.DependencyList) {
|
||||
const firstTime = React.useRef(true)
|
||||
React.useEffect(() => {
|
||||
if (firstTime.current) {
|
||||
firstTime.current = false
|
||||
return
|
||||
}
|
||||
return effect()
|
||||
}, deps)
|
||||
}
|
||||
|
||||
export function useOnLocationChange(
|
||||
callback: React.EffectCallback,
|
||||
extraDeps: React.DependencyList = [],
|
||||
) {
|
||||
const { href, pathname, search } = useLocation()
|
||||
React.useEffect(callback, [href, pathname, search, ...extraDeps])
|
||||
}
|
||||
16
src/utils/hooks/useAsyncMemo.ts
Normal file
16
src/utils/hooks/useAsyncMemo.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import * as React from 'react'
|
||||
import { useStates } from './useStates'
|
||||
|
||||
export function useAsyncMemo<T, D extends any[] | readonly any[]>(
|
||||
factory: (dependencies: D) => T | Promise<T>,
|
||||
deps: D,
|
||||
initialValue: T,
|
||||
): T {
|
||||
const firstTime = React.useRef(true)
|
||||
const state = useStates<T>(() => initialValue)
|
||||
React.useEffect(() => {
|
||||
if (firstTime.current) firstTime.current = false
|
||||
Promise.resolve(factory(deps)).then(consumed => state.set(() => consumed))
|
||||
}, deps)
|
||||
return state.val
|
||||
}
|
||||
12
src/utils/hooks/useDidUpdate.ts
Normal file
12
src/utils/hooks/useDidUpdate.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import * as React from 'react'
|
||||
|
||||
export function useDidUpdate(effect: React.EffectCallback, deps?: React.DependencyList) {
|
||||
const firstTime = React.useRef(true)
|
||||
React.useEffect(() => {
|
||||
if (firstTime.current) {
|
||||
firstTime.current = false
|
||||
return
|
||||
}
|
||||
return effect()
|
||||
}, deps)
|
||||
}
|
||||
27
src/utils/hooks/useMediaStyleSheet.ts
Normal file
27
src/utils/hooks/useMediaStyleSheet.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import * as React from 'react'
|
||||
import { createStyleSheet, setStyleSheetMedia } from '../general'
|
||||
|
||||
export function useMediaStyleSheet(
|
||||
content: string,
|
||||
getMediaQuery: (width: number) => string[],
|
||||
size: number,
|
||||
) {
|
||||
const style = React.useRef<HTMLStyleElement>()
|
||||
// this order may prevent first effect actually occur at first time
|
||||
React.useEffect(() => {
|
||||
setSheetMedia()
|
||||
}, [size])
|
||||
React.useEffect(() => {
|
||||
style.current = createStyleSheet(content)
|
||||
setSheetMedia()
|
||||
}, [])
|
||||
function setSheetMedia() {
|
||||
if (style.current)
|
||||
setStyleSheetMedia(
|
||||
style.current,
|
||||
getMediaQuery(size)
|
||||
.map(query => `(${query})`)
|
||||
.join(' and '),
|
||||
)
|
||||
}
|
||||
}
|
||||
10
src/utils/hooks/useOnLocationChange.ts
Normal file
10
src/utils/hooks/useOnLocationChange.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import * as React from 'react'
|
||||
import useLocation from 'react-use/esm/useLocation'
|
||||
|
||||
export function useOnLocationChange(
|
||||
callback: React.EffectCallback,
|
||||
extraDeps: React.DependencyList = [],
|
||||
) {
|
||||
const { href, pathname, search } = useLocation()
|
||||
React.useEffect(callback, [href, pathname, search, ...extraDeps])
|
||||
}
|
||||
9
src/utils/hooks/usePrevious.ts
Normal file
9
src/utils/hooks/usePrevious.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import * as React from 'react'
|
||||
|
||||
export function usePrevious<T>(newValue: T) {
|
||||
const previousRef = React.useRef(newValue)
|
||||
React.useEffect(() => {
|
||||
previousRef.current = newValue
|
||||
})
|
||||
return previousRef.current
|
||||
}
|
||||
11
src/utils/hooks/useStates.ts
Normal file
11
src/utils/hooks/useStates.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import * as React from 'react'
|
||||
|
||||
export function useStates<S>(
|
||||
initialState: S | (() => S),
|
||||
): {
|
||||
val: S
|
||||
set: React.Dispatch<React.SetStateAction<S>>
|
||||
} {
|
||||
const [val, set] = React.useState(initialState)
|
||||
return { val, set }
|
||||
}
|
||||
12
src/utils/hooks/useWindowSize.ts
Normal file
12
src/utils/hooks/useWindowSize.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import * as React from 'react'
|
||||
|
||||
export function useWindowSize(
|
||||
callback: (width: number) => void,
|
||||
deps?: ReadonlyArray<any> | undefined,
|
||||
) {
|
||||
React.useEffect(() => {
|
||||
const resizeListener: (this: Window, ev: UIEvent) => void = () => callback(window.innerWidth)
|
||||
window.addEventListener('resize', resizeListener)
|
||||
return () => window.removeEventListener('resize', resizeListener)
|
||||
}, deps)
|
||||
}
|
||||
Loading…
Reference in a new issue