navigateBack.uts 3.1 KB
Newer Older
DCloud-yyl's avatar
DCloud-yyl 已提交
1 2 3 4 5 6
import {
    ANIMATION_DURATION,
    ANIMATION_TYPE,
    NAVIGATE_BACK,
    ON_LAST_PAGE_BACK_PRESS,
    ON_SHOW,
DCloud-yyl's avatar
DCloud-yyl 已提交
7
    Page,
DCloud-yyl's avatar
DCloud-yyl 已提交
8 9 10 11 12 13 14 15 16 17
    invokeAfterRouteHooks,
    invokeBeforeRouteHooks,
    invokeCurrentAppHook,
    invokeCurrentPageHook,
    invokePageOnBackPress,
    isTabPage,
} from '@dcloudio/uni-runtime'
import { NavigateBackOptions, NavigateBackSuccess } from '../interface.uts'
import {
    DEFAULT_ANIMATION_DURATION,
DCloud-yyl's avatar
DCloud-yyl 已提交
18
    DEFAULT_ANIMATION_NAVIGATE_BACK,
DCloud-yyl's avatar
DCloud-yyl 已提交
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
    DEFAULT_ANIMATION_OUT,
} from '../constants.uts'
import { NavigateBackFailImpl } from '../unierror.uts'
import { isDirectPage, reLaunchEntryPage } from './direct.uts'

export const navigateBack = defineAsyncApi<
    NavigateBackOptions | null,
    NavigateBackSuccess
>(NAVIGATE_BACK, (options: NavigateBackOptions | null, res: ApiExecutor) => {
    _navigateBack(NAVIGATE_BACK, options, res)
})

export const _navigateBack = (
    from: string,
    options: NavigateBackOptions | null,
    res: ApiExecutor | null,
) => {
    const pages = getCurrentPages()
    if (pages.length == 0) {
        if (res !== null) {
            res.reject(new NavigateBackFailImpl(`getCurrentPage is empty`))
        }
        return
    }
    const currentPage = pages[pages.length - 1]
DCloud-yyl's avatar
DCloud-yyl 已提交
44 45 46 47 48 49 50 51
    let onBackPressRes = invokePageOnBackPress(currentPage.vm!, from)
    if (onBackPressRes !== true) {
        const dialogPages = currentPage.getDialogPages()
        if (dialogPages.length > 0) {
            const dialogPage = dialogPages[dialogPages.length - 1]
            onBackPressRes = invokePageOnBackPress(dialogPage.$vm as Page, from)
        }
    }
DCloud-yyl's avatar
DCloud-yyl 已提交
52 53 54 55 56 57 58
    if (onBackPressRes == true) {
        if (res !== null) {
            res.resolve(null)
        }
        return
    }
    invokeBeforeRouteHooks(NAVIGATE_BACK)
DCloud-yyl's avatar
DCloud-yyl 已提交
59
    if (isDirectPage(currentPage.vm!)) {
DCloud-yyl's avatar
DCloud-yyl 已提交
60
        reLaunchEntryPage()
DCloud-yyl's avatar
DCloud-yyl 已提交
61
    } else if (isTabPage(currentPage.vm!) || pages.length == 1) {
DCloud-yyl's avatar
DCloud-yyl 已提交
62 63 64 65 66 67 68 69 70 71 72 73
        quit()
    } else {
        if (options?.delta !== null && options?.delta! > 1) {
            const length = pages.length
            options!.delta = Math.min(options!.delta!, length - 1)
            // 中间页隐藏
            const deltaPages = pages.splice(
                length - options!.delta!,
                options!.delta! - 1,
            )
            deltaPages.reverse()
            deltaPages.forEach(deltaPage => {
DCloud-yyl's avatar
DCloud-yyl 已提交
74
                deltaPage.vm!.$close(
DCloud-yyl's avatar
DCloud-yyl 已提交
75 76 77 78
                    new Map<string, any | null>([[ANIMATION_TYPE, 'none']]),
                )
            })
        }
DCloud-yyl's avatar
DCloud-yyl 已提交
79
        currentPage.vm!.$close(
DCloud-yyl's avatar
DCloud-yyl 已提交
80 81 82
            new Map<string, any | null>([
                [
                    ANIMATION_TYPE,
DCloud-yyl's avatar
DCloud-yyl 已提交
83
                    options?.animationType ?? DEFAULT_ANIMATION_NAVIGATE_BACK,
DCloud-yyl's avatar
DCloud-yyl 已提交
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
                ],
                [
                    ANIMATION_DURATION,
                    options?.animationDuration ?? DEFAULT_ANIMATION_DURATION,
                ],
            ]),
        )
        invokeCurrentPageHook(ON_SHOW)
        invokeAfterRouteHooks(NAVIGATE_BACK)
    }
    if (res !== null) {
        res.resolve(null)
    }
}

function quit() {
    invokeCurrentAppHook(ON_LAST_PAGE_BACK_PRESS)
}