|
1 | 1 | import { Frame, NavigationEntry, Page } from '@nativescript/core';
|
2 | 2 | import { App, Component, Ref, nextTick, unref } from '@vue/runtime-core';
|
3 |
| -import { NSVElement } from '../dom'; |
| 3 | +import { NSVElement, NSVRoot } from '../dom'; |
4 | 4 | import { createNativeView } from '../runtimeHelpers';
|
5 | 5 |
|
6 | 6 | declare module '@vue/runtime-core' {
|
@@ -69,28 +69,75 @@ export function $navigateTo(
|
69 | 69 | throw new Error('Failed to resolve frame. Make sure your frame exists.');
|
70 | 70 | }
|
71 | 71 |
|
72 |
| - let view = createNativeView<Page>(target, options?.props); |
| 72 | + const root = new NSVRoot(); |
| 73 | + let isReloading = false; |
73 | 74 |
|
74 |
| - view.mount(); |
| 75 | + const attachDisposeCallback = (page: Page) => { |
| 76 | + const dispose = page.disposeNativeView; |
75 | 77 |
|
76 |
| - const page = view.nativeView; |
77 |
| - const dispose = page.disposeNativeView; |
| 78 | + page.disposeNativeView = () => { |
| 79 | + dispose.call(page); |
78 | 80 |
|
79 |
| - page.disposeNativeView = () => { |
80 |
| - dispose.call(page); |
81 |
| - |
82 |
| - nextTick(() => { |
83 |
| - view.unmount(); |
84 |
| - view = null; |
| 81 | + // if we are reloading, don't unmount the view, as the reload will unmount/remount it. |
| 82 | + if (!isReloading) { |
| 83 | + view.unmount(); |
| 84 | + view = null; |
| 85 | + } |
| 86 | + }; |
| 87 | + }; |
| 88 | + const reloadPage = () => { |
| 89 | + if (isReloading) { |
| 90 | + return; |
| 91 | + } |
| 92 | + |
| 93 | + // if the page we are reloading is not the current page, wait for it to be navigated to |
| 94 | + if (frame.currentPage !== view.nativeView) { |
| 95 | + view.nativeView.once('navigatedTo', () => { |
| 96 | + nextTick(() => { |
| 97 | + reloadPage(); |
| 98 | + }); |
| 99 | + }); |
| 100 | + return; |
| 101 | + } |
| 102 | + |
| 103 | + isReloading = true; |
| 104 | + view.unmount(); |
| 105 | + view.mount(root); |
| 106 | + attachDisposeCallback(view.nativeView); |
| 107 | + |
| 108 | + const originalTransition = frame.currentEntry.transition; |
| 109 | + // replace current page |
| 110 | + frame.replacePage({ |
| 111 | + ...options, |
| 112 | + transition: { |
| 113 | + name: 'fade', |
| 114 | + duration: 10, |
| 115 | + }, |
| 116 | + create: () => view.nativeView, |
| 117 | + }); |
| 118 | + // reset the transition to the original one |
| 119 | + frame.once('navigatedTo', () => { |
| 120 | + frame.currentEntry.transition = originalTransition; |
| 121 | + isReloading = false; |
85 | 122 | });
|
86 | 123 | };
|
87 | 124 |
|
| 125 | + let view = createNativeView<Page>(target, options?.props, { |
| 126 | + /** |
| 127 | + * Called by @vue/runtime-core when the component is reloaded during HMR. |
| 128 | + */ |
| 129 | + reload: reloadPage, |
| 130 | + }); |
| 131 | + |
| 132 | + view.mount(root); |
| 133 | + attachDisposeCallback(view.nativeView); |
| 134 | + |
88 | 135 | frame.navigate({
|
89 | 136 | ...options,
|
90 |
| - create: () => page, |
| 137 | + create: () => view.nativeView, |
91 | 138 | });
|
92 | 139 |
|
93 |
| - return page; |
| 140 | + return view.nativeView; |
94 | 141 | } catch (e) {
|
95 | 142 | console.error('[$navigateTo] Failed to navigate:\n\n');
|
96 | 143 | console.error(e, e.stack);
|
|
0 commit comments