OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ios/chrome/browser/reading_list/reading_list_model_impl.h" | 5 #include "ios/chrome/browser/reading_list/reading_list_model_impl.h" |
6 | 6 |
7 #include "base/bind.h" | |
8 #include "base/logging.h" | |
9 #include "base/memory/ptr_util.h" | |
10 #include "components/prefs/pref_service.h" | |
7 #include "ios/chrome/browser/reading_list/reading_list_model_storage.h" | 11 #include "ios/chrome/browser/reading_list/reading_list_model_storage.h" |
12 #include "ios/chrome/browser/reading_list/reading_list_pref_names.h" | |
13 #include "ios/web/public/web_thread.h" | |
8 #include "url/gurl.h" | 14 #include "url/gurl.h" |
9 | 15 |
10 ReadingListModelImpl::ReadingListModelImpl() : ReadingListModelImpl(NULL) {} | 16 ReadingListModelImpl::ReadingListModelImpl() |
17 : ReadingListModelImpl(NULL, NULL) {} | |
11 | 18 |
12 ReadingListModelImpl::ReadingListModelImpl( | 19 ReadingListModelImpl::ReadingListModelImpl( |
13 std::unique_ptr<ReadingListModelStorage> storage) | 20 std::unique_ptr<ReadingListModelStorage> storage, |
14 : hasUnseen_(false) { | 21 PrefService* pref_service) |
22 : pref_service_(pref_service), | |
23 has_unseen_(false), | |
24 loaded_(false), | |
25 weak_ptr_factory_(this) { | |
26 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
15 if (storage) { | 27 if (storage) { |
16 storageLayer_ = std::move(storage); | 28 storage_layer_ = std::move(storage); |
17 read_ = storageLayer_->LoadPersistentReadList(); | 29 storage_layer_->SetReadingListModel(this); |
18 unread_ = storageLayer_->LoadPersistentUnreadList(); | 30 } else { |
19 hasUnseen_ = storageLayer_->LoadPersistentHasUnseen(); | 31 loaded_ = true; |
32 read_ = base::MakeUnique<ReadingListEntries>(); | |
33 unread_ = base::MakeUnique<ReadingListEntries>(); | |
20 } | 34 } |
21 loaded_ = true; | 35 has_unseen_ = LoadPersistentHasUnseen(); |
22 } | 36 } |
23 ReadingListModelImpl::~ReadingListModelImpl() {} | 37 ReadingListModelImpl::~ReadingListModelImpl() {} |
24 | 38 |
39 void ReadingListModelImpl::ModelLoaded( | |
40 std::unique_ptr<ReadingListEntries> unread, | |
41 std::unique_ptr<ReadingListEntries> read) { | |
42 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
43 read_ = std::move(read); | |
44 unread_ = std::move(unread); | |
45 SortEntries(); | |
46 loaded_ = true; | |
47 for (auto& observer : observers_) | |
48 observer.ReadingListModelLoaded(this); | |
49 } | |
50 | |
25 void ReadingListModelImpl::Shutdown() { | 51 void ReadingListModelImpl::Shutdown() { |
52 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
26 for (auto& observer : observers_) | 53 for (auto& observer : observers_) |
27 observer.ReadingListModelBeingDeleted(this); | 54 observer.ReadingListModelBeingDeleted(this); |
28 loaded_ = false; | 55 loaded_ = false; |
29 } | 56 } |
30 | 57 |
31 bool ReadingListModelImpl::loaded() const { | 58 bool ReadingListModelImpl::loaded() const { |
59 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
32 return loaded_; | 60 return loaded_; |
33 } | 61 } |
34 | 62 |
35 size_t ReadingListModelImpl::unread_size() const { | 63 size_t ReadingListModelImpl::unread_size() const { |
36 DCHECK(loaded()); | 64 DCHECK_CURRENTLY_ON(web::WebThread::UI); |
37 return unread_.size(); | 65 if (!loaded()) |
66 return 0; | |
67 return unread_->size(); | |
38 } | 68 } |
39 | 69 |
40 size_t ReadingListModelImpl::read_size() const { | 70 size_t ReadingListModelImpl::read_size() const { |
41 DCHECK(loaded()); | 71 DCHECK_CURRENTLY_ON(web::WebThread::UI); |
42 return read_.size(); | 72 if (!loaded()) |
73 return 0; | |
74 return read_->size(); | |
43 } | 75 } |
44 | 76 |
45 bool ReadingListModelImpl::HasUnseenEntries() const { | 77 bool ReadingListModelImpl::HasUnseenEntries() const { |
46 DCHECK(loaded()); | 78 DCHECK_CURRENTLY_ON(web::WebThread::UI); |
47 return unread_size() && hasUnseen_; | 79 if (!loaded()) |
80 return false; | |
81 return unread_size() && has_unseen_; | |
48 } | 82 } |
49 | 83 |
50 void ReadingListModelImpl::ResetUnseenEntries() { | 84 void ReadingListModelImpl::ResetUnseenEntries() { |
51 DCHECK(loaded()); | 85 DCHECK(loaded()); |
52 hasUnseen_ = false; | 86 has_unseen_ = false; |
53 if (storageLayer_ && !IsPerformingBatchUpdates()) | 87 if (!IsPerformingBatchUpdates()) |
54 storageLayer_->SavePersistentHasUnseen(false); | 88 SavePersistentHasUnseen(false); |
55 } | 89 } |
56 | 90 |
57 const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex( | 91 const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex( |
58 size_t index) const { | 92 size_t index) const { |
93 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
59 DCHECK(loaded()); | 94 DCHECK(loaded()); |
60 return unread_[index]; | 95 return unread_->at(index); |
61 } | 96 } |
62 | 97 |
63 const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex( | 98 const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex( |
64 size_t index) const { | 99 size_t index) const { |
100 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
65 DCHECK(loaded()); | 101 DCHECK(loaded()); |
66 return read_[index]; | 102 return read_->at(index); |
67 } | 103 } |
68 | 104 |
69 const ReadingListEntry* ReadingListModelImpl::GetEntryFromURL( | 105 const ReadingListEntry* ReadingListModelImpl::GetEntryFromURL( |
70 const GURL& gurl) const { | 106 const GURL& gurl) const { |
71 DCHECK(loaded()); | 107 DCHECK(loaded()); |
108 bool read; | |
109 return GetMutableEntryFromURL(gurl, read); | |
110 } | |
111 | |
112 ReadingListEntry* ReadingListModelImpl::GetMutableEntryFromURL( | |
113 const GURL& gurl, | |
114 bool& read) const { | |
skym
2016/11/01 18:27:25
I think this is against Google C++ style, https://
Olivier
2016/11/02 14:57:10
Done.
| |
115 DCHECK(loaded()); | |
72 ReadingListEntry entry(gurl, std::string()); | 116 ReadingListEntry entry(gurl, std::string()); |
73 auto it = std::find(read_.begin(), read_.end(), entry); | 117 auto it = std::find(read_->begin(), read_->end(), entry); |
74 if (it == read_.end()) { | 118 read = true; |
75 it = std::find(unread_.begin(), unread_.end(), entry); | 119 if (it == read_->end()) { |
76 if (it == unread_.end()) | 120 it = std::find(unread_->begin(), unread_->end(), entry); |
121 read = false; | |
122 if (it == unread_->end()) | |
77 return nullptr; | 123 return nullptr; |
78 } | 124 } |
79 return &(*it); | 125 return &(*it); |
80 } | 126 } |
81 | 127 |
82 bool ReadingListModelImpl::CallbackEntryURL( | 128 bool ReadingListModelImpl::CallbackEntryURL( |
83 const GURL& url, | 129 const GURL& url, |
84 base::Callback<void(const ReadingListEntry&)> callback) const { | 130 base::Callback<void(const ReadingListEntry&)> callback) const { |
131 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
85 DCHECK(loaded()); | 132 DCHECK(loaded()); |
86 const ReadingListEntry* entry = GetEntryFromURL(url); | 133 bool read; |
134 const ReadingListEntry* entry = GetMutableEntryFromURL(url, read); | |
87 if (entry) { | 135 if (entry) { |
88 callback.Run(*entry); | 136 callback.Run(*entry); |
89 return true; | 137 return true; |
90 } | 138 } |
91 return false; | 139 return false; |
92 } | 140 } |
93 | 141 |
94 void ReadingListModelImpl::RemoveEntryByUrl(const GURL& url) { | 142 bool ReadingListModelImpl::CallbackEntryReadStatusURL( |
143 const GURL& url, | |
144 base::Callback<void(const ReadingListEntry&, bool read)> callback) const { | |
145 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
95 DCHECK(loaded()); | 146 DCHECK(loaded()); |
96 const ReadingListEntry entry(url, std::string()); | 147 bool read; |
148 const ReadingListEntry* entry = GetMutableEntryFromURL(url, read); | |
149 if (entry) { | |
150 callback.Run(*entry, read); | |
151 return true; | |
152 } | |
153 return false; | |
154 } | |
97 | 155 |
98 auto result = std::find(unread_.begin(), unread_.end(), entry); | 156 void ReadingListModelImpl::SyncAddEntry(std::unique_ptr<ReadingListEntry> entry, |
99 if (result != unread_.end()) { | 157 bool read) { |
100 for (auto& observer : observers_) { | 158 DCHECK_CURRENTLY_ON(web::WebThread::UI); |
101 observer.ReadingListWillRemoveUnreadEntry( | 159 DCHECK(loaded()); |
102 this, std::distance(unread_.begin(), result)); | 160 bool is_entry_read; |
skym
2016/11/01 18:27:25
Can you rename to make it clear this is for the ol
Olivier
2016/11/02 14:57:10
Done.
| |
161 ReadingListEntry* existing_entry = | |
162 GetMutableEntryFromURL(entry->URL(), is_entry_read); | |
163 if (!existing_entry) { | |
164 if (storage_layer_) { | |
165 storage_layer_->SaveEntry(*entry, read, true); | |
103 } | 166 } |
104 unread_.erase(result); | 167 if (read) { |
105 if (storageLayer_ && !IsPerformingBatchUpdates()) | 168 for (auto& observer : observers_) |
106 storageLayer_->SavePersistentUnreadList(unread_); | 169 observer.ReadingListWillAddReadEntry(this, *entry); |
170 read_->insert(read_->begin(), std::move(*entry)); | |
171 } else { | |
172 for (auto& observer : observers_) | |
173 observer.ReadingListWillAddUnreadEntry(this, *entry); | |
174 has_unseen_ = true; | |
175 SavePersistentHasUnseen(true); | |
176 unread_->insert(unread_->begin(), std::move(*entry)); | |
177 } | |
107 for (auto& observer : observers_) | 178 for (auto& observer : observers_) |
108 observer.ReadingListDidApplyChanges(this); | 179 observer.ReadingListDidApplyChanges(this); |
skym
2016/11/01 18:27:25
I don't understand what these various observer met
Olivier
2016/11/02 14:57:10
You are right. Added ReadingListWillMoveEntry
| |
109 return; | 180 return; |
110 } | 181 } |
111 | 182 |
112 result = std::find(read_.begin(), read_.end(), entry); | 183 if (existing_entry->UpdateTime() > entry->UpdateTime()) { |
113 if (result != read_.end()) { | 184 // Existing entry is newer thatn sync one. Do not update it. |
114 for (auto& observer : observers_) { | 185 return; |
115 observer.ReadingListWillRemoveReadEntry( | 186 } |
116 this, std::distance(read_.begin(), result)); | 187 |
188 // Merge local data in new entry. | |
189 entry->MergeLocalStateFrom(*existing_entry); | |
190 | |
191 if (is_entry_read) { | |
192 auto result = std::find(read_->begin(), read_->end(), *existing_entry); | |
skym
2016/11/01 18:27:25
There's a lot of std::find calls in here. They're
Olivier
2016/11/02 14:57:10
Yes, the number of entries should stay small
| |
193 if (result != read_->end()) { | |
194 read_->erase(result); | |
skym
2016/11/01 18:27:25
If |is_entry_read| == |read|, then updating the ex
| |
117 } | 195 } |
118 read_.erase(result); | 196 } else { |
119 if (storageLayer_ && !IsPerformingBatchUpdates()) | 197 auto result = std::find(unread_->begin(), unread_->end(), *existing_entry); |
120 storageLayer_->SavePersistentReadList(read_); | 198 if (result != unread_->end()) { |
199 unread_->erase(result); | |
200 } | |
201 } | |
202 | |
203 if (storage_layer_) { | |
204 storage_layer_->SaveEntry(*entry, true, read); | |
skym
2016/11/01 18:27:25
Are the arguments |true| and |read| swapped here?
skym
2016/11/01 18:27:25
Also, kind of weird that the storage call is in th
Olivier
2016/11/02 14:57:10
Yes, thanks! Done.
Olivier
2016/11/02 14:57:10
It is there because there is a std::move on the ne
| |
205 } | |
206 | |
207 if (read) { | |
208 read_->push_back(std::move(*entry)); | |
209 } else { | |
210 unread_->push_back(std::move(*entry)); | |
211 } | |
212 } | |
213 | |
214 void ReadingListModelImpl::SyncRemoveEntry(const GURL& gurl) { | |
215 RemoveEntryByUrlImpl(gurl, true); | |
216 } | |
217 | |
218 void ReadingListModelImpl::RemoveEntryByUrl(const GURL& url) { | |
219 RemoveEntryByUrlImpl(url, false); | |
220 } | |
221 | |
222 void ReadingListModelImpl::RemoveEntryByUrlImpl(const GURL& url, | |
223 bool from_sync) { | |
224 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
225 DCHECK(loaded()); | |
226 const ReadingListEntry entry(url, std::string()); | |
227 | |
228 auto result = std::find(unread_->begin(), unread_->end(), entry); | |
229 if (result != unread_->end()) { | |
230 for (auto& observer : observers_) | |
231 observer.ReadingListWillRemoveUnreadEntry( | |
232 this, std::distance(unread_->begin(), result)); | |
233 | |
234 if (storage_layer_) { | |
235 storage_layer_->RemoveEntry(*result, from_sync); | |
236 } | |
237 unread_->erase(result); | |
238 | |
121 for (auto& observer : observers_) | 239 for (auto& observer : observers_) |
122 observer.ReadingListDidApplyChanges(this); | 240 observer.ReadingListDidApplyChanges(this); |
123 return; | 241 return; |
242 } | |
243 | |
244 result = std::find(read_->begin(), read_->end(), entry); | |
245 if (result != read_->end()) { | |
246 for (auto& observer : observers_) | |
247 observer.ReadingListWillRemoveReadEntry( | |
248 this, std::distance(read_->begin(), result)); | |
249 if (storage_layer_) { | |
250 storage_layer_->RemoveEntry(*result, from_sync); | |
251 } | |
252 read_->erase(result); | |
253 | |
254 for (auto& observer : observers_) | |
255 observer.ReadingListDidApplyChanges(this); | |
256 return; | |
124 } | 257 } |
125 } | 258 } |
126 | 259 |
127 const ReadingListEntry& ReadingListModelImpl::AddEntry( | 260 const ReadingListEntry& ReadingListModelImpl::AddEntry( |
128 const GURL& url, | 261 const GURL& url, |
129 const std::string& title) { | 262 const std::string& title) { |
263 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
130 DCHECK(loaded()); | 264 DCHECK(loaded()); |
131 RemoveEntryByUrl(url); | 265 RemoveEntryByUrl(url); |
132 ReadingListEntry entry(url, title); | 266 ReadingListEntry entry(url, title); |
133 for (auto& observer : observers_) | 267 for (auto& observer : observers_) |
134 observer.ReadingListWillAddUnreadEntry(this, entry); | 268 observer.ReadingListWillAddUnreadEntry(this, entry); |
135 unread_.insert(unread_.begin(), std::move(entry)); | 269 has_unseen_ = true; |
136 hasUnseen_ = true; | 270 SavePersistentHasUnseen(true); |
137 if (storageLayer_ && !IsPerformingBatchUpdates()) { | 271 if (storage_layer_) { |
138 storageLayer_->SavePersistentUnreadList(unread_); | 272 storage_layer_->SaveEntry(entry, false, false); |
139 storageLayer_->SavePersistentHasUnseen(true); | |
140 } | 273 } |
274 unread_->insert(unread_->begin(), std::move(entry)); | |
275 | |
141 for (auto& observer : observers_) | 276 for (auto& observer : observers_) |
142 observer.ReadingListDidApplyChanges(this); | 277 observer.ReadingListDidApplyChanges(this); |
143 return *unread_.begin(); | 278 return *unread_->begin(); |
144 } | 279 } |
145 | 280 |
146 void ReadingListModelImpl::MarkUnreadByURL(const GURL& url) { | 281 void ReadingListModelImpl::MarkUnreadByURL(const GURL& url) { |
147 DCHECK(loaded()); | 282 DCHECK(loaded()); |
148 ReadingListEntry entry(url, std::string()); | 283 ReadingListEntry entry(url, std::string()); |
149 auto result = std::find(read_.begin(), read_.end(), entry); | 284 auto result = std::find(read_->begin(), read_->end(), entry); |
150 if (result == read_.end()) | 285 if (result == read_->end()) |
151 return; | 286 return; |
152 | 287 |
153 for (ReadingListModelObserver& observer : observers_) { | 288 for (ReadingListModelObserver& observer : observers_) { |
154 observer.ReadingListWillMoveEntry(this, | 289 observer.ReadingListWillMoveEntry(this, |
155 std::distance(read_.begin(), result)); | 290 std::distance(read_->begin(), result)); |
156 } | 291 } |
157 | 292 |
158 unread_.insert(unread_.begin(), std::move(*result)); | 293 result->MarkEntryUpdated(); |
159 read_.erase(result); | 294 if (storage_layer_) { |
295 storage_layer_->SaveEntry(*result, false, false); | |
296 } | |
160 | 297 |
161 if (storageLayer_ && !IsPerformingBatchUpdates()) { | 298 unread_->insert(unread_->begin(), std::move(*result)); |
162 storageLayer_->SavePersistentUnreadList(read_); | 299 read_->erase(result); |
163 storageLayer_->SavePersistentReadList(unread_); | 300 |
164 } | |
165 for (ReadingListModelObserver& observer : observers_) { | 301 for (ReadingListModelObserver& observer : observers_) { |
166 observer.ReadingListDidApplyChanges(this); | 302 observer.ReadingListDidApplyChanges(this); |
167 } | 303 } |
168 } | 304 } |
169 | 305 |
170 void ReadingListModelImpl::MarkReadByURL(const GURL& url) { | 306 void ReadingListModelImpl::MarkReadByURL(const GURL& url) { |
307 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
171 DCHECK(loaded()); | 308 DCHECK(loaded()); |
172 ReadingListEntry entry(url, std::string()); | 309 ReadingListEntry entry(url, std::string()); |
173 auto result = std::find(unread_.begin(), unread_.end(), entry); | 310 auto result = std::find(unread_->begin(), unread_->end(), entry); |
174 if (result == unread_.end()) | 311 if (result == unread_->end()) |
175 return; | 312 return; |
176 | 313 |
177 for (auto& observer : observers_) { | 314 for (auto& observer : observers_) |
178 observer.ReadingListWillMoveEntry(this, | 315 observer.ReadingListWillMoveEntry(this, |
179 std::distance(unread_.begin(), result)); | 316 std::distance(unread_->begin(), result)); |
317 | |
318 result->MarkEntryUpdated(); | |
319 if (storage_layer_) { | |
320 storage_layer_->SaveEntry(*result, true, false); | |
180 } | 321 } |
181 | 322 |
182 read_.insert(read_.begin(), std::move(*result)); | 323 read_->insert(read_->begin(), std::move(*result)); |
183 unread_.erase(result); | 324 unread_->erase(result); |
184 | 325 |
185 if (storageLayer_ && !IsPerformingBatchUpdates()) { | |
186 storageLayer_->SavePersistentUnreadList(unread_); | |
187 storageLayer_->SavePersistentReadList(read_); | |
188 } | |
189 for (auto& observer : observers_) | 326 for (auto& observer : observers_) |
190 observer.ReadingListDidApplyChanges(this); | 327 observer.ReadingListDidApplyChanges(this); |
191 } | 328 } |
192 | 329 |
193 void ReadingListModelImpl::SetEntryTitle(const GURL& url, | 330 void ReadingListModelImpl::SetEntryTitle(const GURL& url, |
194 const std::string& title) { | 331 const std::string& title) { |
332 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
195 DCHECK(loaded()); | 333 DCHECK(loaded()); |
196 const ReadingListEntry entry(url, std::string()); | 334 const ReadingListEntry entry(url, std::string()); |
197 | 335 |
198 auto result = std::find(unread_.begin(), unread_.end(), entry); | 336 auto result = std::find(unread_->begin(), unread_->end(), entry); |
199 if (result != unread_.end()) { | 337 if (result != unread_->end()) { |
200 for (auto& observer : observers_) { | 338 for (auto& observer : observers_) |
201 observer.ReadingListWillUpdateUnreadEntry( | 339 observer.ReadingListWillUpdateUnreadEntry( |
202 this, std::distance(unread_.begin(), result)); | 340 this, std::distance(unread_->begin(), result)); |
341 result->SetTitle(title); | |
342 | |
343 if (storage_layer_) { | |
344 storage_layer_->SaveEntry(*result, false, false); | |
203 } | 345 } |
204 result->SetTitle(title); | |
205 if (storageLayer_ && !IsPerformingBatchUpdates()) | |
206 storageLayer_->SavePersistentUnreadList(unread_); | |
207 for (auto& observer : observers_) | 346 for (auto& observer : observers_) |
208 observer.ReadingListDidApplyChanges(this); | 347 observer.ReadingListDidApplyChanges(this); |
209 return; | 348 return; |
210 } | 349 } |
211 | 350 |
212 result = std::find(read_.begin(), read_.end(), entry); | 351 result = std::find(read_->begin(), read_->end(), entry); |
213 if (result != read_.end()) { | 352 if (result != read_->end()) { |
214 for (auto& observer : observers_) { | 353 for (auto& observer : observers_) |
215 observer.ReadingListWillUpdateReadEntry( | 354 observer.ReadingListWillUpdateReadEntry( |
216 this, std::distance(read_.begin(), result)); | 355 this, std::distance(read_->begin(), result)); |
356 result->SetTitle(title); | |
357 if (storage_layer_) { | |
358 storage_layer_->SaveEntry(*result, true, false); | |
217 } | 359 } |
218 result->SetTitle(title); | |
219 if (storageLayer_ && !IsPerformingBatchUpdates()) | |
220 storageLayer_->SavePersistentReadList(read_); | |
221 for (auto& observer : observers_) | 360 for (auto& observer : observers_) |
222 observer.ReadingListDidApplyChanges(this); | 361 observer.ReadingListDidApplyChanges(this); |
223 return; | 362 return; |
224 } | 363 } |
225 } | 364 } |
226 | 365 |
227 void ReadingListModelImpl::SetEntryDistilledURL(const GURL& url, | 366 void ReadingListModelImpl::SetEntryDistilledURL(const GURL& url, |
228 const GURL& distilled_url) { | 367 const GURL& distilled_url) { |
368 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
229 DCHECK(loaded()); | 369 DCHECK(loaded()); |
230 const ReadingListEntry entry(url, std::string()); | 370 const ReadingListEntry entry(url, std::string()); |
231 | 371 |
232 auto result = std::find(unread_.begin(), unread_.end(), entry); | 372 auto result = std::find(unread_->begin(), unread_->end(), entry); |
233 if (result != unread_.end()) { | 373 if (result != unread_->end()) { |
234 for (auto& observer : observers_) { | 374 for (auto& observer : observers_) |
235 observer.ReadingListWillUpdateUnreadEntry( | 375 observer.ReadingListWillUpdateUnreadEntry( |
236 this, std::distance(unread_.begin(), result)); | 376 this, std::distance(unread_->begin(), result)); |
377 result->SetDistilledURL(distilled_url); | |
378 if (storage_layer_) { | |
379 storage_layer_->SaveEntry(*result, false, false); | |
237 } | 380 } |
238 result->SetDistilledURL(distilled_url); | |
239 if (storageLayer_ && !IsPerformingBatchUpdates()) | |
240 storageLayer_->SavePersistentUnreadList(unread_); | |
241 for (auto& observer : observers_) | 381 for (auto& observer : observers_) |
242 observer.ReadingListDidApplyChanges(this); | 382 observer.ReadingListDidApplyChanges(this); |
243 return; | 383 return; |
244 } | 384 } |
245 | 385 |
246 result = std::find(read_.begin(), read_.end(), entry); | 386 result = std::find(read_->begin(), read_->end(), entry); |
247 if (result != read_.end()) { | 387 if (result != read_->end()) { |
248 for (auto& observer : observers_) { | 388 for (auto& observer : observers_) |
249 observer.ReadingListWillUpdateReadEntry( | 389 observer.ReadingListWillUpdateReadEntry( |
250 this, std::distance(read_.begin(), result)); | 390 this, std::distance(read_->begin(), result)); |
391 result->SetDistilledURL(distilled_url); | |
392 if (storage_layer_) { | |
393 storage_layer_->SaveEntry(*result, true, false); | |
251 } | 394 } |
252 result->SetDistilledURL(distilled_url); | |
253 if (storageLayer_ && !IsPerformingBatchUpdates()) | |
254 storageLayer_->SavePersistentReadList(read_); | |
255 for (auto& observer : observers_) | 395 for (auto& observer : observers_) |
256 observer.ReadingListDidApplyChanges(this); | 396 observer.ReadingListDidApplyChanges(this); |
257 return; | 397 return; |
258 } | 398 } |
259 } | 399 } |
260 | 400 |
261 void ReadingListModelImpl::SetEntryDistilledState( | 401 void ReadingListModelImpl::SetEntryDistilledState( |
262 const GURL& url, | 402 const GURL& url, |
263 ReadingListEntry::DistillationState state) { | 403 ReadingListEntry::DistillationState state) { |
404 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
264 DCHECK(loaded()); | 405 DCHECK(loaded()); |
265 const ReadingListEntry entry(url, std::string()); | 406 const ReadingListEntry entry(url, std::string()); |
266 | 407 |
267 auto result = std::find(unread_.begin(), unread_.end(), entry); | 408 auto result = std::find(unread_->begin(), unread_->end(), entry); |
268 if (result != unread_.end()) { | 409 if (result != unread_->end()) { |
269 for (auto& observer : observers_) { | 410 for (auto& observer : observers_) |
270 observer.ReadingListWillUpdateUnreadEntry( | 411 observer.ReadingListWillUpdateUnreadEntry( |
271 this, std::distance(unread_.begin(), result)); | 412 this, std::distance(unread_->begin(), result)); |
413 result->SetDistilledState(state); | |
414 if (storage_layer_) { | |
415 storage_layer_->SaveEntry(*result, false, false); | |
272 } | 416 } |
273 result->SetDistilledState(state); | |
274 if (storageLayer_ && !IsPerformingBatchUpdates()) | |
275 storageLayer_->SavePersistentUnreadList(unread_); | |
276 for (auto& observer : observers_) | 417 for (auto& observer : observers_) |
277 observer.ReadingListDidApplyChanges(this); | 418 observer.ReadingListDidApplyChanges(this); |
278 return; | 419 return; |
279 } | 420 } |
280 | 421 |
281 result = std::find(read_.begin(), read_.end(), entry); | 422 result = std::find(read_->begin(), read_->end(), entry); |
282 if (result != read_.end()) { | 423 if (result != read_->end()) { |
283 for (auto& observer : observers_) { | 424 for (auto& observer : observers_) |
284 observer.ReadingListWillUpdateReadEntry( | 425 observer.ReadingListWillUpdateReadEntry( |
285 this, std::distance(read_.begin(), result)); | 426 this, std::distance(read_->begin(), result)); |
427 result->SetDistilledState(state); | |
428 if (storage_layer_) { | |
429 storage_layer_->SaveEntry(*result, true, false); | |
286 } | 430 } |
287 result->SetDistilledState(state); | |
288 if (storageLayer_ && !IsPerformingBatchUpdates()) | |
289 storageLayer_->SavePersistentReadList(read_); | |
290 for (auto& observer : observers_) | 431 for (auto& observer : observers_) |
291 observer.ReadingListDidApplyChanges(this); | 432 observer.ReadingListDidApplyChanges(this); |
292 return; | 433 return; |
293 } | 434 } |
294 }; | 435 }; |
295 | 436 |
296 void ReadingListModelImpl::EndBatchUpdates() { | 437 void ReadingListModelImpl::LeavingBatchUpdates() { |
297 ReadingListModel::EndBatchUpdates(); | 438 DCHECK_CURRENTLY_ON(web::WebThread::UI); |
298 if (IsPerformingBatchUpdates() || !storageLayer_) { | 439 ReadingListModel::LeavingBatchUpdates(); |
440 if (storage_layer_) { | |
441 SavePersistentHasUnseen(has_unseen_); | |
442 storage_layer_->CommitTransaction(); | |
443 SortEntries(); | |
444 } | |
445 } | |
446 | |
447 void ReadingListModelImpl::EnteringBatchUpdates() { | |
448 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
449 if (storage_layer_) { | |
450 storage_layer_->BeginTransaction(); | |
451 } | |
452 ReadingListModel::EnteringBatchUpdates(); | |
453 } | |
454 | |
455 void ReadingListModelImpl::SavePersistentHasUnseen(bool has_unseen) { | |
456 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
457 if (!pref_service_) { | |
299 return; | 458 return; |
300 } | 459 } |
301 storageLayer_->SavePersistentUnreadList(unread_); | 460 pref_service_->SetBoolean(reading_list::prefs::kReadingListHasUnseenEntries, |
302 storageLayer_->SavePersistentReadList(read_); | 461 has_unseen); |
303 storageLayer_->SavePersistentHasUnseen(hasUnseen_); | |
304 } | 462 } |
463 | |
464 bool ReadingListModelImpl::LoadPersistentHasUnseen() { | |
465 DCHECK_CURRENTLY_ON(web::WebThread::UI); | |
466 if (!pref_service_) { | |
467 return false; | |
468 } | |
469 return pref_service_->GetBoolean( | |
470 reading_list::prefs::kReadingListHasUnseenEntries); | |
471 } | |
472 | |
473 syncer::ModelTypeService* ReadingListModelImpl::GetModelTypeService() { | |
474 return storage_layer_->GetModelTypeService(); | |
475 } | |
476 | |
477 void ReadingListModelImpl::SortEntries() { | |
478 std::sort(read_->begin(), read_->end(), | |
479 ReadingListEntry::CompareEntryUpdateTime); | |
480 std::sort(unread_->begin(), unread_->end(), | |
481 ReadingListEntry::CompareEntryUpdateTime); | |
482 } | |
OLD | NEW |