@rentlydev/rently-tuya 0.2.1 → 0.2.3
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/android/src/main/java/com/rentlytuya/RentlyTuyaModule.kt +10 -0
- package/android/src/main/java/com/rentlytuya/alerts/PermissionAlert.kt +2 -2
- package/android/src/main/java/com/rentlytuya/components/AnchorButton.kt +4 -2
- package/android/src/main/java/com/rentlytuya/components/Button.kt +5 -4
- package/android/src/main/java/com/rentlytuya/components/CustomDatePicker.kt +9 -7
- package/android/src/main/java/com/rentlytuya/components/Divider.kt +1 -5
- package/android/src/main/java/com/rentlytuya/components/Label.kt +1 -1
- package/android/src/main/java/com/rentlytuya/dashboard/AdvancedSettings.kt +11 -9
- package/android/src/main/java/com/rentlytuya/dashboard/Dashboard.kt +4 -4
- package/android/src/main/java/com/rentlytuya/dashboard/DoorbellSettings.kt +125 -103
- package/android/src/main/java/com/rentlytuya/dashboard/FirmwareUpdate.kt +5 -8
- package/android/src/main/java/com/rentlytuya/dashboard/Messages.kt +3 -4
- package/android/src/main/java/com/rentlytuya/dashboard/NavController.kt +28 -13
- package/android/src/main/java/com/rentlytuya/dashboard/OfflineScreen.kt +12 -12
- package/android/src/main/java/com/rentlytuya/dashboard/Playback.kt +3 -3
- package/android/src/main/java/com/rentlytuya/tuya/Settings.kt +28 -1
- package/android/src/main/java/com/rentlytuya/tuya/Tuya.kt +6 -1
- package/android/src/main/java/com/rentlytuya/ui/theme/LocalColor.kt +34 -21
- package/android/src/main/java/com/rentlytuya/ui/theme/Theme.kt +13 -1
- package/android/src/main/java/com/rentlytuya/util/KeylessModule.kt +16 -4
- package/android/src/main/res/drawable/update_complete.png +0 -0
- package/android/src/main/res/values/strings.xml +4 -2
- package/ios/components/Alert.swift +5 -7
- package/ios/components/AnchorButton.swift +2 -0
- package/ios/components/Button.swift +17 -2
- package/ios/components/CustomDatePicker.swift +5 -5
- package/ios/components/Label.swift +6 -1
- package/ios/dashboard/AdvanceSettings.swift +5 -5
- package/ios/dashboard/Dashboard.swift +43 -6
- package/ios/dashboard/FirmwareSettings.swift +11 -9
- package/ios/dashboard/Messages.swift +5 -3
- package/ios/dashboard/NavigationController.swift +51 -8
- package/ios/dashboard/OfflineScreen.swift +5 -7
- package/ios/dashboard/Playback.swift +7 -5
- package/ios/dashboard/PreviewManager.swift +20 -4
- package/ios/dashboard/Settings.swift +39 -21
- package/ios/generated/RNRentlyTuyaSpec/RNRentlyTuyaSpec.h +30 -0
- package/ios/icons/cloud.png +0 -0
- package/ios/icons/cloud@2x.png +0 -0
- package/ios/icons/cloud@3x.png +0 -0
- package/ios/icons/down_update.png +0 -0
- package/ios/icons/down_update@2x.png +0 -0
- package/ios/icons/down_update@3x.png +0 -0
- package/ios/listener/KeylessListener.swift +11 -5
- package/ios/listener/RentlyTuya.mm +6 -1
- package/ios/listener/RentlyTuyaImpl.swift +11 -1
- package/ios/theme/LocalColor.swift +66 -20
- package/ios/theme/Theme.swift +162 -25
- package/ios/tuya/CameraManager.swift +1 -1
- package/ios/tuya/Tuya.swift +8 -0
- package/ios/utils/PermissionManager.swift +41 -0
- package/lib/commonjs/NativeRentlyTuya.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/NativeRentlyTuya.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/commonjs/src/NativeRentlyTuya.d.ts +5 -0
- package/lib/typescript/commonjs/src/NativeRentlyTuya.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.d.ts +5 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/NativeRentlyTuya.d.ts +5 -0
- package/lib/typescript/module/src/NativeRentlyTuya.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts +5 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/NativeRentlyTuya.ts +5 -0
- package/src/index.tsx +5 -0
- package/android/src/main/res/drawable/green_complete.png +0 -0
- package/android/src/main/res/drawable/white_complete.png +0 -0
|
@@ -19,6 +19,9 @@ struct CustomButton: View {
|
|
|
19
19
|
var secondary: Bool = false
|
|
20
20
|
var tertiary: Bool = false
|
|
21
21
|
var black: Bool = false
|
|
22
|
+
|
|
23
|
+
//disabled Button Color
|
|
24
|
+
var greyDisabled: Bool = false
|
|
22
25
|
|
|
23
26
|
// Text/Border Color
|
|
24
27
|
var textColor: Color = .black
|
|
@@ -42,7 +45,7 @@ struct CustomButton: View {
|
|
|
42
45
|
if primary {
|
|
43
46
|
return LocalColor.Primary.medium
|
|
44
47
|
} else if secondary {
|
|
45
|
-
return Color(
|
|
48
|
+
return Color(hex: "#EF4343")
|
|
46
49
|
} else if tertiary {
|
|
47
50
|
return LocalColor.Monochrome.regular
|
|
48
51
|
} else if black {
|
|
@@ -52,6 +55,18 @@ struct CustomButton: View {
|
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
57
|
|
|
58
|
+
var disabledButtonColor: Color? {
|
|
59
|
+
if greyDisabled {
|
|
60
|
+
return Color(hex: "#6B7280")
|
|
61
|
+
} else if black {
|
|
62
|
+
return LocalColor.Monochrome.black
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
return LocalColor.Primary.light
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
|
|
55
70
|
var body: some View {
|
|
56
71
|
|
|
57
72
|
let font: Font = {
|
|
@@ -97,7 +112,7 @@ struct CustomButton: View {
|
|
|
97
112
|
.frame(maxWidth: .infinity)
|
|
98
113
|
}
|
|
99
114
|
.padding()
|
|
100
|
-
.background(buttonColor)
|
|
115
|
+
.background( (Tuya.shared.darkThemefinal && !secondary) ? disabledButtonColor ?? buttonColor : buttonColor)
|
|
101
116
|
.opacity(disabled ? 0.5 : 1)
|
|
102
117
|
.cornerRadius(cornerRadius)
|
|
103
118
|
.overlay(
|
|
@@ -52,7 +52,7 @@ struct CustomDatePicker: View {
|
|
|
52
52
|
Spacer()
|
|
53
53
|
}
|
|
54
54
|
.frame(maxWidth: .infinity)
|
|
55
|
-
.background(LocalColor.Main.dark)
|
|
55
|
+
.background(Tuya.shared.darkThemefinal ? Color(hex: "#242526") : LocalColor.Main.dark)
|
|
56
56
|
|
|
57
57
|
HStack {
|
|
58
58
|
Button(action: {
|
|
@@ -70,7 +70,7 @@ struct CustomDatePicker: View {
|
|
|
70
70
|
Label(
|
|
71
71
|
title: formatMonthYear(date: displayedDate),
|
|
72
72
|
xl18: true,
|
|
73
|
-
|
|
73
|
+
blackColor: true,
|
|
74
74
|
bold: true
|
|
75
75
|
)
|
|
76
76
|
|
|
@@ -93,7 +93,7 @@ struct CustomDatePicker: View {
|
|
|
93
93
|
VStack {
|
|
94
94
|
Spacer()
|
|
95
95
|
ProgressView()
|
|
96
|
-
.progressViewStyle(CircularProgressViewStyle(tint: LocalColor.Monochrome.
|
|
96
|
+
.progressViewStyle(CircularProgressViewStyle(tint: LocalColor.Monochrome.blackColor))
|
|
97
97
|
Spacer()
|
|
98
98
|
}
|
|
99
99
|
.frame(maxWidth: .infinity)
|
|
@@ -117,7 +117,7 @@ struct CustomDatePicker: View {
|
|
|
117
117
|
id: "DatePicker_Cancel",
|
|
118
118
|
title: "Cancel",
|
|
119
119
|
l: true,
|
|
120
|
-
|
|
120
|
+
paleWhite: true,
|
|
121
121
|
center: true
|
|
122
122
|
) {
|
|
123
123
|
onCancel()
|
|
@@ -205,7 +205,7 @@ struct CalendarView: View {
|
|
|
205
205
|
.font(.footnote)
|
|
206
206
|
.frame(width: 30, height: 30)
|
|
207
207
|
.background(isSelected ? LocalColor.Main.dark : LocalColor.Monochrome.transparent)
|
|
208
|
-
.foregroundColor(isSelected ? LocalColor.Monochrome.
|
|
208
|
+
.foregroundColor(isSelected ? LocalColor.Monochrome.whiteColor : (isAvailable ? LocalColor.Monochrome.blackColor : LocalColor.Monochrome.greyColor))
|
|
209
209
|
.overlay(
|
|
210
210
|
Circle()
|
|
211
211
|
.stroke(isAvailable ? LocalColor.Main.dark : LocalColor.Monochrome.transparent, lineWidth: 1)
|
|
@@ -22,7 +22,10 @@ struct Label: View {
|
|
|
22
22
|
var lightGrey: Bool = false
|
|
23
23
|
var grey: Bool = false
|
|
24
24
|
var white: Bool = false
|
|
25
|
+
var whiteColor: Bool = false
|
|
25
26
|
var black: Bool = false
|
|
27
|
+
var blackColor: Bool = false
|
|
28
|
+
var greyColor: Bool = false
|
|
26
29
|
var customColor: Color? = nil
|
|
27
30
|
|
|
28
31
|
// Font Weight Options
|
|
@@ -58,8 +61,10 @@ struct Label: View {
|
|
|
58
61
|
if secondary { return LocalColor.Primary.secondary }
|
|
59
62
|
if lightGrey { return LocalColor.Monochrome.regular }
|
|
60
63
|
if grey { return LocalColor.Monochrome.medium }
|
|
61
|
-
if white { return LocalColor.Monochrome.
|
|
64
|
+
if white { return LocalColor.Monochrome.whiteColor }
|
|
62
65
|
if black { return LocalColor.Monochrome.black }
|
|
66
|
+
if blackColor { return LocalColor.Monochrome.blackColor }
|
|
67
|
+
if greyColor { return LocalColor.Monochrome.greyColor }
|
|
63
68
|
return LocalColor.Primary.light
|
|
64
69
|
}()
|
|
65
70
|
|
|
@@ -64,11 +64,11 @@ struct StorageSettings: View {
|
|
|
64
64
|
VStack(alignment: .leading) {
|
|
65
65
|
Text("Note:")
|
|
66
66
|
.font(.custom(LocalFont.FontFamily.bold, size: LocalFont.FontSize.L))
|
|
67
|
-
.foregroundColor(LocalColor.Monochrome.
|
|
67
|
+
.foregroundColor(LocalColor.Monochrome.greyColor)
|
|
68
68
|
+
|
|
69
69
|
Text(" Formatting will delete all recorded activities on the SD Card.")
|
|
70
70
|
.font(.custom(LocalFont.FontFamily.semiBold, size: LocalFont.FontSize.L))
|
|
71
|
-
.foregroundColor(LocalColor.Monochrome.
|
|
71
|
+
.foregroundColor(LocalColor.Monochrome.greyColor)
|
|
72
72
|
Spacer()
|
|
73
73
|
HStack {
|
|
74
74
|
Spacer()
|
|
@@ -76,7 +76,7 @@ struct StorageSettings: View {
|
|
|
76
76
|
id: "FormatSDCard",
|
|
77
77
|
title: "Format",
|
|
78
78
|
secondary: true,
|
|
79
|
-
textColor: LocalColor.Monochrome.
|
|
79
|
+
textColor: LocalColor.Monochrome.whiteColor,
|
|
80
80
|
semiBold: true,
|
|
81
81
|
disabled: tuya.sdCardStatus == 4
|
|
82
82
|
) {
|
|
@@ -107,7 +107,7 @@ struct Item: View {
|
|
|
107
107
|
id: title,
|
|
108
108
|
title: title,
|
|
109
109
|
l: true,
|
|
110
|
-
|
|
110
|
+
grey: true,
|
|
111
111
|
semiBold: true
|
|
112
112
|
)
|
|
113
113
|
Spacer()
|
|
@@ -116,7 +116,7 @@ struct Item: View {
|
|
|
116
116
|
id: value,
|
|
117
117
|
title: value,
|
|
118
118
|
l: true,
|
|
119
|
-
|
|
119
|
+
lightGrey: true,
|
|
120
120
|
medium: true,
|
|
121
121
|
right: true,
|
|
122
122
|
maxLines: 3
|
|
@@ -15,6 +15,7 @@ struct Dashboard: View {
|
|
|
15
15
|
@Binding var currentScreen: ScreenState
|
|
16
16
|
@State private var isDoorbellControlVisible = true
|
|
17
17
|
@State private var isPermissionDisclaimerAlertVisible = false
|
|
18
|
+
@State private var permissionType: String = "microphone"
|
|
18
19
|
@EnvironmentObject var orientationManager: OrientationManager
|
|
19
20
|
|
|
20
21
|
var body: some View {
|
|
@@ -32,7 +33,8 @@ struct Dashboard: View {
|
|
|
32
33
|
if tuya.isConnected {
|
|
33
34
|
DoorbellControls(
|
|
34
35
|
isDoorbellControlVisible: $isDoorbellControlVisible,
|
|
35
|
-
isPermissionDisclaimerAlertVisible: $isPermissionDisclaimerAlertVisible
|
|
36
|
+
isPermissionDisclaimerAlertVisible: $isPermissionDisclaimerAlertVisible,
|
|
37
|
+
permissionType: $permissionType
|
|
36
38
|
)
|
|
37
39
|
.padding(.bottom, 10)
|
|
38
40
|
.alert(
|
|
@@ -46,7 +48,7 @@ struct Dashboard: View {
|
|
|
46
48
|
}
|
|
47
49
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
48
50
|
|
|
49
|
-
BottomBar(currentScreen: $currentScreen)
|
|
51
|
+
BottomBar(currentScreen: $currentScreen, isPermissionDisclaimerAlertVisible: $isPermissionDisclaimerAlertVisible, permissionType: $permissionType)
|
|
50
52
|
.alert(
|
|
51
53
|
isPresented: $tuya.isRecordingFailure,
|
|
52
54
|
content: {
|
|
@@ -75,6 +77,21 @@ struct Dashboard: View {
|
|
|
75
77
|
)
|
|
76
78
|
}
|
|
77
79
|
|
|
80
|
+
VStack {
|
|
81
|
+
}
|
|
82
|
+
.alert(isPresented: $isPermissionDisclaimerAlertVisible,
|
|
83
|
+
content: {
|
|
84
|
+
getAlert(
|
|
85
|
+
title: "Permission Request",
|
|
86
|
+
message: "Please provide permission to access your \(permissionType)",
|
|
87
|
+
primaryButtonTitle: "Open Settings",
|
|
88
|
+
secondaryButtonTitle: "Cancel") {
|
|
89
|
+
if let url = URL(string: UIApplication.openSettingsURLString) {
|
|
90
|
+
UIApplication.shared.open(url)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
)
|
|
78
95
|
}
|
|
79
96
|
.background(LocalColor.Monochrome.black)
|
|
80
97
|
.onAppear(perform: handleOnAppear)
|
|
@@ -129,7 +146,7 @@ struct Dashboard: View {
|
|
|
129
146
|
}
|
|
130
147
|
|
|
131
148
|
if tuya.isConnected {
|
|
132
|
-
tuya.enableMute(enable: false, type: .preview)
|
|
149
|
+
tuya.enableMute(enable: tuya.doorbell_setting ?? false, type: .preview)
|
|
133
150
|
}
|
|
134
151
|
|
|
135
152
|
orientationManager.updateOrientationFlag()
|
|
@@ -165,6 +182,7 @@ struct DoorbellControls: View {
|
|
|
165
182
|
@ObservedObject var tuya = Tuya.shared
|
|
166
183
|
@Binding var isDoorbellControlVisible: Bool
|
|
167
184
|
@Binding var isPermissionDisclaimerAlertVisible: Bool
|
|
185
|
+
@Binding var permissionType: String
|
|
168
186
|
@EnvironmentObject var orientationManager: OrientationManager
|
|
169
187
|
|
|
170
188
|
private var batteryIcon: String {
|
|
@@ -219,7 +237,8 @@ struct DoorbellControls: View {
|
|
|
219
237
|
title: tuya.isMicOn ? "Tap to mute" : "Tap to speak",
|
|
220
238
|
l: true,
|
|
221
239
|
tertiary: !tuya.isMicOn,
|
|
222
|
-
|
|
240
|
+
greyDisabled: !tuya.isMicOn,
|
|
241
|
+
textColor: Color.white,
|
|
223
242
|
medium: tuya.isMicOn,
|
|
224
243
|
semiBold: true,
|
|
225
244
|
cornerRadius: 40,
|
|
@@ -228,11 +247,17 @@ struct DoorbellControls: View {
|
|
|
228
247
|
if tuya.isMicOn {
|
|
229
248
|
tuya.stopTalk()
|
|
230
249
|
} else {
|
|
250
|
+
PermissionManager.request(.microphone, granted: {
|
|
251
|
+
tuya.startTalk()
|
|
252
|
+
}, denied: {
|
|
253
|
+
permissionType = "microphone"
|
|
254
|
+
isPermissionDisclaimerAlertVisible = true
|
|
255
|
+
}
|
|
256
|
+
)
|
|
231
257
|
// The speaker needs to be un muted when the mic is turned on.
|
|
232
258
|
if tuya.isMuted {
|
|
233
259
|
tuya.enableMute(enable: false, type: .preview)
|
|
234
260
|
}
|
|
235
|
-
tuya.startTalk()
|
|
236
261
|
}
|
|
237
262
|
}
|
|
238
263
|
.frame(width: 185, height: 70)
|
|
@@ -279,6 +304,8 @@ struct BottomBar: View {
|
|
|
279
304
|
|
|
280
305
|
@ObservedObject var tuya = Tuya.shared
|
|
281
306
|
@Binding var currentScreen: ScreenState
|
|
307
|
+
@Binding var isPermissionDisclaimerAlertVisible: Bool
|
|
308
|
+
@Binding var permissionType: String
|
|
282
309
|
@EnvironmentObject var orientationManager: OrientationManager
|
|
283
310
|
|
|
284
311
|
var body: some View {
|
|
@@ -310,7 +337,12 @@ struct BottomBar: View {
|
|
|
310
337
|
print("Camera not connected. Screenshot action disabled.")
|
|
311
338
|
return
|
|
312
339
|
}
|
|
313
|
-
|
|
340
|
+
PermissionManager.request(.photos) {
|
|
341
|
+
tuya.screenshot()
|
|
342
|
+
} denied: {
|
|
343
|
+
permissionType = "Photos Library"
|
|
344
|
+
isPermissionDisclaimerAlertVisible = true
|
|
345
|
+
}
|
|
314
346
|
}
|
|
315
347
|
)
|
|
316
348
|
|
|
@@ -328,7 +360,12 @@ struct BottomBar: View {
|
|
|
328
360
|
if tuya.isRecording {
|
|
329
361
|
tuya.stopRecording()
|
|
330
362
|
} else {
|
|
363
|
+
PermissionManager.request(.photos) {
|
|
331
364
|
tuya.startRecording()
|
|
365
|
+
} denied: {
|
|
366
|
+
permissionType = "Photos Library"
|
|
367
|
+
isPermissionDisclaimerAlertVisible = true
|
|
368
|
+
}
|
|
332
369
|
}
|
|
333
370
|
}
|
|
334
371
|
)
|
|
@@ -15,13 +15,13 @@ struct FirmwareSettings: View {
|
|
|
15
15
|
if tuya.isFirmwareUpdateInProgress {
|
|
16
16
|
ZStack {
|
|
17
17
|
Circle()
|
|
18
|
-
.stroke(LocalColor.
|
|
18
|
+
.stroke(LocalColor.Main.dark.opacity(0.2), lineWidth: 6)
|
|
19
19
|
.frame(width: 132, height: 132)
|
|
20
20
|
.padding(20)
|
|
21
21
|
|
|
22
22
|
Circle()
|
|
23
23
|
.trim(from: 0.0, to: CGFloat(tuya.firmwareUpdateProgress) / 100)
|
|
24
|
-
.stroke(LocalColor.
|
|
24
|
+
.stroke(LocalColor.Main.dark, style: StrokeStyle(lineWidth: 6, lineCap: .round))
|
|
25
25
|
.rotationEffect(.degrees(-90))
|
|
26
26
|
.frame(width: 132, height: 132)
|
|
27
27
|
.padding(20)
|
|
@@ -43,7 +43,7 @@ struct FirmwareSettings: View {
|
|
|
43
43
|
Spacer()
|
|
44
44
|
Label(title: tuya.firmwareUpdateProgress >= 50 && tuya.firmwareUpdateProgress < 100 ? "Please keep the doorbell powered on while we complete this update. Thank you for your patience." : "This might take a few minutes. During this time you will not be able to use your video doorbell.",
|
|
45
45
|
l: true,
|
|
46
|
-
|
|
46
|
+
blackColor: true,
|
|
47
47
|
center: true)
|
|
48
48
|
.padding(20)
|
|
49
49
|
}
|
|
@@ -61,26 +61,26 @@ struct FirmwareSettings: View {
|
|
|
61
61
|
Label(
|
|
62
62
|
title: "Current Firmware Version:",
|
|
63
63
|
l: true,
|
|
64
|
-
|
|
64
|
+
grey: true,
|
|
65
65
|
semiBold: true
|
|
66
66
|
)
|
|
67
67
|
Label(
|
|
68
68
|
title: (tuya.firmwareNewVersion != nil) ? "New Version Available:" : "",
|
|
69
69
|
l: true,
|
|
70
|
-
|
|
70
|
+
grey: true,
|
|
71
71
|
semiBold: true
|
|
72
72
|
)
|
|
73
73
|
VStack(alignment: .leading, spacing: 0) {
|
|
74
74
|
Label(
|
|
75
75
|
title: Tuya.shared.whatsNew != nil ? "What's new?" : "",
|
|
76
76
|
l: true,
|
|
77
|
-
|
|
77
|
+
grey: true,
|
|
78
78
|
semiBold: true
|
|
79
79
|
)
|
|
80
80
|
Label(
|
|
81
81
|
title: Tuya.shared.whatsNew ?? "",
|
|
82
82
|
l: true,
|
|
83
|
-
|
|
83
|
+
grey: true,
|
|
84
84
|
semiBold: true
|
|
85
85
|
)
|
|
86
86
|
.padding(12)
|
|
@@ -91,13 +91,14 @@ struct FirmwareSettings: View {
|
|
|
91
91
|
Label(
|
|
92
92
|
title: Tuya.shared.firmwareVersion ?? "",
|
|
93
93
|
l: true,
|
|
94
|
-
|
|
94
|
+
lightGrey: true,
|
|
95
95
|
semiBold: true
|
|
96
96
|
)
|
|
97
97
|
|
|
98
98
|
Label(
|
|
99
99
|
title: Tuya.shared.firmwareNewVersion ?? "",
|
|
100
100
|
l: true,
|
|
101
|
+
lightGrey: true,
|
|
101
102
|
semiBold: true
|
|
102
103
|
)
|
|
103
104
|
Spacer()
|
|
@@ -146,7 +147,8 @@ struct FirmwareSettings: View {
|
|
|
146
147
|
id: "UpdateFirmware",
|
|
147
148
|
title: "Update Firmware",
|
|
148
149
|
l: true,
|
|
149
|
-
|
|
150
|
+
greyDisabled: tuya.isAutomaticUpdateEnabled || !tuya.isFirmwareUpdateAvailable || tuya.isFirmwareUpdateInProgress,
|
|
151
|
+
textColor: LocalColor.Monochrome.whiteColor,
|
|
150
152
|
medium: true,
|
|
151
153
|
semiBold: true,
|
|
152
154
|
disabled: tuya.isAutomaticUpdateEnabled || !tuya.isFirmwareUpdateAvailable || tuya.isFirmwareUpdateInProgress,
|
|
@@ -24,7 +24,7 @@ struct Messages: View {
|
|
|
24
24
|
ZStack {
|
|
25
25
|
if tuya.messagesLoader && messages.isEmpty {
|
|
26
26
|
ProgressView()
|
|
27
|
-
.progressViewStyle(CircularProgressViewStyle(tint: LocalColor.Monochrome.
|
|
27
|
+
.progressViewStyle(CircularProgressViewStyle(tint: LocalColor.Monochrome.blackColor))
|
|
28
28
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
29
29
|
} else if messages.isEmpty {
|
|
30
30
|
NoMessages()
|
|
@@ -157,6 +157,7 @@ struct NoMessages: View {
|
|
|
157
157
|
Label(
|
|
158
158
|
id: "noMessages",
|
|
159
159
|
title: "No activity available at the moment.",
|
|
160
|
+
blackColor: true,
|
|
160
161
|
bold: true,
|
|
161
162
|
maxLines: 2
|
|
162
163
|
)
|
|
@@ -176,13 +177,14 @@ struct MessageItem: View {
|
|
|
176
177
|
Label(
|
|
177
178
|
title: formattedDateTime ?? message.dateTime,
|
|
178
179
|
m: true,
|
|
179
|
-
|
|
180
|
+
lightGrey: true
|
|
180
181
|
)
|
|
181
182
|
.padding(.bottom, 3)
|
|
182
183
|
|
|
183
184
|
Label(
|
|
184
185
|
title: (message.attachPic != nil) ? message.msgContent : "Unable to capture detected events because the doorbell's battery is too low. Please charge it to ensure events are detected and recorded.",
|
|
185
|
-
l: true
|
|
186
|
+
l: true,
|
|
187
|
+
grey: true
|
|
186
188
|
)
|
|
187
189
|
.padding(.bottom, 4)
|
|
188
190
|
|
|
@@ -5,7 +5,7 @@ enum ScreenState: String {
|
|
|
5
5
|
case playback = "Playback"
|
|
6
6
|
case messages = "Activity History"
|
|
7
7
|
case settings = "Settings"
|
|
8
|
-
case advancedSettings = "
|
|
8
|
+
case advancedSettings = "Device Information"
|
|
9
9
|
case storageSettings = "Activity Storage"
|
|
10
10
|
case firmwareUpdateSettings = "Firmware Update"
|
|
11
11
|
}
|
|
@@ -22,18 +22,38 @@ struct NavigationController: View {
|
|
|
22
22
|
@State private var updateSettingsTask: Task<Void, Never>? = nil
|
|
23
23
|
@EnvironmentObject var orientationManager: OrientationManager
|
|
24
24
|
@ObservedObject var tuya = Tuya.shared
|
|
25
|
+
@Environment(\.colorScheme) private var colorScheme
|
|
26
|
+
@State private var themeUpdateTrigger: Int = 0
|
|
25
27
|
|
|
26
28
|
private var topBarTitle: String {
|
|
27
29
|
if isFirmwareUpdateSettings {
|
|
28
30
|
return tuya.isFirmwareUpdateInProgress ? "Update Firmware" : "Firmware Version"
|
|
29
31
|
}
|
|
30
|
-
if isAdvancedSettings { return "
|
|
32
|
+
if isAdvancedSettings { return "Device Information" }
|
|
31
33
|
if isStorageSettings { return "Activity Storage" }
|
|
32
34
|
return currentScreen == .dashboard ? (tuya.device?.deviceModel.name ?? "Doorbell") : currentScreen.rawValue
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
private var isSpecialTitle: Bool {
|
|
36
|
-
[.settings, .messages, .advancedSettings, .storageSettings, .firmwareUpdateSettings].contains(currentScreen)
|
|
38
|
+
[.settings, .messages, .advancedSettings, .storageSettings, .firmwareUpdateSettings, .playback].contains(currentScreen)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private func onThemeChanged(_ scheme: ColorScheme) {
|
|
42
|
+
guard tuya.useSystemTheme else { return }
|
|
43
|
+
DispatchQueue.main.async {
|
|
44
|
+
tuya.currentSystemColorScheme = scheme == .dark ? "dark" : "light"
|
|
45
|
+
tuya.darkThemefinal = tuya.currentSystemColorScheme == "dark"
|
|
46
|
+
|
|
47
|
+
Themes.configureTheme(for: tuya.flavour, darkThemeEnabled: tuya.darkThemefinal)
|
|
48
|
+
|
|
49
|
+
if let windowScene = UIApplication.shared.connectedScenes
|
|
50
|
+
.compactMap({ $0 as? UIWindowScene })
|
|
51
|
+
.first(where: { $0.activationState == .foregroundActive }),
|
|
52
|
+
let window = windowScene.windows.first(where: { $0.isKeyWindow }) {
|
|
53
|
+
window.overrideUserInterfaceStyle = tuya.darkThemefinal ? .dark : .light
|
|
54
|
+
}
|
|
55
|
+
themeUpdateTrigger += 1
|
|
56
|
+
}
|
|
37
57
|
}
|
|
38
58
|
|
|
39
59
|
var body: some View {
|
|
@@ -68,8 +88,12 @@ struct NavigationController: View {
|
|
|
68
88
|
} else if currentScreen == .dashboard {
|
|
69
89
|
AppUtility.disconnectAndClose()
|
|
70
90
|
} else {
|
|
71
|
-
|
|
72
|
-
|
|
91
|
+
if Tuya.shared.doorbell_setting ?? false {
|
|
92
|
+
AppUtility.disconnectAndClose()
|
|
93
|
+
} else {
|
|
94
|
+
isSettings = false
|
|
95
|
+
currentScreen = .dashboard
|
|
96
|
+
}
|
|
73
97
|
}
|
|
74
98
|
}
|
|
75
99
|
}
|
|
@@ -85,6 +109,11 @@ struct NavigationController: View {
|
|
|
85
109
|
}
|
|
86
110
|
}
|
|
87
111
|
)
|
|
112
|
+
.onAppear {
|
|
113
|
+
if currentScreen == .dashboard && Tuya.shared.doorbell_setting ?? false {
|
|
114
|
+
currentScreen = .settings
|
|
115
|
+
}
|
|
116
|
+
}
|
|
88
117
|
}
|
|
89
118
|
|
|
90
119
|
ZStack {
|
|
@@ -125,6 +154,7 @@ struct NavigationController: View {
|
|
|
125
154
|
}
|
|
126
155
|
}
|
|
127
156
|
}
|
|
157
|
+
.id(themeUpdateTrigger)
|
|
128
158
|
.onChange(of: currentScreen) { newValue in
|
|
129
159
|
HeapAnalytics.trackEvent(eventName: "\(newValue.rawValue) Screen")
|
|
130
160
|
}
|
|
@@ -143,7 +173,15 @@ struct NavigationController: View {
|
|
|
143
173
|
}
|
|
144
174
|
}
|
|
145
175
|
}
|
|
176
|
+
.onChange(of: colorScheme) { newScheme in
|
|
177
|
+
onThemeChanged(newScheme)
|
|
178
|
+
}
|
|
146
179
|
.onReceive(NotificationCenter.default.publisher(for: UIApplication.didEnterBackgroundNotification)) { _ in
|
|
180
|
+
if tuya.useSystemTheme {
|
|
181
|
+
let interfaceStyle = UITraitCollection.current.userInterfaceStyle
|
|
182
|
+
tuya.currentSystemColorScheme = interfaceStyle == .dark ? "dark" : "light"
|
|
183
|
+
onThemeChanged(interfaceStyle == .dark ? .dark : .light)
|
|
184
|
+
}
|
|
147
185
|
if currentScreen == .playback {
|
|
148
186
|
tuya.pausePlayback()
|
|
149
187
|
} else {
|
|
@@ -151,6 +189,11 @@ struct NavigationController: View {
|
|
|
151
189
|
}
|
|
152
190
|
}
|
|
153
191
|
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
|
|
192
|
+
if tuya.useSystemTheme {
|
|
193
|
+
let interfaceStyle = UITraitCollection.current.userInterfaceStyle
|
|
194
|
+
tuya.currentSystemColorScheme = interfaceStyle == .dark ? "dark" : "light"
|
|
195
|
+
onThemeChanged(interfaceStyle == .dark ? .dark : .light)
|
|
196
|
+
}
|
|
154
197
|
if currentScreen == .dashboard {
|
|
155
198
|
tuya.connect()
|
|
156
199
|
}
|
|
@@ -171,7 +214,7 @@ struct TopBar: View {
|
|
|
171
214
|
title: title,
|
|
172
215
|
xl20: true,
|
|
173
216
|
white: !isSpecialTitle,
|
|
174
|
-
|
|
217
|
+
greyColor: isSpecialTitle,
|
|
175
218
|
semiBold: true
|
|
176
219
|
)
|
|
177
220
|
|
|
@@ -184,7 +227,7 @@ struct TopBar: View {
|
|
|
184
227
|
.resizable()
|
|
185
228
|
.aspectRatio(contentMode: .fit)
|
|
186
229
|
.frame(width: 22, height: 22)
|
|
187
|
-
.foregroundColor(isSpecialTitle ? LocalColor.Monochrome.
|
|
230
|
+
.foregroundColor(isSpecialTitle ? LocalColor.Monochrome.greyColor : LocalColor.Monochrome.whiteColor)
|
|
188
231
|
}
|
|
189
232
|
.padding(.leading, 5)
|
|
190
233
|
|
|
@@ -199,7 +242,7 @@ struct TopBar: View {
|
|
|
199
242
|
.resizable()
|
|
200
243
|
.aspectRatio(contentMode: .fit)
|
|
201
244
|
.frame(width: 24, height: 24)
|
|
202
|
-
.foregroundColor(title == "Activity History" ? LocalColor.Monochrome.
|
|
245
|
+
.foregroundColor(title == "Activity History" || title == "Playback" ? LocalColor.Monochrome.greyColor : LocalColor.Monochrome.whiteColor)
|
|
203
246
|
}
|
|
204
247
|
.padding(.trailing, 5)
|
|
205
248
|
}
|
|
@@ -70,17 +70,15 @@ struct OfflineScreen: View {
|
|
|
70
70
|
center: true,
|
|
71
71
|
underLine: true
|
|
72
72
|
) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
AppUtility.disconnectAndClose()
|
|
73
|
+
KeylessListener.emitter.resetWifiForDoorbell(
|
|
74
|
+
withTuyaProductName: tuya.tuyaProductName ?? "") { success, message in
|
|
75
|
+
if success {
|
|
76
|
+
print("Tuya: Successfully navigated to the 'Add Doorbell' screen.")
|
|
77
|
+
AppUtility.disconnectAndClose()
|
|
79
78
|
} else {
|
|
80
79
|
print("Tuya: Failed to navigate to the 'Add Doorbell' screen.")
|
|
81
80
|
}
|
|
82
81
|
}
|
|
83
|
-
}
|
|
84
82
|
}
|
|
85
83
|
.frame(maxWidth: .infinity, alignment: .center)
|
|
86
84
|
.padding(.bottom, 5)
|
|
@@ -86,7 +86,7 @@ struct Playback: View {
|
|
|
86
86
|
|
|
87
87
|
if tuya.playbackLoader {
|
|
88
88
|
ProgressView()
|
|
89
|
-
.progressViewStyle(CircularProgressViewStyle(tint: LocalColor.Monochrome.
|
|
89
|
+
.progressViewStyle(CircularProgressViewStyle(tint: LocalColor.Monochrome.blackColor))
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
CustomDatePicker(
|
|
@@ -293,7 +293,7 @@ struct PlaybackList: View {
|
|
|
293
293
|
id: "noPlaybackVideos",
|
|
294
294
|
title: "No Playback videos available at the moment.",
|
|
295
295
|
xl18: true,
|
|
296
|
-
|
|
296
|
+
blackColor: true,
|
|
297
297
|
semiBold: true,
|
|
298
298
|
center: true
|
|
299
299
|
)
|
|
@@ -342,7 +342,8 @@ struct VideoItem: View {
|
|
|
342
342
|
Label(
|
|
343
343
|
title: "\(convertTimestampToTime(item["startTime"] as? Int))",
|
|
344
344
|
l: true,
|
|
345
|
-
|
|
345
|
+
grey: !isSelected,
|
|
346
|
+
white: isSelected,
|
|
346
347
|
bold: true,
|
|
347
348
|
left: true
|
|
348
349
|
)
|
|
@@ -350,7 +351,8 @@ struct VideoItem: View {
|
|
|
350
351
|
Label(
|
|
351
352
|
title: ("Duration: \(calculateVideoDuration(from: item["startTime"] as? Int, to: item["endTime"] as? Int))"),
|
|
352
353
|
m: true,
|
|
353
|
-
|
|
354
|
+
lightGrey: !isSelected,
|
|
355
|
+
white: isSelected,
|
|
354
356
|
left: true
|
|
355
357
|
)
|
|
356
358
|
.padding(.top, 5)
|
|
@@ -360,7 +362,7 @@ struct VideoItem: View {
|
|
|
360
362
|
Spacer()
|
|
361
363
|
}
|
|
362
364
|
.frame(maxWidth: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/)
|
|
363
|
-
.background(isSelected ? LocalColor.
|
|
365
|
+
.background(isSelected ? LocalColor.Main.dark : LocalColor.Monochrome.white)
|
|
364
366
|
.cornerRadius(5)
|
|
365
367
|
.padding(.top, 8)
|
|
366
368
|
.padding(.horizontal, 10)
|
|
@@ -102,15 +102,31 @@ struct PreviewView: UIViewRepresentable {
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
func openLivePreview(appFlavor: String) {
|
|
106
|
-
|
|
105
|
+
func openLivePreview(appFlavor: String, darkThemeEnabled: Bool = false, useSystemTheme: Bool = false, currentSystemColorScheme: String = "light") {
|
|
106
|
+
Tuya.shared.darkThemeEnabled = darkThemeEnabled
|
|
107
|
+
Tuya.shared.useSystemTheme = useSystemTheme
|
|
108
|
+
Tuya.shared.currentSystemColorScheme = currentSystemColorScheme
|
|
109
|
+
if useSystemTheme {
|
|
110
|
+
let interfaceStyle = UITraitCollection.current.userInterfaceStyle
|
|
111
|
+
Tuya.shared.currentSystemColorScheme = interfaceStyle == .dark ? "dark" : "light"
|
|
112
|
+
}
|
|
113
|
+
Tuya.shared.darkThemefinal = useSystemTheme ? (Tuya.shared.currentSystemColorScheme == "dark") : darkThemeEnabled
|
|
107
114
|
DispatchQueue.main.async {
|
|
108
|
-
Themes.configureTheme(for: appFlavor)
|
|
115
|
+
Themes.configureTheme(for: appFlavor, darkThemeEnabled: Tuya.shared.darkThemefinal)
|
|
116
|
+
|
|
117
|
+
if let windowScene = UIApplication.shared.connectedScenes
|
|
118
|
+
.compactMap({ $0 as? UIWindowScene })
|
|
119
|
+
.first(where: { $0.activationState == .foregroundActive }),
|
|
120
|
+
let window = windowScene.windows.first(where: { $0.isKeyWindow }) {
|
|
121
|
+
window.overrideUserInterfaceStyle = Tuya.shared.darkThemefinal ? .dark : .light
|
|
122
|
+
}
|
|
123
|
+
|
|
109
124
|
let orientationManager = OrientationManager()
|
|
110
125
|
let dashboardView = NavigationController().environmentObject(orientationManager)
|
|
111
126
|
let hostingController = UIHostingController(rootView: dashboardView)
|
|
112
127
|
hostingController.modalPresentationStyle = .fullScreen
|
|
113
|
-
|
|
128
|
+
|
|
129
|
+
if let windowScene = UIApplication.shared.connectedScenes
|
|
114
130
|
.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene,
|
|
115
131
|
let rootVC = windowScene.windows.first(where: { $0.isKeyWindow })?.rootViewController {
|
|
116
132
|
rootVC.present(hostingController, animated: true, completion: nil)
|