Skip to content

Commit 52ad026

Browse files
authored
Merge pull request #106 from TaskarCenterAtUW/feature-bug-fix-13
Bug Fixes in Build 13
2 parents 8bc97e5 + bca86d1 commit 52ad026

File tree

28 files changed

+232
-65
lines changed

28 files changed

+232
-65
lines changed

GoInfoGame/GoInfoGame/AppQuestManager.swift

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class AppQuestManager {
1818
// let opManager = OverpassRequestManager()
1919

2020
let dbInstance = DatabaseConnector.shared
21-
let osmConnection = OSMConnection()
21+
let osmConnection = OSMConnection(config: OSMConfig.testPOSM, currentChangesetId: nil)
2222

2323
static let shared = AppQuestManager()
2424
private init() {}
@@ -62,6 +62,60 @@ class AppQuestManager {
6262
}
6363

6464

65+
func getUpdatedQuest(elementId: String) -> DisplayUnitWithCoordinate? {
66+
let nodesFromStorage = dbInstance.getNodes().filter { n in
67+
n.tags.count != 0
68+
}
69+
let waysFromStorage = dbInstance.getWays().filter{w in w.tags.count != 0 }
70+
let theWay = waysFromStorage.first(where: {$0.id == Int(elementId)})
71+
let theNode = nodesFromStorage.first(where: {$0.id == Int(elementId)})
72+
let allQuests = QuestsRepository.shared.applicableQuests
73+
// theElement if not equal to nil
74+
if (theNode != nil) {
75+
let nodeElement = theNode?.asNode()
76+
for quest in allQuests {
77+
if quest.filter.isEmpty {continue} // Ignore quest
78+
if quest.isApplicable(element: nodeElement!){
79+
// Create a duplicate of the quest
80+
// Create a display Unit
81+
let duplicateQuest = quest.copyWithElement(element: nodeElement!)
82+
let unit = DisplayUnitWithCoordinate(displayUnit: duplicateQuest.displayUnit, coordinateInfo: CLLocationCoordinate2D(latitude: nodeElement!.position.latitude, longitude: nodeElement!.position.longitude), id: nodeElement!.id)
83+
return unit
84+
}
85+
}
86+
87+
}
88+
else if (theWay != nil){
89+
let wayElement = theWay?.asWay()
90+
for quest in allQuests {
91+
if quest.filter.isEmpty {continue} // Ignore quest
92+
if quest.isApplicable(element: wayElement!){
93+
// Create a duplicate of the quest
94+
// Need to add another here.
95+
let duplicateQuest = quest.copyWithElement(element: wayElement!)
96+
let position = dbInstance.getCenterForWay(id: String(wayElement!.id)) ?? CLLocationCoordinate2D()
97+
let unit = DisplayUnitWithCoordinate(displayUnit: duplicateQuest.displayUnit, coordinateInfo: position, id: wayElement!.id)
98+
return unit
99+
}
100+
}
101+
102+
}
103+
return nil
104+
}
105+
106+
// internal func getPossibleQuest(element: osmparser.Element) -> DisplayUnitWithCoordinate? {
107+
// let allQuests = QuestsRepository.shared.applicableQuests
108+
// for quest in allQuests {
109+
// if quest.filter.isEmpty {continue}
110+
// if quest.isApplicable(element: element){
111+
// let duplicateQuest = quest.copyWithElement(element: element)
112+
// let unit = DisplayUnitWithCoordinate(displayUnit: duplicateQuest.displayUnit, coordinateInfo: CLLocationCoordinate2D(latitude: node.position.latitude, longitude: node.position.longitude), id: node.id)
113+
// }
114+
//
115+
// }
116+
//
117+
// }
118+
65119

66120

67121
// Fetches all the available quests from Database

GoInfoGame/GoInfoGame/LocationManagerDelegate.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ class LocationManagerDelegate: NSObject, ObservableObject, CLLocationManagerDele
1313
var locationManager = CLLocationManager()
1414
@Published var location: CLLocation?
1515
var locationUpdateHandler: ((CLLocationCoordinate2D) -> Void)?
16-
17-
var hasUpdatedLocation = false
18-
16+
1917
override init() {
2018
super.init()
2119
locationManager.delegate = self
@@ -36,13 +34,15 @@ class LocationManagerDelegate: NSObject, ObservableObject, CLLocationManagerDele
3634

3735
DispatchQueue.main.async {
3836
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
37+
self.locationManager.distanceFilter = 150
3938
self.locationManager.startUpdatingLocation()
4039
}
4140
}
4241
}
4342

