@@ -13,6 +13,8 @@ class MapUndoManager {
1313 static let shared = MapUndoManager ( )
1414
1515 private let realm : Realm
16+
17+ var isUndoInProgress : Bool = false
1618
1719 private init ( ) {
1820 realm = try ! Realm ( )
@@ -21,96 +23,138 @@ class MapUndoManager {
2123 var updateTagsHandler : ( ( _ id: Int64 , _ tags: [ String : String ] , _ type: ElementType ) -> Void ) ?
2224
2325 func undo( for id: Int64 , type: ElementType ) {
26+ MapUndoManager . shared. isUndoInProgress = true
2427 switch type {
2528 case . way:
2629 guard let original = DatabaseConnector . shared. getWay ( id: Int ( id) , version: . original) ,
27- let current = DatabaseConnector . shared. getWay ( id: Int ( id) , version: . edited) else {
28- print ( " Undo failed: Way not found " )
30+ let edited = DatabaseConnector . shared. getWay ( id: Int ( id) , version: . edited) else {
31+ print ( " ❌ Undo failed: Way not found" )
2932 return
3033 }
3134
3235 try ? realm. write {
33- current. tags. removeAll ( )
34- original. tags. forEach { current. tags [ $0. key] = $0. value }
35-
36- current. polyline. removeAll ( )
37- current. polyline. append ( objectsIn: original. polyline)
36+ edited. tags. removeAll ( )
37+ original. tags. forEach { edited. tags [ $0. key] = $0. value }
3838
39- current . nodes . removeAll ( )
40- current . nodes . append ( objectsIn: original. nodes )
39+ edited . polyline . removeAll ( )
40+ edited . polyline . append ( objectsIn: original. polyline )
4141
42- // current.version += 1
42+ edited. nodes. removeAll ( )
43+ edited. nodes. append ( objectsIn: original. nodes)
4344 }
4445
45- updateTagsHandler ? ( id, current. tags. toDictionary ( ) , . way)
46-
47- if let changeset = DatabaseConnector . shared. getChangeset ( for: id, type: type) {
48- try ? realm. write {
49- realm. delete ( changeset)
50- }
51- }
52-
53- if let edited = DatabaseConnector . shared. getWay ( id: Int ( id) , version: . edited) {
54- try ? realm. write {
55- realm. delete ( edited)
56- }
46+ updateTagsHandler ? ( id, edited. tags. toDictionary ( ) , . way)
47+
48+ try ? realm. write {
49+ realm. delete ( edited)
5750 }
5851
5952 case . node:
6053 guard let original = DatabaseConnector . shared. getNode ( id: Int ( id) , version: . original) ,
61- let current = DatabaseConnector . shared. getNode ( id: Int ( id) , version: . edited) else {
62- print ( " Undo failed: Node not found " )
54+ let edited = DatabaseConnector . shared. getNode ( id: Int ( id) , version: . edited) else {
55+ print ( " ❌ Undo failed: Node not found" )
6356 return
6457 }
6558
6659 try ? realm. write {
67- current. tags. removeAll ( )
68- original. tags. forEach { current. tags [ $0. key] = $0. value }
60+ edited. tags. removeAll ( )
61+ original. tags. forEach { edited. tags [ $0. key] = $0. value }
62+ edited. point = original. point
63+ }
64+
65+ updateTagsHandler ? ( id, edited. tags. toDictionary ( ) , . node)
66+
67+ default :
68+ print ( " Unknown element type " )
69+ }
70+ }
71+
6972
70- current. point = original. point
71- // current.version += 1
73+
74+ func getUndoItems( ) -> [ UndoItem ] {
75+ let excludedKeys : Set < String > = [ " ext:gig_complete " , " ext:gig_last_updated " ]
76+ var items : [ UndoItem ] = [ ]
77+
78+ let editedNodes = realm. objects ( StoredNode . self)
79+ for edited in editedNodes {
80+ guard let original = DatabaseConnector . shared. getNode ( id: edited. id, version: . original) else {
81+ print ( " ⚠️ Original node not found for id: \( edited. id) " )
82+ continue
7283 }
7384
74- updateTagsHandler ? ( id, current. tags. toDictionary ( ) , . node)
75-
76- if let changeset = DatabaseConnector . shared. getChangeset ( for: id, type: type) {
77- try ? realm. write {
78- realm. delete ( changeset)
85+ let changedKeys = Set ( edited. tags. keys)
86+ . union ( original. tags. keys)
87+ . filter { key in
88+ edited. tags [ key] != original. tags [ key] && !excludedKeys. contains ( key)
7989 }
90+
91+ if !changedKeys. isEmpty {
92+ items. append ( UndoItem ( elementId: edited. id, type: . node, changedKeys: Array ( changedKeys) ) )
8093 }
81-
82- if let edited = DatabaseConnector . shared. getNode ( id: Int ( id) , version: . edited) {
83- try ? realm. write {
84- realm. delete ( edited)
85- }
94+ }
95+
96+ let editedWays = realm. objects ( StoredWay . self)
97+ for edited in editedWays {
98+ guard let original = DatabaseConnector . shared. getWay ( id: edited. id, version: . original) else {
99+ print ( " ⚠️ Original way not found for id: \( edited. id) " )
100+ continue
86101 }
87102
88- default :
89- print ( " Unknown element type " )
103+ let changedKeys = Set ( edited. tags. keys)
104+ . union ( original. tags. keys)
105+ . filter { key in
106+ edited. tags [ key] != original. tags [ key] && !excludedKeys. contains ( key)
107+ }
108+
109+ if !changedKeys. isEmpty {
110+ items. append ( UndoItem ( elementId: edited. id, type: . way, changedKeys: Array ( changedKeys) ) )
111+ }
90112 }
113+
114+ return items
91115 }
92-
93- func getUndoItems( ) -> [ UndoItem ] {
94- let changesets = DatabaseConnector . shared. getChangesets ( synced: true )
95-
96- var seen = Set < String > ( )
97-
98- return changesets. compactMap { cs in
99- guard let type = cs. elementType. toElementType ( ) else { return nil }
100- let key = " \( cs. elementId) - \( type) "
101-
102- if seen. contains ( key) {
103- return nil // Skip duplicates
104- } else {
105- seen. insert ( key)
106- let changedKeys = cs. tags. map { $0. key }
107- return UndoItem ( elementId: Int ( cs. elementId) ?? - 1 , type: type, changedKeys: changedKeys)
116+
117+
118+
119+
120+ }
121+
122+ extension MapUndoManager {
123+ func finalizeSuccessfulSubmit( id: Int , type: ElementType ) {
124+ let realm = try ! Realm ( )
125+
126+ try ? realm. write {
127+ switch type {
128+ case . way:
129+ if let original = DatabaseConnector . shared. getWay ( id: id, version: . original) {
130+ original. tags [ " ext:gig_complete " ] = " yes "
131+ }
132+ if let edited = DatabaseConnector . shared. getWay ( id: id, version: . edited) {
133+ realm. delete ( edited)
134+ }
135+
136+ case . node:
137+ if let original = DatabaseConnector . shared. getNode ( id: id, version: . original) {
138+ original. tags [ " ext:gig_complete " ] = " yes "
139+ }
140+ if let edited = DatabaseConnector . shared. getNode ( id: id, version: . edited) {
141+ realm. delete ( edited)
142+ }
143+
144+ default :
145+ break
146+ }
147+
148+ if let changeset = DatabaseConnector . shared. getChangeset ( for: Int64 ( id) , type: type) {
149+ realm. delete ( changeset)
108150 }
109151 }
110152 }
111153
154+
112155}
113156
157+
114158extension Map where Key == String , Value == String {
115159 func toDictionary( ) -> [ String : String ] {
116160 var dict : [ String : String ] = [ : ]
0 commit comments