Add invalidation when highlights are added to items

This commit is contained in:
Jackson Harper 2022-03-31 15:04:22 -07:00
parent 183776c791
commit 13cd668cdd
3 changed files with 51 additions and 27 deletions

View file

@ -21,20 +21,18 @@ final class WebReaderViewModel: ObservableObject {
@Published var isLoading = false
@Published var articleContent: ArticleContent?
var slug: String?
var subscriptions = Set<AnyCancellable>()
func loadContent(dataService: DataService, slug: String) {
self.slug = slug
isLoading = true
guard let viewer = dataService.currentViewer else { return }
if let content = dataService.pageCache.object(forKey: NSString(string: slug)) {
print("RETRIEVED FORM CACHE", slug)
isLoading = false
articleContent = content.value
return
} else {
print("MISSED CACHE", slug)
if let content = dataService.pageFromCache(slug: slug) {
articleContent = content
// continue to load from the web if possible
}
dataService.articleContentPublisher(username: viewer.username, slug: slug).sink(
@ -44,7 +42,7 @@ final class WebReaderViewModel: ObservableObject {
},
receiveValue: { [weak self] articleContent in
self?.articleContent = articleContent
dataService.pageCache.setObject(CachedPageContent(articleContent), forKey: NSString(string: slug))
dataService.pageCache.setObject(CachedPageContent(slug, articleContent), forKey: NSString(string: slug))
}
)
.store(in: &subscriptions)
@ -177,12 +175,16 @@ final class WebReaderViewModel: ObservableObject {
switch actionID {
case "deleteHighlight":
dataService.invalidateCachedPage(slug: slug)
deleteHighlight(messageBody: messageBody, replyHandler: replyHandler, dataService: dataService)
case "createHighlight":
dataService.invalidateCachedPage(slug: slug)
createHighlight(messageBody: messageBody, replyHandler: replyHandler, dataService: dataService)
case "mergeHighlight":
dataService.invalidateCachedPage(slug: slug)
mergeHighlight(messageBody: messageBody, replyHandler: replyHandler, dataService: dataService)
case "updateHighlight":
dataService.invalidateCachedPage(slug: slug)
updateHighlight(messageBody: messageBody, replyHandler: replyHandler, dataService: dataService)
case "articleReadingProgress":
updateReadingProgress(messageBody: messageBody, replyHandler: replyHandler, dataService: dataService)

View file

@ -1,9 +1,11 @@
import Foundation
public class CachedPageContent: NSObject {
public let slug: String
public let value: ArticleContent
public init(_ content: ArticleContent) {
public init(_ slug: String, _ content: ArticleContent) {
self.slug = slug
self.value = content
}
}

View file

@ -4,7 +4,10 @@ import Models
public class CacheManager: NSObject, NSCacheDelegate {
public func cache(_: NSCache<AnyObject, AnyObject>, willEvictObject obj: Any) {
print("evicting object", obj)
// This is just used for debugging
if let content = obj as? CachedPageContent {
print("evicting page from cache", content.slug)
}
}
}
@ -32,23 +35,6 @@ public final class DataService: ObservableObject {
pageCache.delegate = cacheManager
}
public func prefetchPages(items: [FeedItem]) {
print("prefetching items", items, "cost limit", pageCache.countLimit)
guard let viewer = currentViewer else { return }
for item in items {
let slug = item.slug
articleContentPublisher(username: viewer.username, slug: slug).sink(
receiveCompletion: { _ in },
receiveValue: { [weak self] articleContent in
self?.pageCache.setObject(CachedPageContent(articleContent), forKey: NSString(string: slug))
}
)
.store(in: &subscriptions)
}
}
public func clearHighlights() {
highlightsCache.removeAllObjects()
}
@ -62,3 +48,37 @@ public final class DataService: ObservableObject {
}
}
}
public extension DataService {
func prefetchPages(items: [FeedItem]) {
print("prefetching pages")
guard let viewer = currentViewer else { return }
for item in items {
let slug = item.slug
articleContentPublisher(username: viewer.username, slug: slug).sink(
receiveCompletion: { _ in },
receiveValue: { [weak self] articleContent in
self?.pageCache.setObject(CachedPageContent(slug, articleContent), forKey: NSString(string: slug))
}
)
.store(in: &subscriptions)
}
}
func pageFromCache(slug: String) -> ArticleContent? {
if let content = pageCache.object(forKey: NSString(string: slug)) {
print("cache hit", slug)
return content.value
} else {
print("cache miss", slug)
}
return nil
}
func invalidateCachedPage(slug: String?) {
if let slug = slug {
pageCache.removeObject(forKey: NSString(string: slug))
}
}
}