mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-15 02:54:11 +08:00
fix(hmr): quick fade upon replace navigation (#7251)
This commit is contained in:
@ -146,9 +146,5 @@ function _test_onLiveSync_ModuleContext_TypeStyle(context: { type, path }) {
|
||||
}
|
||||
|
||||
function waitUntilLivesyncComplete(frame: Frame) {
|
||||
if (isAndroid) {
|
||||
TKUnit.waitUntilReady(() => frame._executingEntry === null);
|
||||
} else {
|
||||
TKUnit.waitUntilReady(() => frame.currentPage.isLoaded);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
} from ".";
|
||||
|
||||
import {
|
||||
ViewBase, Property, booleanConverter, eachDescendant, EventData, layout,
|
||||
ViewBase, Property, booleanConverter, EventData, layout,
|
||||
getEventOrGestureName, traceEnabled, traceWrite, traceCategories,
|
||||
InheritedProperty, ShowModalOptions
|
||||
} from "../view-base";
|
||||
|
@ -169,8 +169,11 @@ export function _setAndroidFragmentTransitions(
|
||||
|
||||
// Having transition means we have custom animation
|
||||
if (transition) {
|
||||
if (fragmentTransaction) {
|
||||
// we do not use Android backstack so setting popEnter / popExit is meaningless (3rd and 4th optional args)
|
||||
fragmentTransaction.setCustomAnimations(AnimationType.enterFakeResourceId, AnimationType.exitFakeResourceId);
|
||||
}
|
||||
|
||||
setupAllAnimation(newEntry, transition);
|
||||
if (currentFragmentNeedsDifferentAnimation) {
|
||||
setupExitAndPopEnterAnimation(currentEntry, transition);
|
||||
@ -502,6 +505,8 @@ function clearEntry(entry: ExpandedEntry, removeListener: boolean): void {
|
||||
clearAnimationListener(entry.exitAnimator, listener);
|
||||
clearAnimationListener(entry.popEnterAnimator, listener);
|
||||
clearAnimationListener(entry.popExitAnimator, listener);
|
||||
clearAnimationListener(entry.defaultEnterAnimator, listener);
|
||||
clearAnimationListener(entry.defaultExitAnimator, listener);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
// Definitions.
|
||||
import {
|
||||
AndroidFrame as AndroidFrameDefinition, AndroidActivityCallbacks,
|
||||
AndroidFragmentCallbacks, BackstackEntry, NavigationTransition
|
||||
AndroidFragmentCallbacks, BackstackEntry, NavigationTransition, NavigationEntry
|
||||
} from ".";
|
||||
import { Page } from "../page";
|
||||
|
||||
// Types.
|
||||
import * as application from "../../application";
|
||||
import {
|
||||
FrameBase, goBack, stack, NavigationContext, NavigationType,
|
||||
FrameBase, goBack, stack, NavigationType,
|
||||
Observable, View, traceCategories, traceEnabled, traceError, traceWrite
|
||||
} from "./frame-common";
|
||||
|
||||
@ -21,7 +21,6 @@ import { profile } from "../../profiling";
|
||||
|
||||
// TODO: Remove this and get it from global to decouple builder for angular
|
||||
import { createViewFromEntry } from "../builder";
|
||||
import { getModuleName } from "../../utils/utils";
|
||||
|
||||
export * from "./frame-common";
|
||||
|
||||
@ -37,6 +36,7 @@ const INTENT_EXTRA = "com.tns.activity";
|
||||
const ROOT_VIEW_ID_EXTRA = "com.tns.activity.rootViewId";
|
||||
const FRAMEID = "_frameId";
|
||||
const CALLBACKS = "_callbacks";
|
||||
const HMR_REPLACE_TRANSITION = "fade";
|
||||
|
||||
const ownerSymbol = Symbol("_owner");
|
||||
const activityRootViewsMap = new Map<number, WeakRef<View>>();
|
||||
@ -319,6 +319,18 @@ export class Frame extends FrameBase {
|
||||
restoreAnimatorState(this._currentEntry, this._cachedAnimatorState);
|
||||
this._cachedAnimatorState = null;
|
||||
}
|
||||
|
||||
// restore original fragment transitions if we just completed replace navigation (hmr)
|
||||
if (navigationType === NavigationType.replace) {
|
||||
_clearEntry(entry);
|
||||
|
||||
const animated = entry.entry.animated;
|
||||
const navigationTransition = this._getNavigationTransition(entry.entry);
|
||||
const currentEntry = null;
|
||||
const newEntry = entry;
|
||||
const transaction = null;
|
||||
_setAndroidFragmentTransitions(animated, navigationTransition, currentEntry, newEntry, transaction, this._android.frameId);
|
||||
}
|
||||
}
|
||||
|
||||
public onBackPressed(): boolean {
|
||||
@ -381,12 +393,20 @@ export class Frame extends FrameBase {
|
||||
const newFragmentTag = `fragment${fragmentId}[${navDepth}]`;
|
||||
const newFragment = this.createFragment(newEntry, newFragmentTag);
|
||||
const transaction = manager.beginTransaction();
|
||||
const animated = currentEntry ? this._getIsAnimatedNavigation(newEntry.entry) : false;
|
||||
let animated = currentEntry ? this._getIsAnimatedNavigation(newEntry.entry) : false;
|
||||
// NOTE: Don't use transition for the initial navigation (same as on iOS)
|
||||
// On API 21+ transition won't be triggered unless there was at least one
|
||||
// layout pass so we will wait forever for transitionCompleted handler...
|
||||
// https://github.com/NativeScript/NativeScript/issues/4895
|
||||
const navigationTransition = this._currentEntry ? this._getNavigationTransition(newEntry.entry) : null;
|
||||
let navigationTransition: NavigationTransition;
|
||||
if (isReplace) {
|
||||
animated = true;
|
||||
navigationTransition = { name: HMR_REPLACE_TRANSITION, duration: 100 };
|
||||
} else if (this._currentEntry) {
|
||||
navigationTransition = this._getNavigationTransition(newEntry.entry);
|
||||
} else {
|
||||
navigationTransition = null;
|
||||
}
|
||||
|
||||
_setAndroidFragmentTransitions(animated, navigationTransition, currentEntry, newEntry, transaction, this._android.frameId);
|
||||
|
||||
|
@ -7,12 +7,11 @@ import { profile } from "../../profiling";
|
||||
|
||||
//Types.
|
||||
import {
|
||||
FrameBase, View, isCategorySet, layout, NavigationContext,
|
||||
FrameBase, View, isCategorySet, layout,
|
||||
NavigationType, traceCategories, traceEnabled, traceWrite
|
||||
} from "./frame-common";
|
||||
import { _createIOSAnimatedTransitioning } from "./fragment.transitions";
|
||||
|
||||
import { createViewFromEntry } from "../builder";
|
||||
import * as utils from "../../utils/utils";
|
||||
|
||||
export * from "./frame-common";
|
||||
@ -24,6 +23,7 @@ const DELEGATE = "_delegate";
|
||||
const NAV_DEPTH = "_navDepth";
|
||||
const TRANSITION = "_transition";
|
||||
const NON_ANIMATED_TRANSITION = "non-animated";
|
||||
const HMR_REPLACE_TRANSITION = "fade";
|
||||
|
||||
let navDepth = -1;
|
||||
|
||||
@ -88,13 +88,16 @@ export class Frame extends FrameBase {
|
||||
|
||||
let navigationTransition: NavigationTransition;
|
||||
let animated = this.currentPage ? this._getIsAnimatedNavigation(backstackEntry.entry) : false;
|
||||
if (animated) {
|
||||
if (isReplace) {
|
||||
animated = true;
|
||||
navigationTransition = { name: HMR_REPLACE_TRANSITION, duration: 100 }
|
||||
viewController[TRANSITION] = navigationTransition;
|
||||
} else if (animated) {
|
||||
navigationTransition = this._getNavigationTransition(backstackEntry.entry);
|
||||
if (navigationTransition) {
|
||||
viewController[TRANSITION] = navigationTransition;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//https://github.com/NativeScript/NativeScript/issues/1787
|
||||
viewController[TRANSITION] = { name: NON_ANIMATED_TRANSITION };
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Definitions.
|
||||
import { Frame } from "../frame";
|
||||
import { Frame, BackstackEntry } from "../frame";
|
||||
import { NavigationType } from "../frame/frame-common";
|
||||
|
||||
// Types.
|
||||
@ -15,6 +15,8 @@ export * from "./page-common";
|
||||
|
||||
const ENTRY = "_entry";
|
||||
const DELEGATE = "_delegate";
|
||||
const TRANSITION = "_transition";
|
||||
const NON_ANIMATED_TRANSITION = "non-animated";
|
||||
|
||||
const majorVersion = iosUtils.MajorVersion;
|
||||
|
||||
@ -130,7 +132,7 @@ class UIViewControllerImpl extends UIViewController {
|
||||
const frame = navigationController ? (<any>navigationController).owner : null;
|
||||
// Skip navigation events if modal page is shown.
|
||||
if (!owner._presentedViewController && frame) {
|
||||
const newEntry = this[ENTRY];
|
||||
const newEntry: BackstackEntry = this[ENTRY];
|
||||
|
||||
let isBack: boolean;
|
||||
let navType = frame.navigationType;
|
||||
@ -146,6 +148,18 @@ class UIViewControllerImpl extends UIViewController {
|
||||
}
|
||||
|
||||
frame.setCurrent(newEntry, navType);
|
||||
|
||||
if (frame.navigationType === NavigationType.replace) {
|
||||
let controller = newEntry.resolvedPage.ios;
|
||||
if (controller) {
|
||||
if (newEntry.entry.animated) {
|
||||
controller[TRANSITION] = frame._getNavigationTransition(newEntry.entry);
|
||||
} else {
|
||||
controller[TRANSITION] = { name: NON_ANIMATED_TRANSITION };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frame.navigationType = isBack ? NavigationType.back : NavigationType.forward;
|
||||
|
||||
// If page was shown with custom animation - we need to set the navigationController.delegate to the animatedDelegate.
|
||||
|
Reference in New Issue
Block a user