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

feat(app): add redirectTo

上级 17298658
...@@ -4417,8 +4417,11 @@ var serviceContext = (function (vue) { ...@@ -4417,8 +4417,11 @@ var serviceContext = (function (vue) {
type: Number, type: Number,
}, },
}, createAnimationProtocol(ANIMATION_OUT)); }, createAnimationProtocol(ANIMATION_OUT));
const RedirectToProtocol = BaseRouteProtocol;
const NavigateToOptions = const NavigateToOptions =
/*#__PURE__*/ createRouteOptions(API_NAVIGATE_TO); /*#__PURE__*/ createRouteOptions(API_NAVIGATE_TO);
const RedirectToOptions =
/*#__PURE__*/ createRouteOptions(API_REDIRECT_TO);
const NavigateBackOptions = { const NavigateBackOptions = {
formatArgs: { formatArgs: {
delta(value, params) { delta(value, params) {
...@@ -8986,6 +8989,67 @@ var serviceContext = (function (vue) { ...@@ -8986,6 +8989,67 @@ var serviceContext = (function (vue) {
return new InteractiveAd(options); return new InteractiveAd(options);
}, CreateInteractiveAdProtocol, CreateInteractiveAdOptions)); }, 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; let pendingNavigator = false;
function setPendingNavigator(path, callback, msg) { function setPendingNavigator(path, callback, msg) {
pendingNavigator = { pendingNavigator = {
...@@ -8997,7 +9061,7 @@ var serviceContext = (function (vue) { ...@@ -8997,7 +9061,7 @@ var serviceContext = (function (vue) {
console.log(formatLog('setPendingNavigator', path, msg)); console.log(formatLog('setPendingNavigator', path, msg));
} }
} }
function navigate(path, callback, isAppLaunch) { function navigate(path, callback, isAppLaunch = false) {
if (!isAppLaunch && pendingNavigator) { if (!isAppLaunch && pendingNavigator) {
return console.error(`Waiting to navigate to: ${pendingNavigator.path}, do not operate continuously: ${path}.`); return console.error(`Waiting to navigate to: ${pendingNavigator.path}, do not operate continuously: ${path}.`);
} }
...@@ -9119,6 +9183,91 @@ var serviceContext = (function (vue) { ...@@ -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 { class UniPageNode extends UniNode {
constructor(pageId, options, setup = false) { constructor(pageId, options, setup = false) {
super(NODE_TYPE_PAGE, '#page', null); super(NODE_TYPE_PAGE, '#page', null);
...@@ -9333,38 +9482,6 @@ var serviceContext = (function (vue) { ...@@ -9333,38 +9482,6 @@ var serviceContext = (function (vue) {
return new UniPageNode(pageId, pageOptions, setup); 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) { function setupPage(component) {
const oldSetup = component.setup; const oldSetup = component.setup;
component.inheritAttrs = false; // 禁止继承 __pageId 等属性,避免告警 component.inheritAttrs = false; // 禁止继承 __pageId 等属性,避免告警
...@@ -9554,117 +9671,56 @@ var serviceContext = (function (vue) { ...@@ -9554,117 +9671,56 @@ var serviceContext = (function (vue) {
]; ];
} }
let lastStatusBarStyle; const redirectTo = defineAsyncApi(API_REDIRECT_TO, ({ url }, { resolve, reject }) => {
let oldSetStatusBarStyle = plus.navigator.setStatusBarStyle; const { path, query } = parseUrl(url);
function newSetStatusBarStyle(style) { navigate(path, () => {
lastStatusBarStyle = style; _redirectTo({
oldSetStatusBarStyle(style); url,
} path,
plus.navigator.setStatusBarStyle = newSetStatusBarStyle; query,
function setStatusBarStyle(statusBarStyle) { })
if (!statusBarStyle) { .then(resolve)
const pages = getCurrentPages(); .catch(reject);
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,
}); });
}, 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 { resolve(undefined);
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(); 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) { ...@@ -9795,8 +9851,9 @@ var serviceContext = (function (vue) {
createFullScreenVideoAd: createFullScreenVideoAd, createFullScreenVideoAd: createFullScreenVideoAd,
createInterstitialAd: createInterstitialAd, createInterstitialAd: createInterstitialAd,
createInteractiveAd: createInteractiveAd, createInteractiveAd: createInteractiveAd,
navigateBack: navigateBack,
navigateTo: navigateTo, navigateTo: navigateTo,
navigateBack: navigateBack redirectTo: redirectTo
}); });
let invokeViewMethodId = 0; let invokeViewMethodId = 0;
......
...@@ -52,8 +52,9 @@ export * from './ad/fullScreenVideoAd' ...@@ -52,8 +52,9 @@ export * from './ad/fullScreenVideoAd'
export * from './ad/interstitialAd' export * from './ad/interstitialAd'
export * from './ad/interactiveAd' export * from './ad/interactiveAd'
export * from './route/navigateTo'
export * from './route/navigateBack' export * from './route/navigateBack'
export * from './route/navigateTo'
export * from './route/redirectTo'
export { export {
upx2px, upx2px,
......
...@@ -94,7 +94,7 @@ function back( ...@@ -94,7 +94,7 @@ function back(
closeWebview(webview, animationType, animationDuration || ANI_DURATION) closeWebview(webview, animationType, animationDuration || ANI_DURATION)
} else { } else {
if (currentPage.$page.openType === 'redirectTo') { if (currentPage.$page.openType === 'redirectTo') {
// 如果是 redirectTo 跳转的,需要定 back 动画 // 如果是 redirectTo 跳转的,需要定 back 动画
closeWebview(webview, ANI_CLOSE, ANI_DURATION) closeWebview(webview, ANI_CLOSE, ANI_DURATION)
} else { } else {
closeWebview(webview, 'auto') 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) { ...@@ -28,7 +28,7 @@ function setPendingNavigator(path: string, callback: Function, msg: string) {
export function navigate( export function navigate(
path: string, path: string,
callback: Function, callback: Function,
isAppLaunch: boolean isAppLaunch: boolean = false
) { ) {
if (!isAppLaunch && pendingNavigator) { if (!isAppLaunch && pendingNavigator) {
return console.error( return console.error(
......
...@@ -23,16 +23,22 @@ export function getCurrentPages() { ...@@ -23,16 +23,22 @@ export function getCurrentPages() {
} }
export function removeCurrentPage() { 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) const index = pages.findIndex((page) => page === curPage)
if (index === -1) { if (index === -1) {
return return
} }
if (!curPage.$page.meta.isNVue) { if (!curPage.$page.meta.isNVue) {
curPage.$.appContext.app.unmount() ;(curPage as ComponentPublicInstance).$.appContext.app.unmount()
} }
pages.splice(index, 1) pages.splice(index, 1)
if (__DEV__) { if (__DEV__) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册