4443

4544
func stopUpdatingLocation() {
45+
print("App is pushed to background. So stopping location updates")
4646
locationManager.stopUpdatingLocation()
4747
}
4848

@@ -61,10 +61,11 @@ class LocationManagerDelegate: NSObject, ObservableObject, CLLocationManagerDele
6161

6262
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
6363
guard let mostRecentLocation = locations.last else { return }
64-
guard !hasUpdatedLocation else { return }
6564
location = mostRecentLocation
6665
locationUpdateHandler?(mostRecentLocation.coordinate)
67-
hasUpdatedLocation = true
68-
stopUpdatingLocation()
66+
}
67+
68+
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
69+
print("Error with location manager is ----\(error.localizedDescription)")
6970
}
7071
}

GoInfoGame/GoInfoGame/SceneDelegate.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import UIKit
1010
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
1111

1212
var window: UIWindow?
13+
14+
var locationManagerDelegate = LocationManagerDelegate()
1315

1416

1517
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
@@ -39,12 +41,14 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
3941
func sceneWillEnterForeground(_ scene: UIScene) {
4042
// Called as the scene transitions from the background to the foreground.
4143
// Use this method to undo the changes made on entering the background.
44+
locationManagerDelegate.startUpdatingLocation()
4245
}
4346

4447
func sceneDidEnterBackground(_ scene: UIScene) {
4548
// Called as the scene transitions from the foreground to the background.
4649
// Use this method to save data, release shared resources, and store enough scene-specific state information
4750
// to restore the scene back to its current state.
51+
locationManagerDelegate.stopUpdatingLocation()
4852
}
4953

5054
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
@@ -56,6 +60,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
5660

5761

5862
}
63+
64+
5965

6066
}
6167

