Repository navigation
Expand file tree
/
Copy pathmain-page.ts
More file actions
169 lines (150 loc) · 5.3 KB
/
Copy pathmain-page.ts
File metadata and controls
169 lines (150 loc) · 5.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import { Application, Color, EventData, isAndroid, Observable, Page, ScrollView, TextField } from '@nativescript/core'
import { MainViewModel } from './main-view-model'
import { dashboardController } from '../g2/dashboard-controller'
const SETTINGS_TEXT_COLOR = new Color('#222222')
const SETTINGS_BACKGROUND_COLOR = new Color('#ffffff')
const SETTINGS_PLACEHOLDER_COLOR = new Color('#666666')
export function navigatingTo(args: EventData) {
const page = <Page>args.object
page.bindingContext = new MainViewModel()
}
type MainPageState = {
model: MainViewModel
isPinnedToBottom: boolean
scrollViews: ScrollView[]
scrollHandler: (args: EventData) => void
propertyChangeHandler: (args: EventData & { propertyName?: string }) => void
orientationHandler: () => void
}
function getPageState(page: Page): MainPageState | undefined {
return (page as Page & { __mainPageState?: MainPageState }).__mainPageState
}
function setPageState(page: Page, state?: MainPageState): void {
;(page as Page & { __mainPageState?: MainPageState }).__mainPageState = state
}
function cleanupPage(page: Page): void {
const state = getPageState(page)
if (!state) {
setPageState(page, undefined)
return
}
for (const scrollView of state.scrollViews) {
scrollView.off(ScrollView.scrollEvent, state.scrollHandler)
}
state.model.off(Observable.propertyChangeEvent, state.propertyChangeHandler)
Application.off(Application.orientationChangedEvent, state.orientationHandler)
setPageState(page, undefined)
}
function isAtBottom(scrollView: ScrollView): boolean {
return scrollView.scrollableHeight <= 0 || scrollView.verticalOffset >= scrollView.scrollableHeight - 8
}
function scrollToBottom(scrollView: ScrollView): void {
setTimeout(() => {
scrollView.scrollToVerticalOffset(scrollView.scrollableHeight, false)
}, 0)
}
function scrollLogsToBottom(scrollViews: ScrollView[]): void {
for (const scrollView of scrollViews) {
scrollToBottom(scrollView)
}
}
function applySettingsTextFieldContrast(textField: TextField): void {
textField.color = SETTINGS_TEXT_COLOR
textField.backgroundColor = SETTINGS_BACKGROUND_COLOR
textField.placeholderColor = SETTINGS_PLACEHOLDER_COLOR
if (!isAndroid) {
return
}
const nativeTextField = (textField as TextField & { nativeView?: android.widget.EditText }).nativeView
if (!nativeTextField) {
return
}
nativeTextField.setTextColor(android.graphics.Color.rgb(34, 34, 34))
nativeTextField.setHintTextColor(android.graphics.Color.rgb(102, 102, 102))
// Editing an existing value usually means replacing it: select all on focus
// so typing starts fresh but the current value stays visible.
nativeTextField.setSelectAllOnFocus(true)
}
function focusSystemNameField(page: Page): void {
setTimeout(() => {
const textField = page.getViewById<TextField>('settingsTextField')
if (textField) {
applySettingsTextFieldContrast(textField)
}
textField?.focus()
}, 0)
}
export function loaded(args: EventData) {
const page = args.object as Page
cleanupPage(page)
dashboardController.refreshEvenAppStatus()
const model = page.bindingContext as MainViewModel | null
// Automatically connect on reaching the main page (no-op if already
// connected or if no glasses are configured).
void model?.autoConnect()
// Reopen the apps that were open before the last restart (no-op after the
// first load).
void dashboardController.restoreOpenApps()
const scrollViews = [
page.getViewById<ScrollView>('logScrollView'),
page.getViewById<ScrollView>('logScrollViewLandscape'),
].filter((scrollView): scrollView is ScrollView => !!scrollView)
const settingsTextField = page.getViewById<TextField>('settingsTextField')
model?.refreshLayoutMetrics()
if (settingsTextField) {
applySettingsTextFieldContrast(settingsTextField)
}
if (!model || scrollViews.length === 0) {
return
}
const state: MainPageState = {
model,
isPinnedToBottom: true,
scrollViews,
scrollHandler: (scrollArgs) => {
state.isPinnedToBottom = isAtBottom(scrollArgs.object as ScrollView)
},
orientationHandler: () => {
setTimeout(() => {
model.refreshLayoutMetrics()
if (state.isPinnedToBottom) {
scrollLogsToBottom(scrollViews)
}
}, 0)
},
propertyChangeHandler: (propertyArgs) => {
if (propertyArgs.propertyName === 'showLog') {
if (model.showLog) {
state.isPinnedToBottom = true
scrollLogsToBottom(scrollViews)
}
return
}
if (propertyArgs.propertyName === 'activeTextSettingId') {
if (model.isTextSettingEditorActive) {
focusSystemNameField(page)
}
return
}
if (propertyArgs.propertyName !== 'log') {
return
}
if (state.isPinnedToBottom) {
scrollLogsToBottom(scrollViews)
}
},
}
for (const scrollView of scrollViews) {
scrollView.on(ScrollView.scrollEvent, state.scrollHandler)
}
model.on(Observable.propertyChangeEvent, state.propertyChangeHandler)
Application.on(Application.orientationChangedEvent, state.orientationHandler)
setPageState(page, state)
scrollLogsToBottom(scrollViews)
if (model.isTextSettingEditorActive) {
focusSystemNameField(page)
}
}
export function unloaded(args: EventData) {
cleanupPage(args.object as Page)
}