fix: 修复组件未能还原状态提示异常,改进二等分结果刷新页面后的行为

This commit is contained in:
JLoeve 2023-02-05 15:58:53 +08:00
parent f2f9eb9a3e
commit de541ec953
3 changed files with 73 additions and 45 deletions

View File

@ -1,10 +1,10 @@
import { DialogInstance, showDialog } from '@/core/dialog'
import type { Settings } from '@/core/settings/types'
import { Toast } from '@/core/toast'
import { mountVueComponent } from '@/core/utils'
import { getRandomId, mountVueComponent, sleep } from '@/core/utils'
import { useScopedConsole } from '@/core/utils/log'
import type { RecordValue } from '../types'
import type { BisectNext } from './bisect'
import type { BisectNext, BisectReturn } from './bisect'
import { bisect } from './bisect'
import { BisectorOptions } from './options'
import ResultToastContent from './ResultToastContent.vue'
@ -13,7 +13,7 @@ type UserComponent = RecordValue<Settings['userComponents']>
let bisectorOptions: BisectorOptions
let scopedConsole: ReturnType<typeof useScopedConsole>
let bisectorGenerator: ReturnType<typeof bisect>
let bisectorGenerator: Generator<BisectNext<UserComponent>, BisectReturn<UserComponent>>
let groupedComponents: Awaited<ReturnType<typeof classifyComponents>>
let dialog: DialogInstance
@ -80,23 +80,25 @@ export const stop = async () => {
scopedConsole?.log('stop - 准备停止组件二等分')
dialog?.close()
const { configurableUserComponents } = await classifyComponents()
const unmatchedComponentNames = []
const unmatchedComponents: UserComponent[] = []
for (const [componentName, componentSettings] of Object.entries(configurableUserComponents)) {
const originalStatus = bisectorOptions.originalComponentEnableState?.[componentName]
if (originalStatus == null) {
unmatchedComponentNames.push(componentName)
unmatchedComponents.push(componentSettings)
continue
}
componentSettings.settings.enabled = originalStatus
}
if (unmatchedComponentNames.length) {
scopedConsole?.warn(
`stop - 部分组件未能还原状态:${getComponentNames(unmatchedComponentNames)}`,
)
if (unmatchedComponents.length) {
const msg = `部分组件未能还原状态:${getComponentNames(unmatchedComponents)}`
scopedConsole?.warn(`stop - ${msg}`)
Toast.error(msg, '组件二等分')
await sleep(3e3)
}
scopedConsole?.log('stop - 清理状态')
bisectorGenerator = null
bisectorOptions.bisectInitialState = {}
bisectorOptions.originalComponentEnableState = {}
scopedConsole?.log('stop - 重载页面')
location.reload()
}
@ -109,24 +111,20 @@ export const next = async (seeingBad?: boolean, autoReload?: boolean) => {
seeingBad == null ? '未知' : seeingBad ? '异常' : '正常'
}`,
)
const { done, value } = bisectorGenerator.next(seeingBad) as unknown as {
done: boolean
value: BisectNext<UserComponent> | UserComponent
}
const { done, value } = bisectorGenerator.next(seeingBad)
if (done) {
const elementId = `bisector-result-toast-content-${Math.floor(
Math.random() * (Number.MAX_SAFE_INTEGER + 1),
)}`
Toast.info(/* html */ `<div id="${elementId}"></div>`, '二等分结果')
setTimeout(() => {
const vm = mountVueComponent<{ userComponent: UserComponent }>(
ResultToastContent,
`#${elementId}`,
)
vm.userComponent = value as UserComponent
vm.$on('restore', () => {
stop()
})
const { low, high } = value
bisectorOptions.bisectInitialState = { low, high }
const elementId = `bisector-result-toast-content-${getRandomId()}`
Toast.info(/* html */ `<div id="${elementId}"></div>`, '组件二等分结果')
await sleep()
const vm = mountVueComponent<{ userComponent: UserComponent }>(
ResultToastContent,
`#${elementId}`,
)
vm.userComponent = value.target
vm.$on('restore', () => {
stop()
})
} else {
const { slice, low, high } = value as BisectNext<UserComponent>

View File

@ -8,62 +8,84 @@ export interface BisectNext<O> {
rouge: number
}
export interface BisectReturn<O> extends BisectNext<O> {
target: O
}
export interface InitialState {
low?: number
high?: number
}
export function* bisectLeft<O>(data: readonly O[], initialState?: InitialState) {
export function* bisectLeft<O>(
data: readonly O[],
initialState?: InitialState,
): Generator<BisectNext<O>, BisectReturn<O>> {
let low = initialState?.low ?? 0
let high = initialState?.high ?? data.length
let mid = (low + high) >>> 1
let mid: number
while (true) {
const seeingBad = yield ({
while (low + 1 < high) {
mid = (low + high) >>> 1
const seeingBad = yield {
low,
high,
mid,
slice: data.slice(low, mid),
rouge: ~~Math.log2(high - low),
} as BisectNext<O>) || false
}
if (seeingBad) {
high = mid
} else {
low = mid
}
if (low + 1 < high) {
mid = (low + high) >>> 1
} else {
return data[low]
}
}
return {
low,
high,
mid,
slice: data.slice(low, mid),
rouge: ~~Math.log2(high - low),
target: data[low],
}
}
export function* bisectRight<O>(data: readonly O[], initialState?: InitialState) {
export function* bisectRight<O>(
data: readonly O[],
initialState?: InitialState,
): Generator<BisectNext<O>, BisectReturn<O>> {
let low = initialState?.low ?? 0
let high = initialState?.high ?? data.length
let mid = (low + high) >>> 1
while (true) {
const seeingBad = yield ({
while (low + 1 < high) {
mid = (low + high) >>> 1
const seeingBad = yield {
low,
high,
mid,
slice: data.slice(mid, high),
rouge: ~~Math.log2(high - low),
} as BisectNext<O>) || false
}
if (seeingBad) {
low = mid
} else {
high = mid
}
if (low + 1 < high) {
mid = (low + high) >>> 1
} else {
return data[low]
}
}
return {
low,
high,
mid,
slice: data.slice(low, mid),
rouge: ~~Math.log2(high - low),
target: data[low],
}
}

View File

@ -634,3 +634,11 @@ export const getRandomId = (length = 8) => {
.join('')
.substring(0, length)
}
/**
*
*
* @param ms setTimeout
* @returns
*/
export const sleep = (ms?: number) => new Promise(resolve => setTimeout(resolve, ms))