@@ -11,6 +11,8 @@ final class WanderModel: ObservableObject {
1111 static let metadataAPIKey = " metadataAPIKey "
1212 static let selectedContinentId = " selectedContinentId "
1313 static let selectedCountryId = " selectedCountryId "
14+ static let metadataRequestLimit = " metadataRequestLimit "
15+ static let metadataRequestsUsed = " metadataRequestsUsed "
1416 }
1517
1618 @Published var browserAPIKey : String {
@@ -37,13 +39,26 @@ final class WanderModel: ObservableObject {
3739 }
3840 }
3941 }
42+ @Published var metadataRequestLimit = 0 {
43+ didSet {
44+ if metadataRequestLimit < 0 {
45+ metadataRequestLimit = 0
46+ }
47+ defaults. set ( metadataRequestLimit, forKey: DefaultsKey . metadataRequestLimit)
48+ }
49+ }
4050
4151 @Published private( set) var panorama : Panorama ?
4252 @Published private( set) var history : [ HistoryEntry ] = [ ]
4353 @Published private( set) var locationOptions = LocationOptions . empty
4454 @Published private( set) var isLoading = false
4555 @Published private( set) var statusText = " Add API keys in Settings, then pick a random place. "
4656 @Published private( set) var errorText : String ?
57+ @Published private( set) var metadataRequestsUsed = 0 {
58+ didSet {
59+ defaults. set ( metadataRequestsUsed, forKey: DefaultsKey . metadataRequestsUsed)
60+ }
61+ }
4762 @Published var activePanel : Panel = . none
4863 @Published var isSettingsPresented = false
4964
@@ -78,6 +93,8 @@ final class WanderModel: ObservableObject {
7893 self . metadataAPIKey = keychainStore. string ( for: DefaultsKey . metadataAPIKey) ?? legacyMetadataAPIKey ?? " "
7994 self . selectedContinentId = defaults. string ( forKey: DefaultsKey . selectedContinentId) ?? " "
8095 self . selectedCountryId = defaults. string ( forKey: DefaultsKey . selectedCountryId) ?? " "
96+ self . metadataRequestLimit = max ( 0 , defaults. integer ( forKey: DefaultsKey . metadataRequestLimit) )
97+ self . metadataRequestsUsed = max ( 0 , defaults. integer ( forKey: DefaultsKey . metadataRequestsUsed) )
8198
8299 persistSecret ( browserAPIKey, key: DefaultsKey . browserAPIKey)
83100 persistSecret ( metadataAPIKey, key: DefaultsKey . metadataAPIKey)
@@ -92,6 +109,13 @@ final class WanderModel: ObservableObject {
92109 !metadataAPIKey. trimmingCharacters ( in: . whitespacesAndNewlines) . isEmpty
93110 }
94111
112+ var metadataRequestsRemaining : Int ? {
113+ guard metadataRequestLimit > 0 else {
114+ return nil
115+ }
116+ return max ( metadataRequestLimit - metadataRequestsUsed, 0 )
117+ }
118+
95119 var selectedScopeLabel : String {
96120 if let country = locationOptions. countries. first ( where: { $0. id == selectedCountryId } ) {
97121 return country. label
@@ -162,7 +186,10 @@ final class WanderModel: ObservableObject {
162186 let next = try await panoramaFinder. findRandomPanorama (
163187 metadataAPIKey: metadataAPIKey,
164188 selection: selection,
165- recentContinents: recentContinents
189+ recentContinents: recentContinents,
190+ onMetadataRequest: { [ weak self] in
191+ await self ? . recordMetadataRequest ( )
192+ }
166193 )
167194 panorama = next
168195 history = try historyStore. append ( next)
@@ -177,6 +204,14 @@ final class WanderModel: ObservableObject {
177204 }
178205 }
179206
207+ func resetMetadataRequestUsage( ) {
208+ metadataRequestsUsed = 0
209+ }
210+
211+ private func recordMetadataRequest( ) {
212+ metadataRequestsUsed += 1
213+ }
214+
180215 private func persistSecret( _ value: String , key: String ) {
181216 let trimmed = value. trimmingCharacters ( in: . whitespacesAndNewlines)
182217 if trimmed. isEmpty {
0 commit comments