diff --git a/Modules/FoundationExtras/Sources/FoundationExtras/Date+Extensions.swift b/Modules/FoundationExtras/Sources/FoundationExtras/Date+Extensions.swift index 48421cbe5..e26e4edb3 100755 --- a/Modules/FoundationExtras/Sources/FoundationExtras/Date+Extensions.swift +++ b/Modules/FoundationExtras/Sources/FoundationExtras/Date+Extensions.swift @@ -21,7 +21,7 @@ public extension Date { } } -private extension TimeInterval { +public extension TimeInterval { init(days: Int) { self.init(days * 24 * 60 * 60) diff --git a/Modules/Images/Sources/Images/HTMLMetadataCache.swift b/Modules/Images/Sources/Images/HTMLMetadataCache.swift new file mode 100644 index 000000000..db6faff6b --- /dev/null +++ b/Modules/Images/Sources/Images/HTMLMetadataCache.swift @@ -0,0 +1,48 @@ +// +// HTMLMetadataCache.swift +// +// +// Created by Brent Simmons on 10/13/24. +// + +import Foundation +import Core +import Parser +import FoundationExtras + +extension Notification.Name { + // Sent when HTMLMetadata is cached. Posted on any thread. + static let htmlMetadataAvailable = Notification.Name("htmlMetadataAvailable") +} + +final class HTMLMetadataCache: Sendable { + + static let shared = HTMLMetadataCache() + + // Sent along with .htmlMetadataAvailable notification + struct UserInfoKey { + static let htmlMetadata = "htmlMetadata" + static let url = "url" // String value + } + + private struct HTMLMetadataCacheRecord: CacheRecord { + let metadata: HTMLMetadata + let dateCreated = Date() + } + + private let cache = Cache(timeToLive: TimeInterval(days: 2), timeBetweenCleanups: TimeInterval(days: 1)) + + subscript(_ url: String) -> HTMLMetadata? { + get { + return cache[url]?.metadata + } + set { + guard let htmlMetadata = newValue else { + return + } + let cacheRecord = HTMLMetadataCacheRecord(metadata: htmlMetadata) + cache[url] = cacheRecord + NotificationCenter.default.post(name: .htmlMetadataAvailable, object: self, userInfo: [UserInfoKey.htmlMetadata: htmlMetadata, UserInfoKey.url: url]) + } + } +}