@@ -7,6 +7,10 @@ import Networking
77public class InboxNotesStore : Store {
88 private let remote : InboxNotesRemote
99
10+ private lazy var sharedDerivedStorage : StorageType = {
11+ return storageManager. writerDerivedStorage
12+ } ( )
13+
1014 public override init ( dispatcher: Dispatcher , storageManager: StorageManagerType , network: Network ) {
1115 self . remote = InboxNotesRemote ( network: network)
1216 super. init ( dispatcher: dispatcher, storageManager: storageManager, network: network)
@@ -52,7 +56,22 @@ private extension InboxNotesStore {
5256 type: [ InboxNotesRemote . NoteType ] ? = nil ,
5357 status: [ InboxNotesRemote . Status ] ? = nil ,
5458 completion: @escaping ( Result < [ InboxNote ] , Error > ) -> ( ) ) {
55- remote. loadAllInboxNotes ( for: siteID, pageNumber: pageNumber, pageSize: pageSize, orderBy: orderBy, type: type, status: status, completion: completion)
59+ remote. loadAllInboxNotes ( for: siteID, pageNumber: pageNumber, pageSize: pageSize, orderBy: orderBy, type: type, status: status) { [ weak self] result in
60+ guard let self = self else { return }
61+ switch result {
62+ case . failure( let error) :
63+ completion ( . failure( error) )
64+
65+ case . success( let inboxNotes) :
66+ if pageNumber == Default . pageNumber {
67+ self . deleteStoredInboxNotes ( siteID: siteID)
68+ }
69+
70+ self . upsertStoredInboxNotesInBackground ( readOnlyInboxNotes: inboxNotes, siteID: siteID) {
71+ completion ( . success( inboxNotes) )
72+ }
73+ }
74+ }
5675 }
5776
5877 /// Dismiss one `InboxNote`.
@@ -61,7 +80,17 @@ private extension InboxNotesStore {
6180 func dismissInboxNote( for siteID: Int64 ,
6281 noteID: Int64 ,
6382 completion: @escaping ( Result < InboxNote , Error > ) -> ( ) ) {
64- remote. dismissInboxNote ( for: siteID, noteID: noteID, completion: completion)
83+ remote. dismissInboxNote ( for: siteID, noteID: noteID) { [ weak self] result in
84+ switch result {
85+ case . failure( let error) :
86+ completion ( . failure( error) )
87+
88+ case . success( let inboxNote) :
89+ self ? . upsertStoredInboxNotesInBackground ( readOnlyInboxNotes: [ inboxNote] , siteID: siteID, onCompletion: {
90+ completion ( . success( inboxNote) )
91+ } )
92+ }
93+ }
6594 }
6695
6796 /// Set an `InboxNote` as `actioned`.
@@ -71,7 +100,79 @@ private extension InboxNotesStore {
71100 noteID: Int64 ,
72101 actionID: Int64 ,
73102 completion: @escaping ( Result < InboxNote , Error > ) -> ( ) ) {
74- remote. markInboxNoteAsActioned ( for: siteID, noteID: noteID, actionID: actionID, completion: completion)
103+ remote. markInboxNoteAsActioned ( for: siteID, noteID: noteID, actionID: actionID) { [ weak self] result in
104+ switch result {
105+ case . failure( let error) :
106+ completion ( . failure( error) )
107+
108+ case . success( let inboxNote) :
109+ self ? . upsertStoredInboxNotesInBackground ( readOnlyInboxNotes: [ inboxNote] , siteID: siteID, onCompletion: {
110+ completion ( . success( inboxNote) )
111+ } )
112+ }
113+ }
114+ }
115+ }
116+
117+ // MARK: - Storage: InboxNote
118+ //
119+ private extension InboxNotesStore {
120+
121+ /// Updates or Inserts specified Inbox Notes Entities in a background thread
122+ /// `onCompletion` will be called on the main thread.
123+ ///
124+ func upsertStoredInboxNotesInBackground( readOnlyInboxNotes: [ Networking . InboxNote ] ,
125+ siteID: Int64 ,
126+ onCompletion: @escaping ( ) -> Void ) {
127+ let derivedStorage = sharedDerivedStorage
128+ derivedStorage. perform { [ weak self] in
129+ self ? . upsertStoredInboxNotes ( readOnlyInboxNotes: readOnlyInboxNotes,
130+ in: derivedStorage,
131+ siteID: siteID)
132+ }
133+
134+ storageManager. saveDerivedType ( derivedStorage: derivedStorage) {
135+ DispatchQueue . main. async ( execute: onCompletion)
136+ }
137+ }
138+
139+ /// Updates or Inserts the specified Inbox Note entities
140+ ///
141+ func upsertStoredInboxNotes( readOnlyInboxNotes: [ Networking . InboxNote ] ,
142+ in storage: StorageType ,
143+ siteID: Int64 ) {
144+ for inboxNote in readOnlyInboxNotes {
145+ let storageInboxNote = storage. loadInboxNote ( siteID: siteID, id: inboxNote. id) ?? storage. insertNewObject ( ofType: Storage . InboxNote. self)
146+ storageInboxNote. update ( with: inboxNote)
147+ handleInboxActions ( inboxNote, storageInboxNote, storage)
148+ }
149+ }
150+
151+ /// Updates, inserts, or prunes the provided stored inboxnote actions using the provided read-only Inbox's actions
152+ ///
153+ func handleInboxActions( _ readOnlyInboxNote: Networking . InboxNote , _ storageInboxNote: Storage . InboxNote , _ storage: StorageType ) {
154+
155+ // Removes all the inbox action first.
156+ storageInboxNote. actions? . forEach { existingStorageAction in
157+ storage. deleteObject ( existingStorageAction)
158+ }
159+
160+ // Inserts the actions from the read-only inbox note.
161+ var storageInboxActions = [ StorageInboxAction] ( )
162+ for readOnlyInboxAction in readOnlyInboxNote. actions {
163+ let newStorageInboxAction = storage. insertNewObject ( ofType: Storage . InboxAction. self)
164+ newStorageInboxAction. update ( with: readOnlyInboxAction)
165+ storageInboxActions. append ( newStorageInboxAction)
166+ }
167+ storageInboxNote. actions = Set ( storageInboxActions)
168+ }
169+
170+ /// Deletes all Storage.InboxNote with the specified `siteID`
171+ ///
172+ func deleteStoredInboxNotes( siteID: Int64 ) {
173+ let storage = storageManager. viewStorage
174+ storage. deleteInboxNotes ( siteID: siteID)
175+ storage. saveIfNeeded ( )
75176 }
76177}
77178
0 commit comments