@@ -3,6 +3,12 @@ import Shared
33import SwiftUI
44
55struct OnboardingServersListView : View {
6+ enum Constants {
7+ static let initialDelayUntilDismissCenterLoader : CGFloat = 3
8+ static let minimumDelayUntilDismissCenterLoader : CGFloat = 1.5
9+ static let delayUntilAutoconnect : CGFloat = 2
10+ }
11+
612 @Environment ( \. dismiss) private var dismiss
713 @Environment ( \. horizontalSizeClass) private var sizeClass
814
@@ -13,6 +19,8 @@ struct OnboardingServersListView: View {
1319 @State private var showManualInput = false
1420 @State private var screenLoaded = false
1521 @State private var autoConnectWorkItem : DispatchWorkItem ?
22+ @State private var autoConnectInstance : DiscoveredHomeAssistant ?
23+ @State private var autoConnectBottomSheetState : AppleLikeBottomSheetViewState ?
1624
1725 let prefillURL : URL ?
1826
@@ -28,10 +36,13 @@ struct OnboardingServersListView: View {
2836 content
2937 . animation ( . easeInOut, value: viewModel. discoveredInstances. count)
3038 centerLoader
39+ autoConnectView
3140 }
3241 . navigationBarTitleDisplayMode ( . inline)
3342 . safeAreaInset ( edge: . bottom, content: {
34- manualInputButton
43+ if autoConnectInstance == nil {
44+ manualInputButton
45+ }
3546 } )
3647 . toolbar ( content: {
3748 toolbarItems
@@ -50,14 +61,20 @@ struct OnboardingServersListView: View {
5061 . onChange ( of: viewModel. discoveredInstances) { newValue in
5162 if newValue. count == 1 {
5263 scheduleAutoConnect ( )
64+ scheduleCenterLoaderDimiss (
65+ amountOfTimeToWaitToDismissCenterLoader: Constants
66+ . initialDelayUntilDismissCenterLoader
67+ )
5368 } else if newValue. count > 1 {
5469 cancelAutoConnect ( )
70+ // We display the loader a bit after instances are discovered
71+ // if there is just 1 server available we connect to it automatically
72+ // otherwise we display the list of servers
73+ scheduleCenterLoaderDimiss (
74+ amountOfTimeToWaitToDismissCenterLoader: Constants
75+ . minimumDelayUntilDismissCenterLoader
76+ )
5577 }
56-
57- // We display the loader a bit after instances are discovered
58- // if there is just 1 server available we connect to it automatically
59- // otherwise we display the list of servers
60- scheduleCenterLoaderDimiss ( )
6178 }
6279 . sheet ( isPresented: $viewModel. showError) {
6380 errorView
@@ -80,25 +97,65 @@ struct OnboardingServersListView: View {
8097 }
8198 }
8299
100+ @ViewBuilder
101+ private var autoConnectView : some View {
102+ if autoConnectInstance != nil {
103+ AppleLikeBottomSheet (
104+ title: autoConnectInstance? . bonjourName ?? autoConnectInstance? . locationName ?? L10n . unknownLabel,
105+ content: {
106+ autoConnectViewContent ( instance: autoConnectInstance)
107+ } ,
108+ state: $autoConnectBottomSheetState,
109+ customDismiss: {
110+ autoConnectInstance = nil
111+ } ,
112+ willDismiss: {
113+ autoConnectInstance = nil
114+ }
115+ )
116+ }
117+ }
118+
119+ private func autoConnectViewContent( instance: DiscoveredHomeAssistant ? ) -> some View {
120+ VStack ( spacing: DesignSystem . Spaces. three) {
121+ Spacer ( )
122+ Image ( systemSymbol: . externaldriveConnectedToLineBelow)
123+ . resizable ( )
124+ . aspectRatio ( contentMode: . fit)
125+ . frame ( width: 240 , height: 100 )
126+ . foregroundStyle ( . haPrimary)
127+ . padding ( . bottom, DesignSystem . Spaces. four)
128+ Text ( instance? . internalOrExternalURL. absoluteString ?? " -- " )
129+ . font ( DesignSystem . Font. body. weight ( . light) )
130+ . foregroundStyle ( . secondary)
131+ Button {
132+ autoConnectInstance = nil
133+ guard let viewController = hostingProvider. viewController, let instance else { return }
134+ viewModel. selectInstance ( instance, controller: viewController)
135+ } label: {
136+ Text ( L10n . Onboarding. Servers. AutoConnect. button)
137+ }
138+ . buttonStyle ( . primaryButton)
139+ }
140+ }
141+
83142 private func scheduleAutoConnect( ) {
84143 autoConnectWorkItem? . cancel ( )
85144 let workItem = DispatchWorkItem { [ weak viewModel] in
86145 if viewModel? . discoveredInstances. count == 1 {
87- // TODO: Display a bottom sheet asking to connect
146+ autoConnectInstance = viewModel ? . discoveredInstances . first
88147 }
89148 }
90149 autoConnectWorkItem = workItem
91- let amountOfTimeToWaitToAutoConnect : CGFloat = 2
92- DispatchQueue . main. asyncAfter ( deadline: . now( ) + amountOfTimeToWaitToAutoConnect, execute: workItem)
150+ DispatchQueue . main. asyncAfter ( deadline: . now( ) + Constants. delayUntilAutoconnect, execute: workItem)
93151 }
94152
95153 private func cancelAutoConnect( ) {
96154 autoConnectWorkItem? . cancel ( )
97155 autoConnectWorkItem = nil
98156 }
99157
100- private func scheduleCenterLoaderDimiss( ) {
101- let amountOfTimeToWaitToDismissCenterLoader : CGFloat = 2
158+ private func scheduleCenterLoaderDimiss( amountOfTimeToWaitToDismissCenterLoader: CGFloat ) {
102159 DispatchQueue . main. asyncAfter ( deadline: . now( ) + amountOfTimeToWaitToDismissCenterLoader) {
103160 viewModel. showCenterLoader = false
104161 }
@@ -257,21 +314,19 @@ struct OnboardingServersListView: View {
257314 }
258315
259316 private var headerView : some View {
260- Section {
261- Text ( L10n . Onboarding. Servers. title)
262- . font ( DesignSystem . Font. largeTitle. bold ( ) )
263- . multilineTextAlignment ( . center)
264- . frame ( maxWidth: . infinity, alignment: . center)
265- . padding ( . bottom)
266- }
317+ Text ( L10n . Onboarding. Servers. title)
318+ . font ( DesignSystem . Font. largeTitle. bold ( ) )
319+ . multilineTextAlignment ( . center)
320+ . frame ( maxWidth: . infinity, alignment: . center)
321+ . padding ( . vertical, DesignSystem . Spaces. four)
267322 }
268323
269324 private func serverRow( instance: DiscoveredHomeAssistant ) -> some View {
270325 Button ( action: {
271326 viewModel. selectInstance ( instance, controller: hostingProvider. viewController)
272327 } , label: {
273328 OnboardingScanningInstanceRow (
274- name: instance. locationName,
329+ name: instance. bonjourName ?? instance . locationName,
275330 internalURLString: instance. internalURL? . absoluteString,
276331 externalURLString: instance. externalURL? . absoluteString,
277332 internalOrExternalURLString: instance. internalOrExternalURL. absoluteString,
0 commit comments