提交 4d414c76 编写于 作者: fxy060608's avatar fxy060608

feat(app): add redirectTo

上级 17298658
......@@ -4417,8 +4417,11 @@ var serviceContext = (function (vue) {
type: Number,
},
}, createAnimationProtocol(ANIMATION_OUT));
const RedirectToProtocol = BaseRouteProtocol;
const NavigateToOptions =
/*#__PURE__*/ createRouteOptions(API_NAVIGATE_TO);
const RedirectToOptions =
/*#__PURE__*/ createRouteOptions(API_REDIRECT_TO);
const NavigateBackOptions = {
formatArgs: {
delta(value, params) {
......@@ -8986,6 +8989,67 @@ var serviceContext = (function (vue) {
return new InteractiveAd(options);
}, CreateInteractiveAdProtocol, CreateInteractiveAdOptions));
const pages = [];
function addCurrentPage(page) {
pages.push(page);
}
function getCurrentPages$1() {
const curPages = [];
pages.forEach((page) => {
if (page.__isTabBar) {
if (page.$.__isActive) {
curPages.push(page);
}
}
else {
curPages.push(page);
}
});
return curPages;
}
function removePage(curPage) {
const index = pages.findIndex((page) => page === curPage);
if (index === -1) {
return;
}
if (!curPage.$page.meta.isNVue) {
curPage.$.appContext.app.unmount();
}
pages.splice(index, 1);
if ((process.env.NODE_ENV !== 'production')) {
console.log(formatLog('removePage', curPage.$page));
}
}
let lastStatusBarStyle;
let oldSetStatusBarStyle = plus.navigator.setStatusBarStyle;
function newSetStatusBarStyle(style) {
lastStatusBarStyle = style;
oldSetStatusBarStyle(style);
}
plus.navigator.setStatusBarStyle = newSetStatusBarStyle;
function setStatusBarStyle(statusBarStyle) {
if (!statusBarStyle) {
const pages = getCurrentPages();
if (!pages.length) {
return;
}
statusBarStyle = pages[pages.length - 1].$page
.statusBarStyle;
if (!statusBarStyle || statusBarStyle === lastStatusBarStyle) {
return;
}
}
if (statusBarStyle === lastStatusBarStyle) {
return;
}
if ((process.env.NODE_ENV !== 'production')) {
console.log(formatLog('setStatusBarStyle', statusBarStyle));
}
lastStatusBarStyle = statusBarStyle;
plus.navigator.setStatusBarStyle(statusBarStyle);
}
let pendingNavigator = false;
function setPendingNavigator(path, callback, msg) {
pendingNavigator = {
......@@ -8997,7 +9061,7 @@ var serviceContext = (function (vue) {
console.log(formatLog('setPendingNavigator', path, msg));
}
}
function navigate(path, callback, isAppLaunch) {
function navigate(path, callback, isAppLaunch = false) {
if (!isAppLaunch && pendingNavigator) {
return console.error(`Waiting to navigate to: ${pendingNavigator.path}, do not operate continuously: ${path}.`);
}
......@@ -9119,6 +9183,91 @@ var serviceContext = (function (vue) {
});
}
const navigateBack = defineAsyncApi(API_NAVIGATE_BACK, (args, { resolve, reject }) => {
const page = getCurrentPage();
if (!page) {
return reject(`getCurrentPages is empty`);
}
if (invokeHook(page, 'onBackPress', {
from: args.from,
})) {
return resolve();
}
uni.hideToast();
uni.hideLoading();
if (page.$page.meta.isQuit) {
quit();
}
else if (page.$page.id === 1 && __uniConfig.realEntryPagePath) {
// condition
__uniConfig.entryPagePath = __uniConfig.realEntryPagePath;
delete __uniConfig.realEntryPagePath;
uni.reLaunch({
url: '/' + __uniConfig.entryPagePath,
});
}
else {
const { delta, animationType, animationDuration } = args;
back(delta, animationType, animationDuration);
}
return resolve();
}, NavigateBackProtocol, NavigateBackOptions);
let firstBackTime = 0;
function quit() {
initI18nAppMsgsOnce();
if (!firstBackTime) {
firstBackTime = Date.now();
plus.nativeUI.toast(useI18n().t('uni.app.quit'));
setTimeout(() => {
firstBackTime = 0;
}, 2000);
}
else if (Date.now() - firstBackTime < 2000) {
plus.runtime.quit();
}
}
function back(delta, animationType, animationDuration) {
const pages = getCurrentPages();
const len = pages.length;
const currentPage = pages[len - 1];
if (delta > 1) {
// 中间页隐藏
pages
.slice(len - delta, len - 1)
.reverse()
.forEach((deltaPage) => {
closeWebview(plus.webview.getWebviewById(deltaPage.$page.id + ''), 'none', 0);
});
}
const backPage = function (webview) {
if (animationType) {
closeWebview(webview, animationType, animationDuration || ANI_DURATION);
}
else {
if (currentPage.$page.openType === 'redirectTo') {
// 如果是 redirectTo 跳转的,需要指定 back 动画
closeWebview(webview, ANI_CLOSE, ANI_DURATION);
}
else {
closeWebview(webview, 'auto');
}
}
pages
.slice(len - delta, len)
.forEach((page) => removePage(page));
setStatusBarStyle();
// 前一个页面触发 onShow
invokeHook('onShow');
};
const webview = plus.webview.getWebviewById(currentPage.$page.id + '');
if (!currentPage.__uniapp_webview) {
return backPage(webview);
}
backWebview(webview, () => {
backPage(webview);
});
}
class UniPageNode extends UniNode {
constructor(pageId, options, setup = false) {
super(NODE_TYPE_PAGE, '#page', null);
......@@ -9333,38 +9482,6 @@ var serviceContext = (function (vue) {
return new UniPageNode(pageId, pageOptions, setup);
}
const pages = [];
function addCurrentPage(page) {
pages.push(page);
}
function getCurrentPages$1() {
const curPages = [];
pages.forEach((page) => {
if (page.__isTabBar) {
if (page.$.__isActive) {
curPages.push(page);
}
}
else {
curPages.push(page);
}
});
return curPages;
}
function removePage(curPage) {
const index = pages.findIndex((page) => page === curPage);
if (index === -1) {
return;
}
if (!curPage.$page.meta.isNVue) {
curPage.$.appContext.app.unmount();
}
pages.splice(index, 1);
if ((process.env.NODE_ENV !== 'production')) {
console.log(formatLog('removePage', curPage.$page));
}
}
function setupPage(component) {
const oldSetup = component.setup;
component.inheritAttrs = false; // 禁止继承 __pageId 等属性,避免告警
......@@ -9554,117 +9671,56 @@ var serviceContext = (function (vue) {
];
}
let lastStatusBarStyle;
let oldSetStatusBarStyle = plus.navigator.setStatusBarStyle;
function newSetStatusBarStyle(style) {
lastStatusBarStyle = style;
oldSetStatusBarStyle(style);
}
plus.navigator.setStatusBarStyle = newSetStatusBarStyle;
function setStatusBarStyle(statusBarStyle) {
if (!statusBarStyle) {
const pages = getCurrentPages();
if (!pages.length) {
return;
}
statusBarStyle = pages[pages.length - 1].$page
.statusBarStyle;
if (!statusBarStyle || statusBarStyle === lastStatusBarStyle) {
return;
}
}
if (statusBarStyle === lastStatusBarStyle) {
return;
}
if ((process.env.NODE_ENV !== 'production')) {
console.log(formatLog('setStatusBarStyle', statusBarStyle));
}
lastStatusBarStyle = statusBarStyle;
plus.navigator.setStatusBarStyle(statusBarStyle);
}
const navigateBack = defineAsyncApi(API_NAVIGATE_BACK, (args, { resolve, reject }) => {
const page = getCurrentPage();
if (!page) {
return reject(`getCurrentPages is empty`);
}
if (invokeHook(page, 'onBackPress', {
from: args.from,
})) {
return resolve();
}
uni.hideToast();
uni.hideLoading();
if (page.$page.meta.isQuit) {
quit();
}
else if (page.$page.id === 1 && __uniConfig.realEntryPagePath) {
// condition
__uniConfig.entryPagePath = __uniConfig.realEntryPagePath;
delete __uniConfig.realEntryPagePath;
uni.reLaunch({
url: '/' + __uniConfig.entryPagePath,
const redirectTo = defineAsyncApi(API_REDIRECT_TO, ({ url }, { resolve, reject }) => {
const { path, query } = parseUrl(url);
navigate(path, () => {
_redirectTo({
url,
path,
query,
})
.then(resolve)
.catch(reject);
});
}, RedirectToProtocol, RedirectToOptions);
function _redirectTo({ url, path, query, }) {
// TODO exists
// if (exists === 'back') {
// const existsPageIndex = findExistsPageIndex(url)
// if (existsPageIndex !== -1) {
// const delta = len - existsPageIndex
// if (delta > 0) {
// navigateBack({
// delta,
// })
// invoke(callbackId, {
// errMsg: 'redirectTo:ok',
// })
// return
// }
// }
// }
const lastPage = getCurrentPage();
lastPage && removePage(lastPage);
return new Promise((resolve) => {
showWebview(registerPage({
url,
path,
query,
openType: 'redirectTo',
}), 'none', 0, () => {
if (lastPage) {
const webview = lastPage
.$getAppWebview();
// TODO preload
// if (webview.__preload__) {
// removePreloadWebview(webview)
// }
webview.close('none');
}
else {
const { delta, animationType, animationDuration } = args;
back(delta, animationType, animationDuration);
}
return resolve();
}, NavigateBackProtocol, NavigateBackOptions);
let firstBackTime = 0;
function quit() {
initI18nAppMsgsOnce();
if (!firstBackTime) {
firstBackTime = Date.now();
plus.nativeUI.toast(useI18n().t('uni.app.quit'));
setTimeout(() => {
firstBackTime = 0;
}, 2000);
}
else if (Date.now() - firstBackTime < 2000) {
plus.runtime.quit();
}
}
function back(delta, animationType, animationDuration) {
const pages = getCurrentPages();
const len = pages.length;
const currentPage = pages[len - 1];
if (delta > 1) {
// 中间页隐藏
pages
.slice(len - delta, len - 1)
.reverse()
.forEach((deltaPage) => {
closeWebview(plus.webview.getWebviewById(deltaPage.$page.id + ''), 'none', 0);
resolve(undefined);
});
}
const backPage = function (webview) {
if (animationType) {
closeWebview(webview, animationType, animationDuration || ANI_DURATION);
}
else {
if (currentPage.$page.openType === 'redirectTo') {
// 如果是 redirectTo 跳转的,需要制定 back 动画
closeWebview(webview, ANI_CLOSE, ANI_DURATION);
}
else {
closeWebview(webview, 'auto');
}
}
pages
.slice(len - delta, len)
.forEach((page) => removePage(page));
setStatusBarStyle();
// 前一个页面触发 onShow
invokeHook('onShow');
};
const webview = plus.webview.getWebviewById(currentPage.$page.id + '');
if (!currentPage.__uniapp_webview) {
return backPage(webview);
}
backWebview(webview, () => {
backPage(webview);
});
}
......@@ -9795,8 +9851,9 @@ var serviceContext = (function (vue) {
createFullScreenVideoAd: createFullScreenVideoAd,
createInterstitialAd: createInterstitialAd,
createInteractiveAd: createInteractiveAd,
navigateBack: navigateBack,
navigateTo: navigateTo,
navigateBack: navigateBack
redirectTo: redirectTo
});
let invokeViewMethodId = 0;
......
......@@ -52,8 +52,9 @@ export * from './ad/fullScreenVideoAd'
export * from './ad/interstitialAd'
export * from './ad/interactiveAd'
export * from './route/navigateTo'
export * from './route/navigateBack'
export * from './route/navigateTo'
export * from './route/redirectTo'
export {
upx2px,
......
......@@ -94,7 +94,7 @@ function back(
closeWebview(webview, animationType, animationDuration || ANI_DURATION)
} else {
if (currentPage.$page.openType === 'redirectTo') {
// 如果是 redirectTo 跳转的,需要定 back 动画
// 如果是 redirectTo 跳转的,需要定 back 动画
closeWebview(webview, ANI_CLOSE, ANI_DURATION)
} else {
closeWebview(webview, 'auto')
......
import {
API_REDIRECT_TO,
API_TYPE_REDIRECT_TO,
defineAsyncApi,
RedirectToOptions,
RedirectToProtocol,
} from '@dcloudio/uni-api'
import { parseUrl } from '@dcloudio/uni-shared'
import { getCurrentPage } from '@dcloudio/uni-core'
import { removePage } from '../../framework/page/getCurrentPages'
import { registerPage } from '../../framework/page'
import { navigate } from './utils'
import { showWebview } from './webview'
import { setStatusBarStyle } from '../../statusBar'
import { ComponentPublicInstance } from 'vue'
export const redirectTo = defineAsyncApi<API_TYPE_REDIRECT_TO>(
API_REDIRECT_TO,
({ url }, { resolve, reject }) => {
const { path, query } = parseUrl(url)
navigate(path, () => {
_redirectTo({
url,
path,
query,
})
.then(resolve)
.catch(reject)
})
},
RedirectToProtocol,
RedirectToOptions
)
interface RedirectToOptions {
url: string
path: string
query: Record<string, any>
}
function _redirectTo({
url,
path,
query,
}: RedirectToOptions): Promise<undefined> {
// TODO exists
// if (exists === 'back') {
// const existsPageIndex = findExistsPageIndex(url)
// if (existsPageIndex !== -1) {
// const delta = len - existsPageIndex
// if (delta > 0) {
// navigateBack({
// delta,
// })
// invoke(callbackId, {
// errMsg: 'redirectTo:ok',
// })
// return
// }
// }
// }
const lastPage = getCurrentPage()
lastPage && removePage(lastPage)
return new Promise((resolve) => {
showWebview(
registerPage({
url,
path,
query,
openType: 'redirectTo',
}),
'none',
0,
() => {
if (lastPage) {
const webview = (lastPage as ComponentPublicInstance)
.$getAppWebview!()
// TODO preload
// if (webview.__preload__) {
// removePreloadWebview(webview)
// }
webview.close('none')
}
resolve(undefined)
}
)
setStatusBarStyle()
})
}
......@@ -28,7 +28,7 @@ function setPendingNavigator(path: string, callback: Function, msg: string) {
export function navigate(
path: string,
callback: Function,
isAppLaunch: boolean
isAppLaunch: boolean = false
) {
if (!isAppLaunch && pendingNavigator) {
return console.error(
......
......@@ -23,16 +23,22 @@ export function getCurrentPages() {
}
export function removeCurrentPage() {
removePage(getCurrentPage() as ComponentPublicInstance)
const page = getCurrentPage() as ComponentPublicInstance
if (!page) {
return
}
removePage(page)
}
export function removePage(curPage: ComponentPublicInstance) {
export function removePage(
curPage: ComponentPublicInstance | Page.PageInstance
) {
const index = pages.findIndex((page) => page === curPage)
if (index === -1) {
return
}
if (!curPage.$page.meta.isNVue) {
curPage.$.appContext.app.unmount()
;(curPage as ComponentPublicInstance).$.appContext.app.unmount()
}
pages.splice(index, 1)
if (__DEV__) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册