@nativescript/vite 8.0.0-alpha.67 → 8.0.0-alpha.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/configuration/angular.js +78 -182
- package/configuration/angular.js.map +1 -1
- package/configuration/base.js +10 -139
- package/configuration/base.js.map +1 -1
- package/helpers/app-css-state.d.ts +20 -0
- package/helpers/app-css-state.js.map +1 -1
- package/helpers/main-entry.js +44 -4
- package/helpers/main-entry.js.map +1 -1
- package/helpers/ns-core-external-urls.d.ts +32 -0
- package/helpers/ns-core-external-urls.js +107 -0
- package/helpers/ns-core-external-urls.js.map +1 -0
- package/helpers/typescript-check.js +2 -2
- package/helpers/typescript-check.js.map +1 -1
- package/helpers/workers.d.ts +0 -8
- package/helpers/workers.js +43 -381
- package/helpers/workers.js.map +1 -1
- package/hmr/client/framework-client-strategy.d.ts +17 -9
- package/hmr/client/framework-client-strategy.js +3 -4
- package/hmr/client/framework-client-strategy.js.map +1 -1
- package/hmr/client/hmr-pending-overlay.js +2 -21
- package/hmr/client/hmr-pending-overlay.js.map +1 -1
- package/hmr/client/index.d.ts +9 -1
- package/hmr/client/index.js +34 -2621
- package/hmr/client/index.js.map +1 -1
- package/hmr/client/overlay-driver.d.ts +10 -0
- package/hmr/client/overlay-driver.js +33 -0
- package/hmr/client/overlay-driver.js.map +1 -0
- package/hmr/client/protocol-dispatch.d.ts +8 -0
- package/hmr/client/protocol-dispatch.js +309 -0
- package/hmr/client/protocol-dispatch.js.map +1 -0
- package/hmr/client/root-reset.d.ts +15 -0
- package/hmr/client/root-reset.js +358 -0
- package/hmr/client/root-reset.js.map +1 -0
- package/hmr/client/strategy-loader.d.ts +24 -0
- package/hmr/client/strategy-loader.js +83 -0
- package/hmr/client/strategy-loader.js.map +1 -0
- package/hmr/client/update-pipeline.d.ts +27 -0
- package/hmr/client/update-pipeline.js +464 -0
- package/hmr/client/update-pipeline.js.map +1 -0
- package/hmr/client/utils.js +3 -2
- package/hmr/client/utils.js.map +1 -1
- package/hmr/client/ws-transport.d.ts +21 -0
- package/hmr/client/ws-transport.js +344 -0
- package/hmr/client/ws-transport.js.map +1 -0
- package/hmr/frameworks/angular/build/angular-linker.js +4 -0
- package/hmr/frameworks/angular/build/angular-linker.js.map +1 -1
- package/hmr/frameworks/angular/build/linker-stats.d.ts +18 -0
- package/hmr/frameworks/angular/build/linker-stats.js +29 -0
- package/hmr/frameworks/angular/build/linker-stats.js.map +1 -0
- package/hmr/frameworks/angular/build/ts-fallback-transform.d.ts +5 -0
- package/hmr/frameworks/angular/build/ts-fallback-transform.js +138 -0
- package/hmr/frameworks/angular/build/ts-fallback-transform.js.map +1 -0
- package/hmr/frameworks/angular/build/worker-url-preserve.d.ts +5 -0
- package/hmr/frameworks/angular/build/worker-url-preserve.js +140 -0
- package/hmr/frameworks/angular/build/worker-url-preserve.js.map +1 -0
- package/hmr/frameworks/angular/client/index.d.ts +3 -0
- package/hmr/frameworks/angular/client/index.js +28 -42
- package/hmr/frameworks/angular/client/index.js.map +1 -1
- package/hmr/frameworks/angular/server/ng-component-route.d.ts +43 -0
- package/hmr/frameworks/angular/server/ng-component-route.js +113 -0
- package/hmr/frameworks/angular/server/ng-component-route.js.map +1 -0
- package/hmr/frameworks/angular/server/strategy.js +15 -11
- package/hmr/frameworks/angular/server/strategy.js.map +1 -1
- package/hmr/frameworks/angular/server/websocket-angular-hot-update.d.ts +12 -0
- package/hmr/frameworks/angular/server/websocket-angular-hot-update.js +39 -0
- package/hmr/frameworks/angular/server/websocket-angular-hot-update.js.map +1 -1
- package/hmr/frameworks/react/client/strategy.d.ts +12 -0
- package/hmr/frameworks/react/client/strategy.js +27 -0
- package/hmr/frameworks/react/client/strategy.js.map +1 -0
- package/hmr/frameworks/solid/client/strategy.d.ts +7 -0
- package/hmr/frameworks/solid/client/strategy.js +391 -0
- package/hmr/frameworks/solid/client/strategy.js.map +1 -0
- package/hmr/frameworks/solid/server/strategy.js +2 -0
- package/hmr/frameworks/solid/server/strategy.js.map +1 -1
- package/hmr/frameworks/typescript/client/strategy.d.ts +7 -0
- package/hmr/frameworks/typescript/client/strategy.js +418 -0
- package/hmr/frameworks/typescript/client/strategy.js.map +1 -0
- package/hmr/frameworks/typescript/server/strategy.js +2 -0
- package/hmr/frameworks/typescript/server/strategy.js.map +1 -1
- package/hmr/frameworks/vue/client/index.d.ts +1 -1
- package/hmr/frameworks/vue/client/index.js +40 -319
- package/hmr/frameworks/vue/client/index.js.map +1 -1
- package/hmr/frameworks/vue/client/navigate-app.d.ts +3 -0
- package/hmr/frameworks/vue/client/navigate-app.js +178 -0
- package/hmr/frameworks/vue/client/navigate-app.js.map +1 -0
- package/hmr/frameworks/vue/client/strategy.d.ts +1 -1
- package/hmr/frameworks/vue/client/strategy.js +9 -14
- package/hmr/frameworks/vue/client/strategy.js.map +1 -1
- package/hmr/frameworks/vue/client/vue-sfc-update-overlay.js +2 -20
- package/hmr/frameworks/vue/client/vue-sfc-update-overlay.js.map +1 -1
- package/hmr/frameworks/vue/server/strategy.js +3 -0
- package/hmr/frameworks/vue/server/strategy.js.map +1 -1
- package/hmr/server/css-connect-sync.d.ts +28 -0
- package/hmr/server/css-connect-sync.js +78 -0
- package/hmr/server/css-connect-sync.js.map +1 -0
- package/hmr/server/framework-strategy.d.ts +30 -0
- package/hmr/server/websocket-hmr-pending.d.ts +0 -8
- package/hmr/server/websocket-hmr-pending.js +0 -22
- package/hmr/server/websocket-hmr-pending.js.map +1 -1
- package/hmr/server/websocket-hot-update.d.ts +3 -0
- package/hmr/server/websocket-hot-update.js +63 -36
- package/hmr/server/websocket-hot-update.js.map +1 -1
- package/hmr/server/websocket-module-bindings.js +23 -5
- package/hmr/server/websocket-module-bindings.js.map +1 -1
- package/hmr/server/websocket-module-specifiers.d.ts +0 -5
- package/hmr/server/websocket-module-specifiers.js +0 -28
- package/hmr/server/websocket-module-specifiers.js.map +1 -1
- package/hmr/server/websocket-ns-m-paths.d.ts +18 -0
- package/hmr/server/websocket-ns-m-paths.js +79 -0
- package/hmr/server/websocket-ns-m-paths.js.map +1 -1
- package/hmr/server/websocket-ns-m-request.d.ts +2 -1
- package/hmr/server/websocket-ns-m-request.js +3 -2
- package/hmr/server/websocket-ns-m-request.js.map +1 -1
- package/hmr/server/websocket-ns-m.js +100 -374
- package/hmr/server/websocket-ns-m.js.map +1 -1
- package/hmr/server/websocket-served-module-helpers.d.ts +7 -0
- package/hmr/server/websocket-served-module-helpers.js +93 -69
- package/hmr/server/websocket-served-module-helpers.js.map +1 -1
- package/hmr/server/websocket.d.ts +0 -1
- package/hmr/server/websocket.js +27 -2
- package/hmr/server/websocket.js.map +1 -1
- package/hmr/shared/ns-globals.d.ts +0 -1
- package/hmr/shared/ns-globals.js.map +1 -1
- package/hmr/shared/protocol.d.ts +14 -0
- package/hmr/shared/protocol.js.map +1 -1
- package/hmr/shared/runtime/dev-overlay-ios.d.ts +87 -0
- package/hmr/shared/runtime/dev-overlay-ios.js +521 -0
- package/hmr/shared/runtime/dev-overlay-ios.js.map +1 -0
- package/hmr/shared/runtime/dev-overlay-shared.d.ts +58 -0
- package/hmr/shared/runtime/dev-overlay-shared.js +116 -0
- package/hmr/shared/runtime/dev-overlay-shared.js.map +1 -0
- package/hmr/shared/runtime/dev-overlay-tree.d.ts +59 -0
- package/hmr/shared/runtime/dev-overlay-tree.js +712 -0
- package/hmr/shared/runtime/dev-overlay-tree.js.map +1 -0
- package/hmr/shared/runtime/dev-overlay.d.ts +15 -107
- package/hmr/shared/runtime/dev-overlay.js +19 -1336
- package/hmr/shared/runtime/dev-overlay.js.map +1 -1
- package/hmr/shared/runtime/overlay-flag.d.ts +9 -0
- package/hmr/shared/runtime/overlay-flag.js +34 -0
- package/hmr/shared/runtime/overlay-flag.js.map +1 -0
- package/hmr/shared/runtime/root-placeholder.js +3 -2
- package/hmr/shared/runtime/root-placeholder.js.map +1 -1
- package/hmr/shared/runtime/session-bootstrap.js +2 -1
- package/hmr/shared/runtime/session-bootstrap.js.map +1 -1
- package/hmr/shared/runtime/vendor-resolve.d.ts +22 -0
- package/hmr/shared/runtime/vendor-resolve.js +45 -0
- package/hmr/shared/runtime/vendor-resolve.js.map +1 -0
- package/hmr/shared/vendor/manifest-collect.js +0 -3
- package/hmr/shared/vendor/manifest-collect.js.map +1 -1
- package/package.json +1 -3
- package/runtime/core-aliases-early.js +3 -2
- package/runtime/core-aliases-early.js.map +1 -1
- package/helpers/module-runner-patch.d.ts +0 -3
- package/helpers/module-runner-patch.js +0 -63
- package/helpers/module-runner-patch.js.map +0 -1
- package/hmr/server/websocket-css-hot-update.d.ts +0 -33
- package/hmr/server/websocket-css-hot-update.js +0 -65
- package/hmr/server/websocket-css-hot-update.js.map +0 -1
- package/hmr/shared/runtime/http-only-boot.d.ts +0 -2
- package/hmr/shared/runtime/http-only-boot.js +0 -172
- package/hmr/shared/runtime/http-only-boot.js.map +0 -1
- package/hmr/vendor-bootstrap.d.ts +0 -1
- package/hmr/vendor-bootstrap.js +0 -30
- package/hmr/vendor-bootstrap.js.map +0 -1
- package/shims/react-reconciler-constants.d.ts +0 -14
- package/shims/react-reconciler-constants.js +0 -21
- package/shims/react-reconciler-constants.js.map +0 -1
- package/shims/react-reconciler.d.ts +0 -8
- package/shims/react-reconciler.js +0 -15
- package/shims/react-reconciler.js.map +0 -1
|
@@ -0,0 +1,712 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-tree overlay backend: the boot placeholder page and the live/update
|
|
3
|
+
* toast chip rendered inside the app's own view tree (Android, and the iOS
|
|
4
|
+
* fallback when the UIWindow backend can't build). Pure margin math
|
|
5
|
+
* (`computeAndroidToastMargin`) is exported separately so the safe-area rules
|
|
6
|
+
* stay unit-testable without a device.
|
|
7
|
+
*/
|
|
8
|
+
import { BOOT_PLACEHOLDER_MOTION, computeBootProgressFillScale, formatBootDetailLine, formatBootPrimaryLine } from './boot-placeholder-ui.js';
|
|
9
|
+
import { BOOT_TITLE } from './dev-overlay-snapshots.js';
|
|
10
|
+
import { asColor, formatStatusText, getHmrDevOverlayPosition, getOverlayGlobal, getRuntimeState, resolveCoreExport } from './dev-overlay-shared.js';
|
|
11
|
+
export function buildBootOverlayRefs(snapshot) {
|
|
12
|
+
const Page = resolveCoreExport('Page');
|
|
13
|
+
const StackLayout = resolveCoreExport('StackLayout');
|
|
14
|
+
const Label = resolveCoreExport('Label');
|
|
15
|
+
const ActivityIndicator = resolveCoreExport('ActivityIndicator');
|
|
16
|
+
if (!Page || !StackLayout || !Label) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const page = new Page();
|
|
20
|
+
page.actionBarHidden = true;
|
|
21
|
+
const root = new StackLayout();
|
|
22
|
+
root.padding = 24;
|
|
23
|
+
root.verticalAlignment = 'middle';
|
|
24
|
+
root.horizontalAlignment = 'stretch';
|
|
25
|
+
const titleLabel = new Label();
|
|
26
|
+
titleLabel.text = BOOT_TITLE;
|
|
27
|
+
titleLabel.textAlignment = 'center';
|
|
28
|
+
titleLabel.textWrap = true;
|
|
29
|
+
titleLabel.fontSize = 22;
|
|
30
|
+
titleLabel.fontWeight = '600';
|
|
31
|
+
const statusLabel = new Label();
|
|
32
|
+
statusLabel.textAlignment = 'center';
|
|
33
|
+
statusLabel.textWrap = true;
|
|
34
|
+
statusLabel.fontSize = 14;
|
|
35
|
+
statusLabel.marginTop = 12;
|
|
36
|
+
const activityIndicator = ActivityIndicator
|
|
37
|
+
? (() => {
|
|
38
|
+
const indicator = new ActivityIndicator();
|
|
39
|
+
indicator.marginTop = 16;
|
|
40
|
+
indicator.width = 28;
|
|
41
|
+
indicator.height = 28;
|
|
42
|
+
indicator.horizontalAlignment = 'center';
|
|
43
|
+
return indicator;
|
|
44
|
+
})()
|
|
45
|
+
: null;
|
|
46
|
+
root.addChild(titleLabel);
|
|
47
|
+
root.addChild(statusLabel);
|
|
48
|
+
if (activityIndicator) {
|
|
49
|
+
root.addChild(activityIndicator);
|
|
50
|
+
}
|
|
51
|
+
page.content = root;
|
|
52
|
+
const refs = {
|
|
53
|
+
page,
|
|
54
|
+
root,
|
|
55
|
+
titleLabel,
|
|
56
|
+
statusLabel,
|
|
57
|
+
activityIndicator,
|
|
58
|
+
};
|
|
59
|
+
applySnapshotToBootRefs(refs, snapshot);
|
|
60
|
+
return refs;
|
|
61
|
+
}
|
|
62
|
+
export function applySnapshotToBootRefs(refs, snapshot) {
|
|
63
|
+
if (!refs) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
refs.page.actionBarHidden = true;
|
|
67
|
+
refs.page.backgroundColor = asColor(snapshot.tone === 'error' ? '#b4181068' : '#a1771683');
|
|
68
|
+
refs.root.visibility = snapshot.visible && snapshot.mode === 'boot' ? 'visible' : 'collapse';
|
|
69
|
+
refs.titleLabel.text = BOOT_TITLE;
|
|
70
|
+
refs.titleLabel.color = asColor(snapshot.tone === 'error' ? '#b41810e6' : '#563e3fb1');
|
|
71
|
+
refs.statusLabel.text = formatStatusText(snapshot) || 'Preparing the HTTP HMR bootstrap (4%)';
|
|
72
|
+
refs.statusLabel.color = asColor(snapshot.tone === 'error' ? '#b41810e6' : '#563e3fb1');
|
|
73
|
+
if (refs.activityIndicator) {
|
|
74
|
+
refs.activityIndicator.busy = !!snapshot.busy;
|
|
75
|
+
refs.activityIndicator.visibility = snapshot.visible && snapshot.mode === 'boot' && snapshot.busy ? 'visible' : 'collapse';
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function findBootActivityIndicator() {
|
|
79
|
+
const g = getOverlayGlobal();
|
|
80
|
+
if (g.__NS_DEV_BOOT_ACTIVITY_INDICATOR__) {
|
|
81
|
+
return g.__NS_DEV_BOOT_ACTIVITY_INDICATOR__;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const frame = g.__NS_DEV_PLACEHOLDER_ROOT_VIEW__;
|
|
85
|
+
if (!frame)
|
|
86
|
+
return null;
|
|
87
|
+
const page = frame.currentPage || frame._currentEntry?.resolvedPage;
|
|
88
|
+
const content = page?.content;
|
|
89
|
+
const children = content?.getChildrenCount?.() || 0;
|
|
90
|
+
if (children >= 3) {
|
|
91
|
+
const indicator = content.getChildAt?.(2);
|
|
92
|
+
if (indicator && typeof indicator.busy !== 'undefined') {
|
|
93
|
+
g.__NS_DEV_BOOT_ACTIVITY_INDICATOR__ = indicator;
|
|
94
|
+
return indicator;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch { }
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
function findBootStatusLabel() {
|
|
102
|
+
const g = getOverlayGlobal();
|
|
103
|
+
// Try direct reference first
|
|
104
|
+
if (g.__NS_DEV_BOOT_STATUS_LABEL__) {
|
|
105
|
+
return g.__NS_DEV_BOOT_STATUS_LABEL__;
|
|
106
|
+
}
|
|
107
|
+
// Fallback: walk from placeholder root view
|
|
108
|
+
try {
|
|
109
|
+
const frame = g.__NS_DEV_PLACEHOLDER_ROOT_VIEW__;
|
|
110
|
+
if (!frame)
|
|
111
|
+
return null;
|
|
112
|
+
const page = frame.currentPage || frame._currentEntry?.resolvedPage;
|
|
113
|
+
if (!page)
|
|
114
|
+
return null;
|
|
115
|
+
const content = page.content;
|
|
116
|
+
if (!content)
|
|
117
|
+
return null;
|
|
118
|
+
// StackLayout with children: titleLabel, statusLabel
|
|
119
|
+
const children = content.getChildrenCount?.() || 0;
|
|
120
|
+
if (children >= 2) {
|
|
121
|
+
const label = content.getChildAt?.(1);
|
|
122
|
+
if (label && typeof label.text !== 'undefined') {
|
|
123
|
+
// Cache for next time
|
|
124
|
+
g.__NS_DEV_BOOT_STATUS_LABEL__ = label;
|
|
125
|
+
return label;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch { }
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
function findBootDetailLabel() {
|
|
133
|
+
const g = getOverlayGlobal();
|
|
134
|
+
return g.__NS_DEV_BOOT_DETAIL_LABEL__ || null;
|
|
135
|
+
}
|
|
136
|
+
function findBootProgressFill() {
|
|
137
|
+
const g = getOverlayGlobal();
|
|
138
|
+
return g.__NS_DEV_BOOT_PROGRESS_FILL__ || null;
|
|
139
|
+
}
|
|
140
|
+
export function updateBootStatusLabel(snapshot) {
|
|
141
|
+
const statusLabel = findBootStatusLabel();
|
|
142
|
+
const detailLabel = findBootDetailLabel();
|
|
143
|
+
const progressFill = findBootProgressFill();
|
|
144
|
+
const activityIndicator = findBootActivityIndicator();
|
|
145
|
+
// New (card) layout: phase line + detail line live in separate
|
|
146
|
+
// labels so the typography can differ. Legacy (single-label)
|
|
147
|
+
// layout: keep the original combined "phase (X%)\ndetail" text so
|
|
148
|
+
// nothing visually regresses for runtimes still attached to the
|
|
149
|
+
// older placeholder shape.
|
|
150
|
+
const hasSplitLabels = !!detailLabel;
|
|
151
|
+
const phaseLine = formatBootPrimaryLine(snapshot);
|
|
152
|
+
const detailLine = formatBootDetailLine(snapshot);
|
|
153
|
+
const combinedText = formatStatusText(snapshot) || 'Preparing the HTTP HMR bootstrap (4%)';
|
|
154
|
+
if (!statusLabel) {
|
|
155
|
+
if (activityIndicator) {
|
|
156
|
+
try {
|
|
157
|
+
activityIndicator.busy = !!snapshot.busy;
|
|
158
|
+
activityIndicator.visibility = snapshot.visible && snapshot.mode === 'boot' && snapshot.busy ? 'visible' : 'collapse';
|
|
159
|
+
}
|
|
160
|
+
catch { }
|
|
161
|
+
}
|
|
162
|
+
applyBootProgressFill(progressFill, snapshot);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
statusLabel.text = hasSplitLabels ? phaseLine || 'Preparing the HTTP HMR bootstrap' : combinedText;
|
|
167
|
+
// Card layout uses the calibrated phase-text colour from the
|
|
168
|
+
// palette; legacy single-label layout keeps the original muted
|
|
169
|
+
// brown so we don't visually regress mid-session.
|
|
170
|
+
const phaseColorHex = snapshot.tone === 'error' ? '#B91C1C' : hasSplitLabels ? '#475569' : '#563e3fb1';
|
|
171
|
+
statusLabel.color = asColor(phaseColorHex);
|
|
172
|
+
if (typeof statusLabel.requestLayout === 'function') {
|
|
173
|
+
statusLabel.requestLayout();
|
|
174
|
+
}
|
|
175
|
+
const parent = statusLabel.parent;
|
|
176
|
+
if (parent && typeof parent.requestLayout === 'function') {
|
|
177
|
+
parent.requestLayout();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch { }
|
|
181
|
+
if (detailLabel) {
|
|
182
|
+
try {
|
|
183
|
+
detailLabel.text = detailLine;
|
|
184
|
+
detailLabel.color = asColor(snapshot.tone === 'error' ? '#DC2626' : '#94A3B8');
|
|
185
|
+
detailLabel.visibility = detailLine ? 'visible' : 'collapse';
|
|
186
|
+
}
|
|
187
|
+
catch { }
|
|
188
|
+
}
|
|
189
|
+
applyBootProgressFill(progressFill, snapshot);
|
|
190
|
+
if (activityIndicator) {
|
|
191
|
+
try {
|
|
192
|
+
activityIndicator.busy = !!snapshot.busy;
|
|
193
|
+
activityIndicator.visibility = snapshot.visible && snapshot.mode === 'boot' && snapshot.busy ? 'visible' : 'collapse';
|
|
194
|
+
}
|
|
195
|
+
catch { }
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Drive the progress fill scaleX from the snapshot. Uses NS's view
|
|
199
|
+
// animate API for a smooth 220 ms easeOut between heartbeat ticks; a
|
|
200
|
+
// monotonic ratchet on `globalThis.__NS_DEV_BOOT_PROGRESS_LAST_SCALE__`
|
|
201
|
+
// guards against the fill snapping backwards if a less-progressed
|
|
202
|
+
// snapshot ever lands between ticks (mirrors the JS-side
|
|
203
|
+
// `applyMonotonicBootProgress` contract).
|
|
204
|
+
function applyBootProgressFill(progressFill, snapshot) {
|
|
205
|
+
if (!progressFill)
|
|
206
|
+
return;
|
|
207
|
+
const g = getOverlayGlobal();
|
|
208
|
+
const isError = snapshot.tone === 'error';
|
|
209
|
+
progressFill.backgroundColor = asColor(isError ? '#B41810' : '#3B6FE5');
|
|
210
|
+
const targetScale = computeBootProgressFillScale(snapshot.progress ?? null);
|
|
211
|
+
const previousRaw = Number(g.__NS_DEV_BOOT_PROGRESS_LAST_SCALE__);
|
|
212
|
+
const previous = Number.isFinite(previousRaw) ? previousRaw : 0;
|
|
213
|
+
const next = Math.max(previous, targetScale);
|
|
214
|
+
g.__NS_DEV_BOOT_PROGRESS_LAST_SCALE__ = next;
|
|
215
|
+
try {
|
|
216
|
+
// NS view.animate scales around `originX`/`originY`; the
|
|
217
|
+
// placeholder builder pins `originX = 0` so the fill grows
|
|
218
|
+
// rightward. animate() may be unavailable in some headless
|
|
219
|
+
// test environments — fall through to a direct property set.
|
|
220
|
+
if (typeof progressFill.animate === 'function') {
|
|
221
|
+
progressFill
|
|
222
|
+
.animate({
|
|
223
|
+
scale: { x: next, y: 1 },
|
|
224
|
+
duration: BOOT_PLACEHOLDER_MOTION.progressDurationMs,
|
|
225
|
+
curve: 'easeOut',
|
|
226
|
+
})
|
|
227
|
+
.catch(() => {
|
|
228
|
+
try {
|
|
229
|
+
progressFill.scaleX = next;
|
|
230
|
+
}
|
|
231
|
+
catch { }
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
progressFill.scaleX = next;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
progressFill.scaleX = next;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function resolveActivePage() {
|
|
243
|
+
try {
|
|
244
|
+
const Frame = resolveCoreExport('Frame');
|
|
245
|
+
const frame = Frame?.topmost?.() || null;
|
|
246
|
+
const currentPage = frame?.currentPage || frame?._currentEntry?.resolvedPage || null;
|
|
247
|
+
if (currentPage) {
|
|
248
|
+
return currentPage;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
catch { }
|
|
252
|
+
try {
|
|
253
|
+
const Application = resolveCoreExport('Application');
|
|
254
|
+
const rootView = Application?.getRootView?.() || null;
|
|
255
|
+
if (rootView?.currentPage) {
|
|
256
|
+
return rootView.currentPage;
|
|
257
|
+
}
|
|
258
|
+
if (typeof rootView?.content !== 'undefined') {
|
|
259
|
+
return rootView;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
catch { }
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
function readCachedAndroidSafeAreaInsets() {
|
|
266
|
+
const g = getOverlayGlobal();
|
|
267
|
+
const cached = g.__NS_HMR_ANDROID_SAFE_INSETS__;
|
|
268
|
+
if (cached && typeof cached.top === 'number') {
|
|
269
|
+
return cached;
|
|
270
|
+
}
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Read the Android system-bar safe-area insets (status bar / navigation
|
|
275
|
+
* bar / display cutout) in device-independent pixels.
|
|
276
|
+
*
|
|
277
|
+
* NativeScript runs every Android activity edge-to-edge, so the overlay
|
|
278
|
+
* wrapper fills the whole window — we need these insets to keep the toast
|
|
279
|
+
* chip out from under the system bars (see `computeAndroidToastMargin`).
|
|
280
|
+
*
|
|
281
|
+
* Returns null on non-Android runtimes (iOS / web / vitest) so callers
|
|
282
|
+
* fall back to base margins. The last good reading is cached on the
|
|
283
|
+
* global so a transient null (e.g. insets queried before the decor view
|
|
284
|
+
* is attached) reuses the previous value instead of snapping the chip
|
|
285
|
+
* back under the status bar.
|
|
286
|
+
*/
|
|
287
|
+
function readAndroidSafeAreaInsets() {
|
|
288
|
+
const g = getOverlayGlobal();
|
|
289
|
+
// `android.*` is exposed as a global only on the NativeScript Android
|
|
290
|
+
// runtime; its absence means iOS, web, or a test environment.
|
|
291
|
+
const androidNs = g.android || (typeof globalThis.android !== 'undefined' ? globalThis.android : undefined);
|
|
292
|
+
if (!androidNs) {
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
try {
|
|
296
|
+
const Application = resolveCoreExport('Application');
|
|
297
|
+
const activity = Application?.android?.foregroundActivity || Application?.android?.startActivity;
|
|
298
|
+
const decorView = activity?.getWindow?.()?.getDecorView?.();
|
|
299
|
+
const rootInsets = decorView?.getRootWindowInsets?.();
|
|
300
|
+
if (!rootInsets) {
|
|
301
|
+
return readCachedAndroidSafeAreaInsets();
|
|
302
|
+
}
|
|
303
|
+
let density = 1;
|
|
304
|
+
try {
|
|
305
|
+
const metricsDensity = Number(activity?.getResources?.()?.getDisplayMetrics?.()?.density);
|
|
306
|
+
if (Number.isFinite(metricsDensity) && metricsDensity > 0) {
|
|
307
|
+
density = metricsDensity;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
catch { }
|
|
311
|
+
let px = { top: 0, bottom: 0, left: 0, right: 0 };
|
|
312
|
+
const WindowInsets = androidNs.view?.WindowInsets;
|
|
313
|
+
const Type = WindowInsets?.Type;
|
|
314
|
+
if (typeof rootInsets.getInsets === 'function' && Type && typeof Type.systemBars === 'function') {
|
|
315
|
+
// API 30+: query the system bars + display cutout so notches /
|
|
316
|
+
// camera holes are respected in landscape.
|
|
317
|
+
let mask = Type.systemBars();
|
|
318
|
+
if (typeof Type.displayCutout === 'function') {
|
|
319
|
+
mask = mask | Type.displayCutout();
|
|
320
|
+
}
|
|
321
|
+
const i = rootInsets.getInsets(mask);
|
|
322
|
+
px = { top: Number(i?.top) || 0, bottom: Number(i?.bottom) || 0, left: Number(i?.left) || 0, right: Number(i?.right) || 0 };
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
// API < 30 fallback.
|
|
326
|
+
px = {
|
|
327
|
+
top: Number(rootInsets.getSystemWindowInsetTop?.()) || 0,
|
|
328
|
+
bottom: Number(rootInsets.getSystemWindowInsetBottom?.()) || 0,
|
|
329
|
+
left: Number(rootInsets.getSystemWindowInsetLeft?.()) || 0,
|
|
330
|
+
right: Number(rootInsets.getSystemWindowInsetRight?.()) || 0,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
const insets = {
|
|
334
|
+
top: px.top / density,
|
|
335
|
+
bottom: px.bottom / density,
|
|
336
|
+
left: px.left / density,
|
|
337
|
+
right: px.right / density,
|
|
338
|
+
};
|
|
339
|
+
g.__NS_HMR_ANDROID_SAFE_INSETS__ = insets;
|
|
340
|
+
return insets;
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
return readCachedAndroidSafeAreaInsets();
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Margin math for the in-tree (Android) live/update toast chip.
|
|
348
|
+
*
|
|
349
|
+
* NativeScript enables edge-to-edge on every Android activity
|
|
350
|
+
* (`@nativescript/core` → `application.android.ts` → `enableEdgeToEdge`),
|
|
351
|
+
* so the page content — and therefore the overlay wrapper we inject into
|
|
352
|
+
* it — extends underneath the status bar and navigation bar. A fixed
|
|
353
|
+
* top/bottom margin leaves the chip tucked behind the system bars, where
|
|
354
|
+
* it gets clipped (Android 15 / API 35 enforces edge-to-edge, so this is
|
|
355
|
+
* now the norm rather than the exception).
|
|
356
|
+
*
|
|
357
|
+
* This pure helper folds the system-bar safe-area insets into the chip's
|
|
358
|
+
* margin so the toast always clears the status bar (top position) /
|
|
359
|
+
* navigation bar (bottom position). It is deterministic and free of
|
|
360
|
+
* native deps so the rules stay unit-testable — the runtime reads the
|
|
361
|
+
* live insets via `readAndroidSafeAreaInsets()` and forwards them here.
|
|
362
|
+
*
|
|
363
|
+
* - 'top': margin.top = baseVerticalInset + safeInsets.top
|
|
364
|
+
* - 'bottom': margin.bottom = baseVerticalInset + safeInsets.bottom
|
|
365
|
+
* - 'center': fixed `centerMargin` all around (vertically centered, so
|
|
366
|
+
* it never approaches the system bars on normal viewports).
|
|
367
|
+
*
|
|
368
|
+
* Horizontal margins always include the relevant safe-area inset so a
|
|
369
|
+
* landscape display cutout / gesture pill doesn't clip the chip edge.
|
|
370
|
+
*/
|
|
371
|
+
export function computeAndroidToastMargin(input) {
|
|
372
|
+
// Clamp to a finite, non-negative number; fall back to `fallback`
|
|
373
|
+
// for missing/NaN input so a glitched measurement can't produce a
|
|
374
|
+
// negative or NaN margin (which NativeScript would silently drop).
|
|
375
|
+
const clamp = (value, fallback) => {
|
|
376
|
+
const n = Number(value);
|
|
377
|
+
return Number.isFinite(n) && n >= 0 ? n : fallback;
|
|
378
|
+
};
|
|
379
|
+
const safe = {
|
|
380
|
+
top: clamp(input.safeInsets?.top, 0),
|
|
381
|
+
bottom: clamp(input.safeInsets?.bottom, 0),
|
|
382
|
+
left: clamp(input.safeInsets?.left, 0),
|
|
383
|
+
right: clamp(input.safeInsets?.right, 0),
|
|
384
|
+
};
|
|
385
|
+
const baseVerticalInset = clamp(input.baseVerticalInset, 8);
|
|
386
|
+
const baseHorizontalInset = clamp(input.baseHorizontalInset, 16);
|
|
387
|
+
const centerMargin = clamp(input.centerMargin, 24);
|
|
388
|
+
if (input.position === 'center') {
|
|
389
|
+
return { top: centerMargin, right: centerMargin, bottom: centerMargin, left: centerMargin };
|
|
390
|
+
}
|
|
391
|
+
const left = Math.round(baseHorizontalInset + safe.left);
|
|
392
|
+
const right = Math.round(baseHorizontalInset + safe.right);
|
|
393
|
+
if (input.position === 'bottom') {
|
|
394
|
+
return { top: 0, right, bottom: Math.round(baseVerticalInset + safe.bottom), left };
|
|
395
|
+
}
|
|
396
|
+
// 'top' (and any unexpected value) hugs the status-bar safe area.
|
|
397
|
+
return { top: Math.round(baseVerticalInset + safe.top), right, bottom: 0, left };
|
|
398
|
+
}
|
|
399
|
+
function buildLiveOverlayView(snapshot) {
|
|
400
|
+
const GridLayout = resolveCoreExport('GridLayout');
|
|
401
|
+
const StackLayout = resolveCoreExport('StackLayout');
|
|
402
|
+
const Label = resolveCoreExport('Label');
|
|
403
|
+
if (!GridLayout || !StackLayout || !Label) {
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
406
|
+
const overlay = new GridLayout();
|
|
407
|
+
overlay.visibility = 'collapse';
|
|
408
|
+
overlay.width = '100%';
|
|
409
|
+
overlay.height = '100%';
|
|
410
|
+
overlay.horizontalAlignment = 'stretch';
|
|
411
|
+
overlay.verticalAlignment = 'stretch';
|
|
412
|
+
// Toast mode lets touches reach the underlying app. We flip
|
|
413
|
+
// isUserInteractionEnabled in applySnapshotToLiveRefs based on
|
|
414
|
+
// the resolved position, but keep it false here as a safe default
|
|
415
|
+
// (the panel itself is purely informational).
|
|
416
|
+
try {
|
|
417
|
+
overlay.isUserInteractionEnabled = false;
|
|
418
|
+
}
|
|
419
|
+
catch { }
|
|
420
|
+
const panel = new StackLayout();
|
|
421
|
+
panel.horizontalAlignment = 'center';
|
|
422
|
+
// Vertical alignment is overridden in applySnapshotToLiveRefs
|
|
423
|
+
// based on getHmrDevOverlayPosition(); 'middle' is the default
|
|
424
|
+
panel.verticalAlignment = 'middle';
|
|
425
|
+
panel.width = 320;
|
|
426
|
+
panel.margin = 24;
|
|
427
|
+
panel.padding = 16;
|
|
428
|
+
const titleLabel = new Label();
|
|
429
|
+
titleLabel.textAlignment = 'center';
|
|
430
|
+
titleLabel.textWrap = true;
|
|
431
|
+
titleLabel.fontSize = 18;
|
|
432
|
+
titleLabel.fontWeight = '600';
|
|
433
|
+
const statusLabel = new Label();
|
|
434
|
+
statusLabel.textAlignment = 'center';
|
|
435
|
+
statusLabel.textWrap = true;
|
|
436
|
+
statusLabel.fontSize = 13;
|
|
437
|
+
statusLabel.marginTop = 10;
|
|
438
|
+
panel.addChild(titleLabel);
|
|
439
|
+
panel.addChild(statusLabel);
|
|
440
|
+
overlay.addChild(panel);
|
|
441
|
+
const refs = {
|
|
442
|
+
overlay,
|
|
443
|
+
titleLabel,
|
|
444
|
+
statusLabel,
|
|
445
|
+
wasVisible: false,
|
|
446
|
+
currentPosition: getHmrDevOverlayPosition(),
|
|
447
|
+
};
|
|
448
|
+
applySnapshotToLiveRefs(refs, snapshot);
|
|
449
|
+
return refs;
|
|
450
|
+
}
|
|
451
|
+
export function ensureLiveOverlayRefs(snapshot) {
|
|
452
|
+
const state = getRuntimeState();
|
|
453
|
+
const page = resolveActivePage();
|
|
454
|
+
if (!page) {
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
if (state.liveRefs) {
|
|
458
|
+
if (state.liveRefs.page === page && state.liveRefs.overlay?.parent) {
|
|
459
|
+
return state.liveRefs;
|
|
460
|
+
}
|
|
461
|
+
try {
|
|
462
|
+
state.liveRefs.overlay.visibility = 'collapse';
|
|
463
|
+
}
|
|
464
|
+
catch { }
|
|
465
|
+
state.liveRefs = null;
|
|
466
|
+
}
|
|
467
|
+
const GridLayout = resolveCoreExport('GridLayout');
|
|
468
|
+
if (!GridLayout || typeof page.content === 'undefined') {
|
|
469
|
+
return null;
|
|
470
|
+
}
|
|
471
|
+
let wrapper = page.content;
|
|
472
|
+
if (!wrapper || !wrapper.__ns_hmr_overlay_wrapper__) {
|
|
473
|
+
const currentContent = page.content || null;
|
|
474
|
+
wrapper = new GridLayout();
|
|
475
|
+
wrapper.width = '100%';
|
|
476
|
+
wrapper.height = '100%';
|
|
477
|
+
wrapper.__ns_hmr_overlay_wrapper__ = true;
|
|
478
|
+
try {
|
|
479
|
+
page.content = null;
|
|
480
|
+
}
|
|
481
|
+
catch { }
|
|
482
|
+
if (currentContent) {
|
|
483
|
+
wrapper.addChild(currentContent);
|
|
484
|
+
}
|
|
485
|
+
page.content = wrapper;
|
|
486
|
+
}
|
|
487
|
+
const liveView = buildLiveOverlayView(snapshot);
|
|
488
|
+
if (!liveView) {
|
|
489
|
+
return null;
|
|
490
|
+
}
|
|
491
|
+
wrapper.addChild(liveView.overlay);
|
|
492
|
+
state.liveRefs = {
|
|
493
|
+
page,
|
|
494
|
+
wrapper,
|
|
495
|
+
...liveView,
|
|
496
|
+
};
|
|
497
|
+
return state.liveRefs;
|
|
498
|
+
}
|
|
499
|
+
export function applySnapshotToLiveRefs(refs, snapshot) {
|
|
500
|
+
if (!refs) {
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
// 'update' mode shares the live (in-tree) overlay chrome with
|
|
504
|
+
// 'connection'. Both render a small panel inside the page; only
|
|
505
|
+
// the colours, text, and (now) panel position change with the
|
|
506
|
+
// snapshot's tone and the configured overlay position.
|
|
507
|
+
const visible = snapshot.visible && (snapshot.mode === 'connection' || snapshot.mode === 'update');
|
|
508
|
+
const wasVisible = !!refs.wasVisible;
|
|
509
|
+
const position = getHmrDevOverlayPosition();
|
|
510
|
+
const previousPosition = refs.currentPosition || position;
|
|
511
|
+
const isToast = position !== 'center';
|
|
512
|
+
refs.titleLabel.text = snapshot.title;
|
|
513
|
+
refs.statusLabel.text = formatStatusText(snapshot);
|
|
514
|
+
const textColor = snapshot.tone === 'error' ? '#b41810e6' : snapshot.tone === 'success' ? '#0e6e2fff' : '#563e3fb1';
|
|
515
|
+
refs.titleLabel.color = asColor(textColor);
|
|
516
|
+
refs.statusLabel.color = asColor(textColor);
|
|
517
|
+
// Backdrop tints (centered modal only). Toast modes use a fully
|
|
518
|
+
// transparent backdrop so the rest of the app stays visible AND
|
|
519
|
+
// reachable; the panel itself carries enough colour to stand out.
|
|
520
|
+
if (isToast) {
|
|
521
|
+
refs.overlay.backgroundColor = asColor('transparent');
|
|
522
|
+
}
|
|
523
|
+
else {
|
|
524
|
+
// Original wash-by-tone for centered:
|
|
525
|
+
// error → red wash (matches existing UX)
|
|
526
|
+
// success → richer green wash so the apply event is visible
|
|
527
|
+
// on bright app backgrounds
|
|
528
|
+
// default → warm orange (existing connection-overlay look)
|
|
529
|
+
const overlayBg = snapshot.tone === 'error' ? '#b4181068' : snapshot.tone === 'success' ? '#1f883d80' : '#a1771683';
|
|
530
|
+
refs.overlay.backgroundColor = asColor(overlayBg);
|
|
531
|
+
}
|
|
532
|
+
// Panel chrome — toast and centered share the same chip look,
|
|
533
|
+
// just position differs. We keep the slightly richer green tint
|
|
534
|
+
// for the HMR success state so it pops without needing the
|
|
535
|
+
// backdrop wash.
|
|
536
|
+
let panel = null;
|
|
537
|
+
try {
|
|
538
|
+
panel = refs.titleLabel.parent;
|
|
539
|
+
if (panel) {
|
|
540
|
+
const panelBg = snapshot.tone === 'success' ? '#E6F8E9FF' : '#FFFFFFFF';
|
|
541
|
+
panel.backgroundColor = asColor(panelBg);
|
|
542
|
+
panel.opacity = 1;
|
|
543
|
+
panel.padding = 16;
|
|
544
|
+
try {
|
|
545
|
+
panel.borderRadius = 12;
|
|
546
|
+
}
|
|
547
|
+
catch { }
|
|
548
|
+
// Position-aware alignment. The wrapper GridLayout fills the
|
|
549
|
+
// page content area. NativeScript runs every Android activity
|
|
550
|
+
// edge-to-edge, so that area extends under the status bar and
|
|
551
|
+
// navigation bar — we fold the system-bar safe-area insets into
|
|
552
|
+
// the chip's margin (via computeAndroidToastMargin) so a top
|
|
553
|
+
// chip clears the status bar and a bottom chip clears the nav
|
|
554
|
+
// bar instead of being clipped behind them. readAndroidSafeAreaInsets
|
|
555
|
+
// returns null off-Android, so the margins collapse to their base
|
|
556
|
+
// values (no behavioural change on iOS's in-tree fallback / tests).
|
|
557
|
+
try {
|
|
558
|
+
if (position === 'top' || position === 'bottom') {
|
|
559
|
+
const m = computeAndroidToastMargin({ position, safeInsets: readAndroidSafeAreaInsets() });
|
|
560
|
+
panel.verticalAlignment = position;
|
|
561
|
+
panel.margin = `${m.top} ${m.right} ${m.bottom} ${m.left}`;
|
|
562
|
+
}
|
|
563
|
+
else {
|
|
564
|
+
panel.verticalAlignment = 'middle';
|
|
565
|
+
panel.margin = 24;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
catch { }
|
|
569
|
+
// Force a tight re-measure so the StackLayout panel hugs the
|
|
570
|
+
// CURRENT title+status text. Connection stages can swap between
|
|
571
|
+
// frames whose text wraps to a different number of lines (e.g. a
|
|
572
|
+
// long 'reconnecting' "Retrying ws://…" detail vs. the short
|
|
573
|
+
// 'offline' message). Without an explicit relayout the panel can
|
|
574
|
+
// retain the tallest height it ever measured, leaving an oversized
|
|
575
|
+
// gap between title and message. Mirrors updateBootStatusLabel.
|
|
576
|
+
try {
|
|
577
|
+
refs.titleLabel.requestLayout?.();
|
|
578
|
+
refs.statusLabel.requestLayout?.();
|
|
579
|
+
panel.requestLayout?.();
|
|
580
|
+
}
|
|
581
|
+
catch { }
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
catch { }
|
|
585
|
+
// Touch passthrough for toast; centered mode keeps the
|
|
586
|
+
// blocking modal so the dim backdrop is meaningful.
|
|
587
|
+
try {
|
|
588
|
+
refs.overlay.isUserInteractionEnabled = !isToast;
|
|
589
|
+
}
|
|
590
|
+
catch { }
|
|
591
|
+
const positionChanged = previousPosition !== position;
|
|
592
|
+
const justAppeared = visible && (!wasVisible || positionChanged);
|
|
593
|
+
const justDismissed = !visible && wasVisible;
|
|
594
|
+
if (justAppeared) {
|
|
595
|
+
refs.overlay.visibility = 'visible';
|
|
596
|
+
if (isToast && panel && typeof panel.animate === 'function') {
|
|
597
|
+
animateLivePanelIn(panel, position);
|
|
598
|
+
}
|
|
599
|
+
else if (panel) {
|
|
600
|
+
try {
|
|
601
|
+
panel.translateY = 0;
|
|
602
|
+
panel.opacity = 1;
|
|
603
|
+
}
|
|
604
|
+
catch { }
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
else if (justDismissed) {
|
|
608
|
+
if (isToast && panel && typeof panel.animate === 'function') {
|
|
609
|
+
animateLivePanelOut(panel, previousPosition, () => {
|
|
610
|
+
try {
|
|
611
|
+
refs.overlay.visibility = 'collapse';
|
|
612
|
+
}
|
|
613
|
+
catch { }
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
refs.overlay.visibility = 'collapse';
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
// Steady-state refresh (e.g. offline → reconnecting → offline while
|
|
622
|
+
// already visible): no slide animation fires here, so clear any
|
|
623
|
+
// transform residue a previously-interrupted slide-in/out may have
|
|
624
|
+
// left on the panel. Otherwise the chip can appear shifted or
|
|
625
|
+
// faded across rapid connection-stage swaps.
|
|
626
|
+
if (visible && panel) {
|
|
627
|
+
try {
|
|
628
|
+
panel.translateY = 0;
|
|
629
|
+
panel.opacity = 1;
|
|
630
|
+
}
|
|
631
|
+
catch { }
|
|
632
|
+
}
|
|
633
|
+
refs.overlay.visibility = visible ? 'visible' : 'collapse';
|
|
634
|
+
}
|
|
635
|
+
if (typeof refs.wasVisible !== 'undefined')
|
|
636
|
+
refs.wasVisible = visible;
|
|
637
|
+
if (typeof refs.currentPosition !== 'undefined')
|
|
638
|
+
refs.currentPosition = position;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Slide-in animation for the in-tree toast panel.
|
|
642
|
+
*
|
|
643
|
+
* NativeScript's `View.animate({ translate, opacity, duration, curve })`
|
|
644
|
+
* is widely available across Core versions, so we don't depend on any
|
|
645
|
+
* specific curve enum being importable here. We use a moderate-to-snappy
|
|
646
|
+
* 320ms ease-out which feels close to a UIView spring without needing
|
|
647
|
+
* platform-specific APIs.
|
|
648
|
+
*/
|
|
649
|
+
function animateLivePanelIn(panel, position) {
|
|
650
|
+
if (!panel || typeof panel.animate !== 'function')
|
|
651
|
+
return;
|
|
652
|
+
try {
|
|
653
|
+
const startY = position === 'bottom' ? 80 : -80;
|
|
654
|
+
panel.translateY = startY;
|
|
655
|
+
panel.opacity = 0;
|
|
656
|
+
const result = panel.animate({
|
|
657
|
+
translate: { x: 0, y: 0 },
|
|
658
|
+
opacity: 1,
|
|
659
|
+
duration: 320,
|
|
660
|
+
curve: 'easeOut',
|
|
661
|
+
});
|
|
662
|
+
if (result && typeof result.catch === 'function') {
|
|
663
|
+
result.catch(() => {
|
|
664
|
+
try {
|
|
665
|
+
panel.translateY = 0;
|
|
666
|
+
panel.opacity = 1;
|
|
667
|
+
}
|
|
668
|
+
catch { }
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
catch {
|
|
673
|
+
try {
|
|
674
|
+
panel.translateY = 0;
|
|
675
|
+
panel.opacity = 1;
|
|
676
|
+
}
|
|
677
|
+
catch { }
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
function animateLivePanelOut(panel, position, onComplete) {
|
|
681
|
+
if (!panel || typeof panel.animate !== 'function') {
|
|
682
|
+
onComplete();
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
try {
|
|
686
|
+
const targetY = position === 'bottom' ? 80 : -80;
|
|
687
|
+
const result = panel.animate({
|
|
688
|
+
translate: { x: 0, y: targetY },
|
|
689
|
+
opacity: 0,
|
|
690
|
+
duration: 220,
|
|
691
|
+
curve: 'easeIn',
|
|
692
|
+
});
|
|
693
|
+
const finish = () => {
|
|
694
|
+
try {
|
|
695
|
+
panel.translateY = 0;
|
|
696
|
+
panel.opacity = 1;
|
|
697
|
+
}
|
|
698
|
+
catch { }
|
|
699
|
+
onComplete();
|
|
700
|
+
};
|
|
701
|
+
if (result && typeof result.then === 'function') {
|
|
702
|
+
result.then(finish, finish);
|
|
703
|
+
}
|
|
704
|
+
else {
|
|
705
|
+
finish();
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
catch {
|
|
709
|
+
onComplete();
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
//# sourceMappingURL=dev-overlay-tree.js.map
|