8000 Quick and dirty fix for the #388 HMR issue (#444) · everpay/nativescript-vue@7e03aad · GitHub
[go: up one dir, main page]

Skip to content

Commit 7e03aad

Browse files
msaelicesrigor789
authored andcommitted
Quick and dirty fix for the nativescript-vue#388 HMR issue (nativescript-vue#444)
* fix (hmr): Fix navigation trigger on iOS when HMR reloads app if <script> is changed. See nativescript-vue#388 * fix (hmr): Better way to know if the HMR is reloaded. See nativescript-vue#388 * fix (hmr): Fix the Android version for the HMR issue. See nativescript-vue#388 * chore (hmr): Remove comment. * chore (hmr): Move comment.
1 parent 72e9097 commit 7e03aad

File tree

6 files changed

+139
-12
lines changed

6 files changed

+139
-12
lines changed

platform/nativescript/plugins/navigator-plugin.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { isObject, isDef, isPrimitive } from 'shared/util'
22
import { getFrame } from '../util/frame'
33
import { getFrameById } from 'tns-core-modules/ui/frame'
44

5-
function getFrameInstance(frame) {
5+
export function getFrameInstance(frame) {
66
// get the frame that we need to navigate
77
// this can be a frame id (String)
88
// a Vue ref to a frame
@@ -19,7 +19,7 @@ function getFrameInstance(frame) {
1919
return getFrame(frame.id)
2020
}
2121

22-
function _findParentNavigationEntry(vm) {
22+
export function findParentNavigationEntry(vm) {
2323
if (!vm) {
2424
return false
2525
}
@@ -35,7 +35,7 @@ function _findParentNavigationEntry(vm) {
3535
export default {
36< 10000 /td>36
install(Vue) {
3737
Vue.prototype.$navigateBack = function(options, backstackEntry = null) {
38-
const navEntry = _findParentNavigationEntry(this)
38+
const navEntry = findParentNavigationEntry(this)
3939
const defaultOptions = {
4040
frame: navEntry ? navEntry.$options.frame : 'default'
4141
}

platform/nativescript/renderer/ViewNode.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ export default class ViewNode {
2727
this._meta = null
2828

2929
/* istanbul ignore next
30-
* make vue happy :)
31-
*/
30+
* make vue happy :)
31+
*/
3232
this.hasAttribute = this.removeAttribute = () => false
3333
}
3434

platform/nativescript/runtime/components/frame.js

Lines changed: 97 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { setFrame, getFrame, deleteFrame } from '../../util/frame'
2-
import { extend } from 'shared/util'
3-
import { isAndroid } from 'tns-core-modules/platform'
2+
import { isHMRChecking, resetHMRChecking } from '../../util/hmr'
3+
import { isAndroid, isIOS } from 'tns-core-modules/platform'
4+
import { ios as iosUtils } from 'tns-core-modules/utils/utils'
5+
import { _setAndroidFragmentTransitions } from 'tns-core-modules/ui/frame/fragment.transitions'
46

57
let idCounter = 1
68

@@ -88,13 +90,103 @@ export default {
8890
},
8991

9092
notifyPageMounted(pageVm) {
93+
let options = {
94+
create: () => pageVm.$el.nativeView
95+
}
96+
9197
this.$nextTick(() => {
92-
this.navigate({
93-
create: () => pageVm.$el.nativeView
94-
})
98+
if (isHMRChecking()) {
99+
this.replace(options)
100+
} else {
101+
this.navigate(options)
102+
}
95103
})
96104
},
97105

106+
replace(entry) {
107+
const frame = this._getFrame()
108+
const page = entry.create()
109+
entry.create = () => page
110+
111+
const backstackEntry = {
112+
entry: entry,
113+
resolvedPage: page,
114+
navDepth: undefined,
115+
fragmentTag: undefined
116+
}
117+
// TODO: this should be in a specific NS Frame method
118+
if (isIOS) {
119+
let viewController = backstackEntry.resolvedPage.ios
120+
if (!viewController) {
121+
throw new Error(
122+
'Required page does not have a viewController created.'
123+
)
124+
}
125+
viewController['_transition'] = { name: 'non-animated' }
126+
viewController['_delegate'] = null
127+
frame._ios.controller.delegate = null
128+
viewController['_entry'] = backstackEntry
129+
130+
if (iosUtils.MajorVersion > 10) {
131+
// Reset back button title before pushing view controller to prevent
132+
// displaying default 'back' title (when NavigationButton custom title is set).
133+
let barButtonItem = UIBarButtonItem.alloc().initWithTitleStyleTargetAction(
134+
'',
135+
UIBarButtonItemStyle.Plain,
136+
null,
137+
null
138+
)
139+
viewController.navigationItem.backBarButtonItem = barButtonItem
140+
}
141+
142+
let newControllers = NSMutableArray.alloc().initWithArray(
143+
frame._ios.controller.viewControllers
144+
)
145+
if (newControllers.count === 0) {
146+
throw new Error('Wrong controllers count.')
147+
}
148+
149+
// the code below fixes a phantom animation that appears on the Back button in this case
150+
viewController.navigationItem.hidesBackButton =
151+
frame.backStack.length === 0
152+
153+
// swap the top entry with the new one
154+
const skippedNavController = newControllers.lastObject
155+
skippedNavController.isBackstackSkipped = true
156+
newControllers.removeLastObject()
157+
newControllers.addObject(viewController)
158+
159+
// replace the controllers instead of pushing directly
160+
frame._ios.controller.setViewControllersAnimated(newControllers, false)
161+
} else {
162+
const frameId = frame._android.frameId
163+
frame._isBack = false
164+
backstackEntry.frameId = frameId
165+
166+
const manager = frame._getFragmentManager()
167+
const currentEntry = frame._currentEntry
168+
169+
const newFragmentTag = `fragment${frameId}[-1]`
170+
const newFragment = frame.createFragment(backstackEntry, newFragmentTag)
171+
const animated = false
172+
const navigationTransition = null
173+
174+
const transaction = manager.beginTransaction()
175+
_setAndroidFragmentTransitions(
176+
animated,
177+
navigationTransition,
178+
currentEntry,
179+
backstackEntry,
180+
transaction,
181+
frameId
182+
)
183+
transaction.remove(currentEntry.fragment)
184+
transaction.replace(frame.containerViewId, newFragment, newFragmentTag)
185+
transaction.commitAllowingStateLoss()
186+
}
187+
resetHMRChecking()
188+
},
189+
98190
navigate(entry, back = false) {
99191
const frame = this._getFrame()
100192

platform/nativescript/runtime/components/page.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
import {
2+
findParentNavigationEntry,
3+
getFrameInstance
4+
} from '../../plugins/navigator-plugin'
5+
import { isHMRChecking } from '../../util/hmr'
6+
17
export const PAGE_REF = '__vuePageRef__'
28

39
export default {
@@ -14,7 +20,17 @@ export default {
1420
mounted() {
1521
this.$el.nativeView[PAGE_REF] = this
1622

17-
const frame = this._findParentFrame()
23+
let frame = null
24+
25+
if (isHMRChecking()) {
26+
const navEntry = findParentNavigationEntry(this)
27+
const options = {
28+
frame: navEntry ? navEntry.$options.frame : 'default'
29+
}
30+
frame = getFrameInstance(options.frame)
31+
} else {
32+
frame = this._findParentFrame()
33+
}
1834

1935
if (frame) {
2036
frame.notifyPageMounted(this)

platform/nativescript/runtime/modules/transition.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ export function enter(vnode, toggleDisplay) {
7676

7777
const beforeEnterHook = isAppear ? beforeAppear || beforeEnter : beforeEnter
7878
const enterHook = isAppear
79-
? typeof appear === 'function' ? appear : enter
79+
? typeof appear === 'function'
80+
? appear
81+
: enter
8082
: enter
8183
const afterEnterHook = isAppear ? afterAppear || afterEnter : afterEnter
8284
const enterCancelledHook = isAppear

platform/nativescript/util/hmr.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
let hmrChecking = false
2+
3+
export const isHMRChecking = () => {
4+
return hmrChecking
5+
}
6+
7+
export const resetHMRChecking = () => {
8+
hmrChecking = false
9+
}
10+
11+
if (module.hot) {
12+
module.hot.addStatusHandler(status => {
13+
if (status === 'check') {
14+
hmrChecking = true
15+
}
16+
})
17+
}

0 commit comments

Comments
 (0)
0