GoInfoGame/GoInfoGame/UI/Map/CustomMap.swift

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct CustomMap: UIViewRepresentable {
2222
@Binding var isPresented: Bool
2323
@StateObject var locationManagerDelegate = LocationManagerDelegate()
2424

25+
2526
@State var lineCoordinates: [CLLocationCoordinate2D] = []
2627

2728
var contextualInfo: ((String) -> Void)?
@@ -41,7 +42,7 @@ struct CustomMap: UIViewRepresentable {
4142

4243
// Updates the UIView with new data
4344
func updateUIView(_ mapView: MKMapView, context: Context) {
44-
mapView.setCenter(userLocation, animated: true)
45+
// mapView.setCenter(userLocation, animated: true)
4546
context.coordinator.updateUserRegion(mapView)
4647
manageAnnotations(mapView, context: context)
4748

@@ -148,7 +149,6 @@ struct CustomMap: UIViewRepresentable {
148149
// Handles selection of annotations
149150
func mapView(_ mapView: MKMapView, didSelect annotation: MKAnnotation) {
150151
print("did select ")
151-
print(annotation)
152152
if let annotation = annotation as? MKClusterAnnotation {
153153
let displayAnnotation = annotation.memberAnnotations.first as! DisplayUnitAnnotation
154154
selectedAnAnnotation(selectedQuest: displayAnnotation)
@@ -177,7 +177,6 @@ struct CustomMap: UIViewRepresentable {
177177
}
178178
}
179179
self.parent.lineCoordinates = polylineCoords
180-
print("POLYLINE COORDS ARE ----\(polylineCoords)")
181180

182181
parent.inferStreetName(location: annotationLocation) { streetName in
183182
if let streetName = streetName {
@@ -222,34 +221,29 @@ struct CustomMap: UIViewRepresentable {
222221

223222
// Helper method to manage annotations
224223
private func manageAnnotations(_ mapView: MKMapView, context: Context) {
225-
/// Extracting coordinates of existing annotations
224+
226225
let existingCoordinates = mapView.annotations.compactMap { ($0 as? DisplayUnitAnnotation)?.coordinate }
227-
let newAnnotations = items.map { $0.annotation }
228-
let newCoordinates = newAnnotations.map { $0.coordinate }
229-
/// Checking if the coordinates of existing annotations are different from the coordinates of new annotations
230-
if existingCoordinates.count != newCoordinates.count {
231-
/// to reset isRegionSet value whenever region changes.
232-
context.coordinator.isRegionSet = false
233-
/// Removing annotations that are not present in the new set
234-
let annotationsToRemove = mapView.annotations.filter {
235-
guard let displayUnitAnnotation = $0 as? DisplayUnitAnnotation else { return false }
236-
return !newCoordinates.contains(displayUnitAnnotation.coordinate)
237-
}
238-
mapView.removeAnnotations(annotationsToRemove)
239-
/// Adding annotations that are present in the new set but not in the existing set
240-
let annotationsToAdd = newAnnotations.filter { !existingCoordinates.contains($0.coordinate) }
241-
mapView.addAnnotations(annotationsToAdd)
242-
243-
/// Updating the region if it hasn't been set yet
244-
if !context.coordinator.isRegionSet {
245-
/// resetting region only when app is launched/re-launched
246-
if existingCoordinates.count == 0 {
247-
mapView.setCenter(userLocation, animated: true)
248-
// mapView.setRegion(region, animated: true)
249-
}
250-
context.coordinator.isRegionSet = true
251-
}
226+
227+
/// resetting region only when app is launched/re-launched
228+
if existingCoordinates.count == 0 {
229+
mapView.setCenter(userLocation, animated: true)
252230
}
231+
context.coordinator.isRegionSet = true
232+
233+
234+
if (existingCoordinates.isEmpty) {
235+
print("Adding annotations completely")
236+
mapView.addAnnotations(items.compactMap({$0.annotation}))
237+
}
238+
239+
let currentAnnotations = Set(mapView.annotations.compactMap { $0 as? DisplayUnitAnnotation })
240+
let newAnnotations = Set(items.map({$0.annotation}))
241+
242+
let annotationsToRemove = currentAnnotations.subtracting(newAnnotations)
243+
let annotationsToAdd = newAnnotations.subtracting(currentAnnotations)
244+
245+
mapView.removeAnnotations(Array(annotationsToRemove))
246+
mapView.addAnnotations(Array(annotationsToAdd))
253247
}
254248

255249
// calculate distance between user current location and selected annotation

GoInfoGame/GoInfoGame/UI/Map/MapView.swift

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ import Combine
1111

1212
struct MapView: View {
1313
let selectedWorkspace: Workspace?
14-
@State var trackingMode: MapUserTrackingMode = MapUserTrackingMode.none
14+
@State var trackingMode: MapUserTrackingMode = MapUserTrackingMode.follow
1515
@Environment(\.presentationMode) private var presentationMode
1616
@AppStorage("isMapFromOnboarding") var isMapFromOnboarding: Bool = false
1717
@StateObject private var viewModel = MapViewModel()
1818
@State private var isPresented = false
1919

2020
@State private var shouldShowPolyline = true
2121
@State private var isSyncing = false
22+
@State private var showAlert = false
2223
@StateObject var contextualInfo = ContextualInfo.shared
2324

2425
@AppStorage("baseUrl") var baseUrl = ""
@@ -31,6 +32,7 @@ struct MapView: View {
3132
items: viewModel.items,
3233
selectedQuest: $viewModel.selectedQuest,
3334
shouldShowPolyline: $shouldShowPolyline,
35+
3436
isPresented: $isPresented, contextualInfo: { contextualInfo in
3537
print(contextualInfo)
3638
self.setContextualInfo(contextualinfo: contextualInfo)
@@ -42,6 +44,30 @@ struct MapView: View {
4244
.edgesIgnoringSafeArea(.all)
4345
ActivityView(activityText: "Looking for quests...")
4446
}
47+
if showAlert {
48+
VStack {
49+
Image(systemName: "checkmark.circle.fill")
50+
.resizable()
51+
.aspectRatio(contentMode: .fit)
52+
.frame(width: 50, height: 50)
53+
.foregroundColor(.green)
54+
.padding(.bottom, 50)
55+
Text("Quest Submitted")
56+
.foregroundColor(.white)
57+
.padding()
58+
.background(Color.orange)
59+
.cornerRadius(10)
60+
}
61+
.padding([.all], 50)
62+
.background(Color.white)
63+
.accessibilityElement(children: .combine)
64+
.accessibilityLabel("Quest Submitted")
65+
.onAppear {
66+
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
67+
showAlert = false // Dismiss notification box after 1 second
68+
}
69+
}
70+
}
4571
}
4672
.environmentObject(contextualInfo)
4773
.navigationBarHidden(false)
@@ -91,15 +117,16 @@ struct MapView: View {
91117
switch scenario {
92118
case .dismissed:
93119
shouldShowPolyline = false
94-
case .submitted:
95-
viewModel.refreshMapAfterSubmission()
120+
case .submitted(let elementId):
96121
shouldShowPolyline = false
122+
viewModel.refreshMapAfterSubmission(elementId: elementId)
97123
case .syncing:
98124
isSyncing = true
99125
print("syncing")
100126
case .synced:
101127
isSyncing = false
102128
print("synced")
129+
showAlert = true
103130
}
104131
}
105132
.onAppear(){
@@ -123,7 +150,7 @@ public class MapViewPublisher: ObservableObject {
123150

124151
public enum SheetDismissalScenario {
125152
case dismissed
126-
case submitted
153+
case submitted(String)
127154
case syncing
128155
case synced
129156
}

GoInfoGame/GoInfoGame/UI/Map/MapViewModel.swift

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import SwiftUI
1010
import MapKit
1111
import CoreLocation
1212

13+
1314
class MapViewModel: ObservableObject {
1415

1516
let locationManagerDelegate = LocationManagerDelegate()
@@ -56,8 +57,21 @@ class MapViewModel: ObservableObject {
5657
}
5758
}
5859

59-
func refreshMapAfterSubmission() {
60-
self.items = AppQuestManager.shared.fetchQuestsFromDB()
60+
func refreshMapAfterSubmission(elementId: String) {
61+
62+
if let newItem = AppQuestManager.shared.getUpdatedQuest(elementId: elementId) {
63+
let toReplace = self.items.first(where: {$0.id == Int(elementId)!})
64+
let index = self.items.firstIndex(where: {$0.id == Int(elementId)!})
65+
66+
self.items.remove(at: index!)
67+
self.items.insert(newItem, at: index!)
68+
}
69+
else{
70+
if let toReplace = self.items.first(where: {$0.id == Int(elementId)!}) {
71+
let index = self.items.firstIndex(where: {$0.id == Int(elementId)!})
72+
self.items.remove(at: index!)
73+
}
74+
}
6175
}
6276

6377
private func boundingBoxAroundLocation(location: CLLocationCoordinate2D, distance: CLLocationDistance) -> BBox {

GoInfoGame/GoInfoGame/quests/BusStopLit/BusStopLit.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import SwiftUI
1111
import osmparser
1212

1313
class BusStopLit: QuestBase, Quest {
14+
var questId: String = "6"
15+
1416
typealias AnswerClass = YesNoAnswer
1517
var relationData: Element? = nil
1618
var _internalExpression: ElementFilterExpression?
@@ -35,7 +37,8 @@ class BusStopLit: QuestBase, Quest {
3537
)
3638
"""
3739
var displayUnit: DisplayUnit {
38-
DisplayUnit(title: self.title, description: "",parent: self,sheetSize:.SMALL )
40+
let uid = String(self.relationData?.id ?? 0)
41+
return DisplayUnit(title: self.title, description: "", id: "\(uid) - \(questId)",parent: self,sheetSize:.SMALL )
3942
}
4043
var filterExpression: ElementFilterExpression? {
4144
if(_internalExpression != nil){

GoInfoGame/GoInfoGame/quests/CrossingIsland/CrossingIsland.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import SwiftUI
1111
import osmparser
1212

1313
class CrossingIsland: QuestBase, Quest {
14+
var questId: String = "8"
15+
1416
typealias AnswerClass = YesNoAnswer
1517
var relationData: Element? = nil
1618
var _internalExpression: ElementFilterExpression?
@@ -25,7 +27,8 @@ class CrossingIsland: QuestBase, Quest {
2527
var title: String = "Crossing Island"
2628
var filter: String = ""
2729
var displayUnit: DisplayUnit {
28-
DisplayUnit(title: self.title, description: "",parent: self,sheetSize:.MEDIUM )
30+
let uid = String(self.relationData?.id ?? 0)
31+
return DisplayUnit(title: self.title, description: "", id: "\(uid) - \(questId)",parent: self,sheetSize:.MEDIUM )
2932
}
3033
var filterExpression: ElementFilterExpression? {
3134
if(_internalExpression != nil){

0 commit comments

Comments
 (0)