@@ -49,7 +49,10 @@ struct ContentView: View {
4949 VStack ( spacing: 0 ) {
5050 topBar
5151 Spacer ( )
52- bottomStatus
52+ HStack {
53+ bottomStatus
54+ Spacer ( minLength: 340 )
55+ }
5356 }
5457 . padding ( 16 )
5558
@@ -118,6 +121,8 @@ struct ContentView: View {
118121 . help ( " API key settings " )
119122 . accessibilityLabel ( " API key settings " )
120123
124+ metadataUsageBadge
125+
121126 if let label = updates. updateLabel {
122127 Button {
123128 updates. updateNow ( )
@@ -176,18 +181,26 @@ struct ContentView: View {
176181 . font ( . system( size: 13 , weight: . semibold) )
177182 . foregroundStyle ( model. errorText == nil ? Color . white. opacity ( 0.86 ) : Color ( red: 1 , green: 0.82 , blue: 0.76 ) )
178183 . layoutPriority ( 1 )
179-
180- Spacer ( minLength: 8 )
181-
182- Text ( metadataUsageStatus)
183- . lineLimit ( 1 )
184- . font ( . system( size: 12 , weight: . bold) )
185- . foregroundStyle ( . white. opacity ( 0.72 ) )
186184 }
187185 . padding ( . horizontal, 14 )
188186 . padding ( . vertical, 10 )
189187 . background ( . black. opacity ( 0.58 ) , in: RoundedRectangle ( cornerRadius: 8 ) )
190- . frame ( maxWidth: . infinity, alignment: . leading)
188+ . frame ( maxWidth: 620 , alignment: . leading)
189+ }
190+
191+ private var metadataUsageBadge : some View {
192+ HStack ( spacing: 6 ) {
193+ Image ( systemName: " gauge.with.dots.needle.33percent " )
194+ Text ( metadataUsageBadgeText)
195+ . lineLimit ( 1 )
196+ }
197+ . font ( . system( size: 12 , weight: . bold) )
198+ . foregroundStyle ( . white. opacity ( 0.78 ) )
199+ . padding ( . horizontal, 10 )
200+ . frame ( height: 34 )
201+ . background ( . white. opacity ( 0.05 ) , in: RoundedRectangle ( cornerRadius: 8 ) )
202+ . help ( metadataUsageStatus)
203+ . accessibilityLabel ( metadataUsageStatus)
191204 }
192205
193206 private var metadataUsageStatus : String {
@@ -197,6 +210,13 @@ struct ContentView: View {
197210 return " Metadata checks \( formatCount ( model. metadataRequestsUsed) ) · no limit "
198211 }
199212
213+ private var metadataUsageBadgeText : String {
214+ if model. metadataRequestLimit > 0 {
215+ return " Checks \( formatCount ( model. metadataRequestsUsed) ) / \( formatCount ( model. metadataRequestLimit) ) "
216+ }
217+ return " Checks \( formatCount ( model. metadataRequestsUsed) ) "
218+ }
219+
200220 private var sidePanel : some View {
201221 HStack {
202222 Spacer ( )
@@ -278,6 +298,9 @@ struct DetailsPanel: View {
278298 if let continent = panorama. continentLabel {
279299 detail ( " Continent " , continent)
280300 }
301+ if let sceneKind = panorama. sceneKind {
302+ detail ( " Search mix " , sceneKind. label)
303+ }
281304 detail ( " Latitude " , formatCoord ( panorama. location. lat) )
282305 detail ( " Longitude " , formatCoord ( panorama. location. lng) )
283306 detail ( " Metadata checks " , " \( panorama. attempts) " )
@@ -361,6 +384,8 @@ struct HistoryPanel: View {
361384struct SettingsView : View {
362385 @EnvironmentObject private var model : WanderModel
363386 @Environment ( \. dismiss) private var dismiss
387+ @State private var draftBrowserAPIKey = " "
388+ @State private var draftMetadataAPIKey = " "
364389
365390 var body : some View {
366391 VStack ( alignment: . leading, spacing: 16 ) {
@@ -385,15 +410,15 @@ struct SettingsView: View {
385410 Text ( " VITE_GOOGLE_MAPS_API_KEY " )
386411 . font ( . system( size: 11 , weight: . medium) )
387412 . foregroundStyle ( . secondary)
388- SecureField ( " Maps JavaScript API key " , text: $model . browserAPIKey )
413+ SecureField ( " Maps JavaScript API key " , text: $draftBrowserAPIKey )
389414 . textFieldStyle ( . roundedBorder)
390415 }
391416
392417 VStack ( alignment: . leading, spacing: 6 ) {
393418 Text ( " GOOGLE_STREET_VIEW_METADATA_API_KEY " )
394419 . font ( . system( size: 11 , weight: . medium) )
395420 . foregroundStyle ( . secondary)
396- SecureField ( " Street View metadata API key " , text: $model . metadataAPIKey )
421+ SecureField ( " Street View metadata API key " , text: $draftMetadataAPIKey )
397422 . textFieldStyle ( . roundedBorder)
398423 }
399424
@@ -425,17 +450,27 @@ struct SettingsView: View {
425450
426451 HStack {
427452 Button ( " Import .env " ) {
428- model. importEnvFile ( )
453+ if model. importEnvFile ( ) {
454+ resetDraftKeys ( )
455+ }
429456 }
430457 Spacer ( )
431458 Button ( " Done " ) {
459+ model. saveAPIKeys ( browser: draftBrowserAPIKey, metadata: draftMetadataAPIKey)
432460 dismiss ( )
433461 }
434462 . keyboardShortcut ( . defaultAction)
435463 }
436464 }
437465 . padding ( 20 )
438466 . frame ( width: 520 )
467+ . onAppear ( perform: resetDraftKeys)
468+ }
469+
470+ private func resetDraftKeys( ) {
471+ model. loadAPIKeysForEditing ( )
472+ draftBrowserAPIKey = model. browserAPIKey
473+ draftMetadataAPIKey = model. metadataAPIKey
439474 }
440475
441476 private func requestMetric( _ label: String , _ value: String ) -> some View {
0 commit comments