Skip to content

Commit 88be93e

Browse files
authored
Merge pull request #247 from TaskarCenterAtUW/fix-undo-complete
Undo - Pending
2 parents 5dc75a3 + 157e227 commit 88be93e

File tree

19 files changed

+263
-211
lines changed

19 files changed

+263
-211
lines changed

GoInfoGame/GoInfoGame/AppQuestManager.swift

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -70,32 +70,17 @@ class AppQuestManager {
7070

7171
let allOriginalNodes = dbInstance.getNodes().filter { $0.isOriginal && $0.tags.count != 0 }
7272

73-
let nodesFromStorage = allOriginalNodes.compactMap { original in
74-
if let edited = self.dbInstance.getNode(id: original.id, version: .edited),
75-
edited.tags.count != 0,
76-
edited.tags["ext:gig_complete"] != "yes" {
77-
return edited
78-
} else if original.tags["ext:gig_complete"] != "yes" {
79-
return original
80-
} else {
81-
return nil
82-
}
73+
74+
let nodesFromStorage: [StoredNode] = allOriginalNodes.compactMap { original in
75+
original.tags["ext:gig_complete"] == "yes" ? nil : original
8376
}
8477

8578
let allOriginalWays = dbInstance.getWays().filter {
8679
$0.isOriginal && $0.tags.count != 0
8780
}
8881

89-
let waysFromStorage = allOriginalWays.compactMap { original in
90-
if let edited = self.dbInstance.getWay(id: original.id, version: .edited),
91-
edited.tags.count != 0,
92-
edited.tags["ext:gig_complete"] != "yes" {
93-
return edited
94-
} else if original.tags["ext:gig_complete"] != "yes" {
95-
return original
96-
} else {
97-
return nil
98-
}
82+
let waysFromStorage: [StoredWay] = allOriginalWays.compactMap { original in
83+
original.tags["ext:gig_complete"] == "yes" ? nil : original
9984
}
10085

10186

GoInfoGame/GoInfoGame/DataBase/DatabaseConnector.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -369,9 +369,7 @@ class DatabaseConnector {
369369
- parameter tags [String:String] tags changed with this
370370
- Returns: An instance of `StoredChangeset`
371371
*/
372-
func createChangeset(id:String, type: StoredElementEnum, tags:[String:String], isUndo: Bool) -> StoredChangeset? {
373-
if isUndo { return nil }
374-
372+
func createChangeset(id:String, type: StoredElementEnum, tags:[String:String]) -> StoredChangeset? {
375373
let storedChangeset = StoredChangeset()
376374
storedChangeset.elementId = id
377375
storedChangeset.elementType = type

GoInfoGame/GoInfoGame/data/DatasyncManager.swift

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ class DatasyncManager {
2020
private let dbInstance = DatabaseConnector.shared
2121
private let barrierQueue: DispatchQueue = DispatchQueue(label: "com.goinfogame.DatasyncManager.barrierQueue", attributes: .concurrent)
2222

23-
func syncDataToOSM(completionHandler: @escaping (Result<Bool, APIError>) -> Void) {
23+
func syncDataToOSM(exclude_gig_tags: Bool, completionHandler: @escaping (Result<Bool, APIError>) -> Void) {
2424
barrierQueue.async(flags: .barrier) { [weak self] in
2525
guard let self = self else { return }
2626
let semaphore = DispatchSemaphore(value: 0)
2727

2828
Task.detached(priority: .userInitiated) {
2929
do {
30-
let isSynced = try await self.syncData()
30+
let isSynced = try await self.syncData(exclude_gig_tags: exclude_gig_tags)
3131

3232
print("Sync finished")
3333
if isSynced {
@@ -57,7 +57,7 @@ class DatasyncManager {
5757
/// *** Terminating app due to uncaught exception 'RLMException', reason: 'Realm accessed from incorrect thread.'
5858
/// To fix the above error added @mainActor
5959
@MainActor
60-
func syncData() async throws -> Bool {
60+
func syncData(exclude_gig_tags: Bool = false) async throws -> Bool {
6161
print("🔄 Starting sync...")
6262

6363
let changesets = dbInstance.getChangesets()
@@ -132,7 +132,7 @@ class DatasyncManager {
132132
print("📤 Syncing way ID: \(way.id)")
133133
let payload = way.asOSMWay()
134134
do {
135-
let isFinished = try await syncWay(way: payload)
135+
let isFinished = try await syncWay(way: payload, exclude_gig_tags: exclude_gig_tags)
136136
if isFinished {
137137
DispatchQueue.main.async {
138138
self.dbInstance.assignChangesetId(obj: key, changesetId: 0)
@@ -195,7 +195,7 @@ class DatasyncManager {
195195
}
196196
}
197197

198-
func openChangeset() async throws -> Int {
198+
func openChangeset(exclude_gig_tags: Bool = false) async throws -> Int {
199199
var versionNumber = ""
200200
var buildNumber = ""
201201

@@ -206,7 +206,7 @@ class DatasyncManager {
206206
}
207207

208208
let createdBy = "\(versionNumber)(\(buildNumber))"
209-
let osmPayloadString = OSMChangesetPayload(createdByTag: createdBy).toPayload()
209+
let osmPayloadString = OSMChangesetPayload(createdByTag: createdBy).toPayload(exclude_gig_tags: exclude_gig_tags)
210210
let osmPayload = osmPayloadString.data(using: .utf8)
211211
let workspaceId = KeychainManager.load(key: "workspaceID")
212212

@@ -252,9 +252,9 @@ class DatasyncManager {
252252
}
253253

254254
// utility function to act as substitute for osmConnection functions
255-
func updateWay(way: OSMWay) async throws -> Int {
255+
func updateWay(way: OSMWay, exclude_gig_tags: Bool = false) async throws -> Int {
256256
var localWay = way
257-
let wayBodyString = localWay.toPayload()
257+
let wayBodyString = localWay.toPayload(exclude_gig_tags: exclude_gig_tags)
258258
let changesetUploadBody = "<osmChange version=\"0.6\" generator=\"GIG Change generator\">" + wayBodyString + "</osmChange>"
259259
let workspaceId = KeychainManager.load(key: "workspaceID")
260260
let wayBody = changesetUploadBody.data(using: .utf8)
@@ -288,9 +288,9 @@ class DatasyncManager {
288288
}
289289

290290
// utility function to act as substitute for osmConnection functions
291-
func updateNode(node: OSMNode) async throws -> Int {
291+
func updateNode(node: OSMNode, exclude_gig_tags: Bool = false) async throws -> Int {
292292
var localNode = node
293-
let nodeBodyString = localNode.toPayload()
293+
let nodeBodyString = localNode.toPayload(exclude_gig_tags: exclude_gig_tags)
294294
let changesetUploadBody = "<osmChange version=\"0.6\" generator=\"GIG Change generator\">" + nodeBodyString + "</osmChange>"
295295
let workspaceId = KeychainManager.load(key: "workspaceID")
296296

@@ -330,9 +330,9 @@ class DatasyncManager {
330330
}
331331
}
332332

333-
func uploadNode(node: OSMNode) async throws -> Bool {
333+
func uploadNode(node: OSMNode, exclude_gig_tags: Bool = false) async throws -> Bool {
334334
var localNode = node
335-
let nodeBodyString = localNode.toCreatePayload()
335+
let nodeBodyString = localNode.toCreatePayload(exclude_gig_tags: exclude_gig_tags)
336336
let changesetUploadBody = "<osmChange version=\"0.6\" generator=\"GIG Change generator\">" + nodeBodyString + "</osmChange>"
337337
let workspaceId = KeychainManager.load(key: "workspaceID")
338338

@@ -356,12 +356,12 @@ class DatasyncManager {
356356
}
357357
}
358358

359-
func updateWay2(way: OSMWay) async throws -> Int {
359+
func updateWay2(way: OSMWay, exclude_gig_tags: Bool = false) async throws -> Int {
360360
var localWay = way
361361
let wayId = "\(localWay.id)"
362362
var updatedResult: Int = -1
363363
do {
364-
updatedResult = try await updateWay(way: localWay)
364+
updatedResult = try await updateWay(way: localWay, exclude_gig_tags: exclude_gig_tags)
365365
return updatedResult
366366
} catch let error as APIError {
367367
switch error {
@@ -551,7 +551,7 @@ class DatasyncManager {
551551
}
552552

553553
@MainActor
554-
func syncWay(way: OSMWay) async throws -> Bool {
554+
func syncWay(way: OSMWay, exclude_gig_tags: Bool = false) async throws -> Bool {
555555
var localWay = way
556556

557557
do {
@@ -560,7 +560,7 @@ class DatasyncManager {
560560

561561
localWay.changeset = changesetID
562562

563-
let newVersion = try await updateWay2(way: localWay)
563+
let newVersion = try await updateWay2(way: localWay, exclude_gig_tags: exclude_gig_tags)
564564

565565
localWay.version = newVersion
566566

GoInfoGame/GoInfoGame/quests/BusStopLit/BusStopLit.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class BusStopLit: QuestBase, Quest {
6464

6565
func onAnswer(answer: YesNoAnswer) {
6666
if let rData = self.relationData {
67-
self.updateTags(id: rData.id, tags: ["lit":answer.rawValue], type: rData.type)
67+
self.updateTags(id: rData.id, tags: ["lit":answer.rawValue], type: rData.type, exclude_gig_tags: false)
6868
}
6969
}
7070

GoInfoGame/GoInfoGame/quests/QuestProtocols.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,18 @@ class QuestBase {
3939

4040
// Add a custom implementation
4141

42-
public func updateTags(id: Int64, tags:[String:String], type: ElementType, isUndo: Bool = false) {
42+
public func updateTags(id: Int64, tags:[String:String], type: ElementType, exclude_gig_tags: Bool = false) {
4343

4444
MapUndoManager.shared.updateTagsHandler = { [weak self] id, tags, type in
45-
self?.updateTags(id: id, tags: tags, type: type)
45+
self?.updateTags(id: id, tags: tags, type: type, exclude_gig_tags: true)
4646
}
4747

4848

4949
// Convert from ElementType enum to StoredElementEnum
5050
let storedElementType: StoredElementEnum = type == .way ? .way : .node
5151
let storedId = String(id)
5252
// Create a changeset
53-
_ = DatabaseConnector.shared.createChangeset(id: storedId, type: storedElementType, tags: tags, isUndo: isUndo)
53+
_ = DatabaseConnector.shared.createChangeset(id: storedId, type: storedElementType, tags: tags)
5454
switch (storedElementType){
5555
case .way:
5656
elementSubmittingToPOSM = .way
@@ -66,7 +66,7 @@ class QuestBase {
6666
// Dismiss sheet after syncing to db
6767
MapViewPublisher.shared.dismissSheet.send(.syncing)
6868

69-
DatasyncManager.shared.syncDataToOSM { success in
69+
DatasyncManager.shared.syncDataToOSM(exclude_gig_tags: exclude_gig_tags) { success in
7070
DispatchQueue.main.async {
7171
MapViewPublisher.shared.dismissSheet.send(.synced)
7272

GoInfoGame/GoInfoGame/quests/QuestUndoManager.swift

Lines changed: 58 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class MapUndoManager {
2424

2525
func undo(for id: Int64, type: ElementType) {
2626
MapUndoManager.shared.isUndoInProgress = true
27+
2728
switch type {
2829
case .way:
2930
guard let original = DatabaseConnector.shared.getWay(id: Int(id), version: .original),
@@ -32,15 +33,26 @@ class MapUndoManager {
3233
return
3334
}
3435

35-
try? realm.write {
36-
edited.tags.removeAll()
37-
original.tags.forEach { edited.tags[$0.key] = $0.value }
36+
do {
37+
try realm.write {
38+
edited.tags.removeAll()
39+
40+
for entry in original.tags {
41+
let key = entry.key
42+
let value = entry.value
43+
if key != "ext:gig_complete", key != "ext:gig_last_updated" {
44+
edited.tags[key] = value
45+
}
46+
}
3847

39-
edited.polyline.removeAll()
40-
edited.polyline.append(objectsIn: original.polyline)
48+
edited.polyline.removeAll()
49+
edited.polyline.append(objectsIn: original.polyline)
4150

42-
edited.nodes.removeAll()
43-
edited.nodes.append(objectsIn: original.nodes)
51+
edited.nodes.removeAll()
52+
edited.nodes.append(objectsIn: original.nodes)
53+
}
54+
} catch {
55+
print("❌ Realm write failed during undo (way): \(error)")
4456
}
4557

4658
updateTagsHandler?(id, edited.tags.toDictionary(), .way)
@@ -52,10 +64,25 @@ class MapUndoManager {
5264
return
5365
}
5466

55-
try? realm.write {
56-
edited.tags.removeAll()
57-
original.tags.forEach { edited.tags[$0.key] = $0.value }
58-
edited.point = original.point
67+
do {
68+
try realm.write {
69+
// Step 1: Clear all tags in edited
70+
edited.tags.removeAll()
71+
72+
// Step 2: Copy original tags except gig tags
73+
for entry in original.tags {
74+
let key = entry.key
75+
let value = entry.value
76+
if key != "ext:gig_complete", key != "ext:gig_last_updated" {
77+
edited.tags[key] = value
78+
}
79+
}
80+
81+
// Step 3: Restore location
82+
edited.point = original.point
83+
}
84+
} catch {
85+
print("❌ Realm write failed during undo (node): \(error)")
5986
}
6087

6188
updateTagsHandler?(id, edited.tags.toDictionary(), .node)
@@ -66,53 +93,40 @@ class MapUndoManager {
6693
}
6794

6895

96+
97+
98+
func fetchUndoItems() -> [UndoItem] {
99+
var items: [UndoItem] = []
100+
101+
102+
103+
104+
return items
105+
106+
}
107+
69108

70109
func getUndoItems() -> [UndoItem] {
71-
let excludedKeys: Set<String> = ["ext:gig_complete", "ext:gig_last_updated"]
72110
var items: [UndoItem] = []
73111

74-
let editedNodes = realm.objects(StoredNode.self)
112+
let editedNodes = realm.objects(StoredNode.self).filter("isOriginal == false")
75113
for edited in editedNodes {
76-
guard let original = DatabaseConnector.shared.getNode(id: edited.id, version: .original) else {
77-
print("⚠️ Original node not found for id: \(edited.id)")
78-
continue
79-
}
80-
81-
let changedKeys = Set(edited.tags.keys)
82-
.union(original.tags.keys)
83-
.filter { key in
84-
edited.tags[key] != original.tags[key] && !excludedKeys.contains(key)
85-
}
86-
87-
if !changedKeys.isEmpty {
88-
items.append(UndoItem(elementId: edited.id, type: .node, changedKeys: Array(changedKeys)))
114+
let keys = Array(edited.tags.keys)
115+
if !keys.isEmpty {
116+
items.append(UndoItem(elementId: edited.id, type: .node, changedKeys: keys))
89117
}
90118
}
91119

92-
let editedWays = realm.objects(StoredWay.self)
120+
let editedWays = realm.objects(StoredWay.self).filter("isOriginal == false")
93121
for edited in editedWays {
94-
guard let original = DatabaseConnector.shared.getWay(id: edited.id, version: .original) else {
95-
print("⚠️ Original way not found for id: \(edited.id)")
96-
continue
97-
}
98-
99-
let changedKeys = Set(edited.tags.keys)
100-
.union(original.tags.keys)
101-
.filter { key in
102-
edited.tags[key] != original.tags[key] && !excludedKeys.contains(key)
103-
}
104-
105-
if !changedKeys.isEmpty {
106-
items.append(UndoItem(elementId: edited.id, type: .way, changedKeys: Array(changedKeys)))
122+
let keys = Array(edited.tags.keys)
123+
if !keys.isEmpty {
124+
items.append(UndoItem(elementId: edited.id, type: .way, changedKeys: keys))
107125
}
108126
}
109127

110128
return items
111129
}
112-
113-
114-
115-
116130
}
117131

118132
extension MapUndoManager {

GoInfoGame/GoInfoGame/quests/SidewalkSurface/SidewalkSurface.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class SidewalkSurface: QuestBase, Quest {
3939

4040
func onAnswer(answer: SidewalkSurfaceAnswer) {
4141
if let rData = self.relationData , let surface = answer.value.surface?.rawValue {
42-
self.updateTags(id: rData.id, tags: ["surface":surface], type: rData.type)
42+
self.updateTags(id: rData.id, tags: ["surface":surface], type: rData.type, exclude_gig_tags: false)
4343
}
4444
}
4545

GoInfoGame/GoInfoGame/quests/SidewalkWidth/SideWalkWidth.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class SideWalkWidth : QuestBase, Quest {
5353

5454
func onAnswer(answer: WidthAnswer) {
5555
if let rData = self.relationData {
56-
self.updateTags(id: rData.id, tags: ["width":answer.width], type: rData.type)
56+
self.updateTags(id: rData.id, tags: ["width":answer.width], type: rData.type, exclude_gig_tags: false)
5757
}
5858
}
5959

GoInfoGame/GoInfoGame/quests/StairNumber/StairNumber.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class StairNumber: QuestBase, Quest {
4949

5050
func onAnswer(answer: Int) {
5151
if let rData = self.relationData {
52-
self.updateTags(id: rData.id, tags: ["step_count":"\(answer)"], type: rData.type)
52+
self.updateTags(id: rData.id, tags: ["step_count":"\(answer)"], type: rData.type, exclude_gig_tags: false)
5353
}
5454
}
5555

GoInfoGame/GoInfoGame/quests/StepsIncline/StepsIncline.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class StepsIncline: QuestBase, Quest {
5050

5151
func onAnswer(answer: StepsInclineDirection) {
5252
if let rData = self.relationData {
53-
self.updateTags(id: rData.id, tags: ["climb":answer.rawValue], type: rData.type)
53+
self.updateTags(id: rData.id, tags: ["climb":answer.rawValue], type: rData.type, exclude_gig_tags: false)
5454
}
5555
}
5656

0 commit comments

Comments
 (0)