| 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 { |
| 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; |
| 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); |
| 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); |
| 193 if (result != read_->end()) { |
| 194 read_->erase(result); |
| 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); |
| 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 |