mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-21 15:50:59 +00:00
Replace Kingfisher with SDWebImage
This commit is contained in:
parent
8b2acf1ace
commit
23a7725840
35 changed files with 215 additions and 250 deletions
|
@ -1,7 +1,7 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import ServiceLayer
|
||||
|
||||
struct ImageCacheConfiguration {
|
||||
|
@ -14,19 +14,23 @@ struct ImageCacheConfiguration {
|
|||
|
||||
extension ImageCacheConfiguration {
|
||||
func configure() throws {
|
||||
KingfisherManager.shared.cache = try ImageCache(
|
||||
name: Self.name,
|
||||
cacheDirectoryURL: Self.directoryURL)
|
||||
try KingfisherManager.shared.defaultOptions = [
|
||||
.cacheSerializer(ImageCacheSerializer(service: .init(environment: environment)))
|
||||
]
|
||||
SDImageCache.defaultDiskCacheDirectory = Self.imageCacheDirectoryURL?.path
|
||||
ImageDiskCache.service = try ImageSerializationService(environment: environment)
|
||||
SDImageCacheConfig.default.diskCacheClass = ImageDiskCache.self
|
||||
|
||||
if let legacyImageCacheDirectoryURL = Self.legacyImageCacheDirectoryURL,
|
||||
FileManager.default.fileExists(atPath: legacyImageCacheDirectoryURL.path) {
|
||||
try? FileManager.default.removeItem(at: legacyImageCacheDirectoryURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension ImageCacheConfiguration {
|
||||
static let name = "Images"
|
||||
static let directoryURL = FileManager.default.containerURL(
|
||||
static let cachesDirectoryURL = FileManager.default.containerURL(
|
||||
forSecurityApplicationGroupIdentifier: AppEnvironment.appGroup)?
|
||||
.appendingPathComponent("Library")
|
||||
.appendingPathComponent("Caches")
|
||||
static let imageCacheDirectoryURL = cachesDirectoryURL?.appendingPathComponent("com.metabolist.metatext.images")
|
||||
static let legacyImageCacheDirectoryURL =
|
||||
cachesDirectoryURL?.appendingPathComponent("com.onevcat.Kingfisher.ImageCache.Images")
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import Kingfisher
|
||||
import ServiceLayer
|
||||
|
||||
struct ImageCacheSerializer {
|
||||
private let service: ImageSerializationService
|
||||
|
||||
init(service: ImageSerializationService) {
|
||||
self.service = service
|
||||
}
|
||||
}
|
||||
|
||||
extension ImageCacheSerializer: CacheSerializer {
|
||||
func data(with image: KFCrossPlatformImage, original: Data?) -> Data? {
|
||||
guard let data = image.kf.data(format: original?.kf.imageFormat ?? .unknown) else { return nil }
|
||||
|
||||
return try? service.serialize(data: data)
|
||||
}
|
||||
|
||||
func image(with data: Data, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage? {
|
||||
guard let deserialized = try? service.deserialize(data: data) else { return nil }
|
||||
|
||||
return KingfisherWrapper.image(data: deserialized, options: .init())
|
||||
}
|
||||
}
|
39
Caches/ImageDiskCache.swift
Normal file
39
Caches/ImageDiskCache.swift
Normal file
|
@ -0,0 +1,39 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import SDWebImage
|
||||
import ServiceLayer
|
||||
|
||||
final class ImageDiskCache: SDDiskCache {
|
||||
static var service: ImageSerializationService?
|
||||
|
||||
private let cachePath: String
|
||||
|
||||
required init?(cachePath: String, config: SDImageCacheConfig) {
|
||||
self.cachePath = cachePath
|
||||
|
||||
super.init(cachePath: cachePath, config: config)
|
||||
}
|
||||
|
||||
override func data(forKey key: String) -> Data? {
|
||||
guard let data = super.data(forKey: key) else { return nil }
|
||||
|
||||
return try? Self.service?.deserialize(data: data)
|
||||
}
|
||||
|
||||
override func setData(_ data: Data?, forKey key: String) {
|
||||
guard let data = data else {
|
||||
super.setData(nil, forKey: key)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
super.setData(try? Self.service?.serialize(data: data), forKey: key)
|
||||
}
|
||||
|
||||
override func cachePath(forKey key: String) -> String? {
|
||||
guard let service = Self.service else { return super.cachePath(forKey: key) }
|
||||
|
||||
return (cachePath as NSString).appendingPathComponent(service.cacheKey(forKey: key))
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import Kingfisher
|
||||
|
||||
struct PrefetchRequestModifier: ImageDownloadRequestModifier {
|
||||
func modified(for request: URLRequest) -> URLRequest? {
|
||||
var mutableRequest = request
|
||||
|
||||
mutableRequest.allowsExpensiveNetworkAccess = false
|
||||
mutableRequest.allowsConstrainedNetworkAccess = false
|
||||
|
||||
return request
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import Mastodon
|
||||
import UIKit
|
||||
import ViewModels
|
||||
|
@ -12,17 +11,15 @@ extension NSMutableAttributedString {
|
|||
|
||||
while let tokenRange = string.range(of: token) {
|
||||
let attachment = AnimatedTextAttachment()
|
||||
let url: URL
|
||||
|
||||
if !identityContext.appPreferences.shouldReduceMotion,
|
||||
identityContext.appPreferences.animateCustomEmojis {
|
||||
url = emoji.url
|
||||
attachment.imageURL = emoji.url
|
||||
} else {
|
||||
url = emoji.staticUrl
|
||||
attachment.imageURL = emoji.staticUrl
|
||||
}
|
||||
|
||||
attachment.accessibilityLabel = emoji.shortcode
|
||||
attachment.kf.setImage(with: url, attributedView: view)
|
||||
replaceCharacters(in: NSRange(tokenRange, in: string), with: NSAttributedString(attachment: attachment))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,16 +35,15 @@
|
|||
D021A69025C3E4B8008A0C0D /* EmojiContentConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07EC7E225B13DD3006DF726 /* EmojiContentConfiguration.swift */; };
|
||||
D021A69525C3E4C1008A0C0D /* EmojiView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07EC7F125B13E57006DF726 /* EmojiView.swift */; };
|
||||
D021A6A625C3E584008A0C0D /* EditAttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936E825AA3F3D00754FDF /* EditAttachmentView.swift */; };
|
||||
D025B14625C4D26B001C69A8 /* ImageCacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D025B14525C4D26A001C69A8 /* ImageCacheSerializer.swift */; };
|
||||
D025B14725C4D26B001C69A8 /* ImageCacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D025B14525C4D26A001C69A8 /* ImageCacheSerializer.swift */; };
|
||||
D025B14D25C4E482001C69A8 /* ImageCacheConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D025B14C25C4E482001C69A8 /* ImageCacheConfiguration.swift */; };
|
||||
D025B14E25C4E482001C69A8 /* ImageCacheConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D025B14C25C4E482001C69A8 /* ImageCacheConfiguration.swift */; };
|
||||
D025B15B25C4EA7D001C69A8 /* ImageCacheConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D025B14C25C4E482001C69A8 /* ImageCacheConfiguration.swift */; };
|
||||
D025B16025C4EA81001C69A8 /* ImageCacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D025B14525C4D26A001C69A8 /* ImageCacheSerializer.swift */; };
|
||||
D025B16A25C4EB18001C69A8 /* ServiceLayer in Frameworks */ = {isa = PBXBuildFile; productRef = D025B16925C4EB18001C69A8 /* ServiceLayer */; };
|
||||
D025B17025C4EB58001C69A8 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = D025B16F25C4EB58001C69A8 /* Kingfisher */; };
|
||||
D025B17E25C500BC001C69A8 /* CapsuleButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D025B17D25C500BC001C69A8 /* CapsuleButton.swift */; };
|
||||
D02E1F95250B13210071AD56 /* SafariView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D02E1F94250B13210071AD56 /* SafariView.swift */; };
|
||||
D035D8F925E4338D00E597C9 /* ImageDiskCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D035D8F825E4338D00E597C9 /* ImageDiskCache.swift */; };
|
||||
D035D8FE25E4339800E597C9 /* ImageDiskCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D035D8F825E4338D00E597C9 /* ImageDiskCache.swift */; };
|
||||
D035D90325E4388800E597C9 /* ImageDiskCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D035D8F825E4338D00E597C9 /* ImageDiskCache.swift */; };
|
||||
D035F86925B7F2ED00DC75ED /* MainNavigationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D035F86825B7F2ED00DC75ED /* MainNavigationViewController.swift */; };
|
||||
D035F86F25B7F30E00DC75ED /* MainNavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D035F86E25B7F30E00DC75ED /* MainNavigationView.swift */; };
|
||||
D035F87D25B7F61600DC75ED /* TimelinesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D035F87C25B7F61600DC75ED /* TimelinesViewController.swift */; };
|
||||
|
@ -60,9 +59,11 @@
|
|||
D036EBB8259FE29800EC1CFC /* Status+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0849C7E25903C4900A5EBCC /* Status+Extensions.swift */; };
|
||||
D036EBC2259FE2AD00EC1CFC /* UIVIewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E7AD3825870B13005F5E2D /* UIVIewController+Extensions.swift */; };
|
||||
D03D87F425C23C44004DCBB2 /* SecondaryNavigationTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03D87F325C23C44004DCBB2 /* SecondaryNavigationTitleView.swift */; };
|
||||
D0477F1525C68BAC005C5368 /* PrefetchRequestModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0477F1425C68BAC005C5368 /* PrefetchRequestModifier.swift */; };
|
||||
D0477F2C25C6EBAD005C5368 /* OpenInDefaultBrowserActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0477F2B25C6EBAD005C5368 /* OpenInDefaultBrowserActivity.swift */; };
|
||||
D0477F4625C72E50005C5368 /* CapsuleLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0477F4525C72E50005C5368 /* CapsuleLabel.swift */; };
|
||||
D04F34B625E42ABE00714251 /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = D04F34B525E42ABE00714251 /* SDWebImage */; };
|
||||
D04F34BC25E42ADC00714251 /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = D04F34BB25E42ADC00714251 /* SDWebImage */; };
|
||||
D04F34C225E42AE500714251 /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = D04F34C125E42AE500714251 /* SDWebImage */; };
|
||||
D04F9E8E259E9C950081B0C9 /* ViewModels in Frameworks */ = {isa = PBXBuildFile; productRef = D04F9E8D259E9C950081B0C9 /* ViewModels */; };
|
||||
D05936CF25A8D79800754FDF /* EditAttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936CE25A8D79800754FDF /* EditAttachmentViewController.swift */; };
|
||||
D05936D025A8D79800754FDF /* EditAttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936CE25A8D79800754FDF /* EditAttachmentViewController.swift */; };
|
||||
|
@ -206,8 +207,6 @@
|
|||
D0F0B12E251A97E400942152 /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F0B12D251A97E400942152 /* TableViewController.swift */; };
|
||||
D0F0B136251AA12700942152 /* CollectionItem+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F0B135251AA12700942152 /* CollectionItem+Extensions.swift */; };
|
||||
D0F4362D25C10B9600E4F896 /* AddIdentityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F4362C25C10B9600E4F896 /* AddIdentityViewController.swift */; };
|
||||
D0F5880525A7E4C500E3A49C /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = D0F5880425A7E4C500E3A49C /* Kingfisher */; };
|
||||
D0F5880F25A7E6CC00E3A49C /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = D0F5880E25A7E6CC00E3A49C /* Kingfisher */; };
|
||||
D0FCC105259C4E61000B67DF /* NewStatusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FCC104259C4E61000B67DF /* NewStatusViewController.swift */; };
|
||||
D0FCC106259C4E62000B67DF /* NewStatusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FCC104259C4E61000B67DF /* NewStatusViewController.swift */; };
|
||||
D0FE1C8F253686F9003EF1EB /* PlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FE1C8E253686F9003EF1EB /* PlayerView.swift */; };
|
||||
|
@ -273,10 +272,10 @@
|
|||
D021A61925C36C1A008A0C0D /* IdentityContentConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityContentConfiguration.swift; sourceTree = "<group>"; };
|
||||
D021A62B25C38570008A0C0D /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; };
|
||||
D021A63525C38ADB008A0C0D /* AcknowledgmentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AcknowledgmentsView.swift; sourceTree = "<group>"; };
|
||||
D025B14525C4D26A001C69A8 /* ImageCacheSerializer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageCacheSerializer.swift; sourceTree = "<group>"; };
|
||||
D025B14C25C4E482001C69A8 /* ImageCacheConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCacheConfiguration.swift; sourceTree = "<group>"; };
|
||||
D025B17D25C500BC001C69A8 /* CapsuleButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapsuleButton.swift; sourceTree = "<group>"; };
|
||||
D02E1F94250B13210071AD56 /* SafariView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariView.swift; sourceTree = "<group>"; };
|
||||
D035D8F825E4338D00E597C9 /* ImageDiskCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageDiskCache.swift; sourceTree = "<group>"; };
|
||||
D035F86825B7F2ED00DC75ED /* MainNavigationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainNavigationViewController.swift; sourceTree = "<group>"; };
|
||||
D035F86E25B7F30E00DC75ED /* MainNavigationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainNavigationView.swift; sourceTree = "<group>"; };
|
||||
D035F87C25B7F61600DC75ED /* TimelinesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinesViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -289,7 +288,6 @@
|
|||
D036AA0B254B612B009094DF /* NotificationContentConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationContentConfiguration.swift; sourceTree = "<group>"; };
|
||||
D036AA16254CA823009094DF /* StatusBodyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBodyView.swift; sourceTree = "<group>"; };
|
||||
D03D87F325C23C44004DCBB2 /* SecondaryNavigationTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondaryNavigationTitleView.swift; sourceTree = "<group>"; };
|
||||
D0477F1425C68BAC005C5368 /* PrefetchRequestModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefetchRequestModifier.swift; sourceTree = "<group>"; };
|
||||
D0477F2B25C6EBAD005C5368 /* OpenInDefaultBrowserActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenInDefaultBrowserActivity.swift; sourceTree = "<group>"; };
|
||||
D0477F4525C72E50005C5368 /* CapsuleLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapsuleLabel.swift; sourceTree = "<group>"; };
|
||||
D047FA8C24C3E21200AF17C5 /* Metatext.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Metatext.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
@ -434,8 +432,8 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D0F5880525A7E4C500E3A49C /* Kingfisher in Frameworks */,
|
||||
D0E2C1D124FD97F000854680 /* ViewModels in Frameworks */,
|
||||
D04F34B625E42ABE00714251 /* SDWebImage in Frameworks */,
|
||||
D0FE7C8025C4C79F00203957 /* PreviewViewModels in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -451,7 +449,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D0F5880F25A7E6CC00E3A49C /* Kingfisher in Frameworks */,
|
||||
D04F34BC25E42ADC00714251 /* SDWebImage in Frameworks */,
|
||||
D04F9E8E259E9C950081B0C9 /* ViewModels in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -460,7 +458,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D025B17025C4EB58001C69A8 /* Kingfisher in Frameworks */,
|
||||
D04F34C225E42AE500714251 /* SDWebImage in Frameworks */,
|
||||
D025B16A25C4EB18001C69A8 /* ServiceLayer in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -823,9 +821,8 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
D025B14C25C4E482001C69A8 /* ImageCacheConfiguration.swift */,
|
||||
D025B14525C4D26A001C69A8 /* ImageCacheSerializer.swift */,
|
||||
D0FE1C9725368A9D003EF1EB /* PlayerCache.swift */,
|
||||
D0477F1425C68BAC005C5368 /* PrefetchRequestModifier.swift */,
|
||||
D035D8F825E4338D00E597C9 /* ImageDiskCache.swift */,
|
||||
);
|
||||
path = Caches;
|
||||
sourceTree = "<group>";
|
||||
|
@ -852,8 +849,8 @@
|
|||
name = Metatext;
|
||||
packageProductDependencies = (
|
||||
D0E2C1D024FD97F000854680 /* ViewModels */,
|
||||
D0F5880425A7E4C500E3A49C /* Kingfisher */,
|
||||
D0FE7C7F25C4C79F00203957 /* PreviewViewModels */,
|
||||
D04F34B525E42ABE00714251 /* SDWebImage */,
|
||||
);
|
||||
productName = "Metatext (iOS)";
|
||||
productReference = D047FA8C24C3E21200AF17C5 /* Metatext.app */;
|
||||
|
@ -894,7 +891,7 @@
|
|||
name = "Share Extension";
|
||||
packageProductDependencies = (
|
||||
D04F9E8D259E9C950081B0C9 /* ViewModels */,
|
||||
D0F5880E25A7E6CC00E3A49C /* Kingfisher */,
|
||||
D04F34BB25E42ADC00714251 /* SDWebImage */,
|
||||
);
|
||||
productName = "Share Extension";
|
||||
productReference = D08E526C257C36CA00FA2C5F /* Share Extension.appex */;
|
||||
|
@ -915,7 +912,7 @@
|
|||
name = "Notification Service Extension";
|
||||
packageProductDependencies = (
|
||||
D025B16925C4EB18001C69A8 /* ServiceLayer */,
|
||||
D025B16F25C4EB58001C69A8 /* Kingfisher */,
|
||||
D04F34C125E42AE500714251 /* SDWebImage */,
|
||||
);
|
||||
productName = "Notification Service Extension";
|
||||
productReference = D0E5361924E3EB4D00FB1CE1 /* Notification Service Extension.appex */;
|
||||
|
@ -957,7 +954,7 @@
|
|||
);
|
||||
mainGroup = D047FA7F24C3E21000AF17C5;
|
||||
packageReferences = (
|
||||
D0F5880325A7E4C500E3A49C /* XCRemoteSwiftPackageReference "Kingfisher" */,
|
||||
D04F34B425E42ABE00714251 /* XCRemoteSwiftPackageReference "SDWebImage" */,
|
||||
);
|
||||
productRefGroup = D047FA8D24C3E21200AF17C5 /* Products */;
|
||||
projectDirPath = "";
|
||||
|
@ -1060,7 +1057,6 @@
|
|||
D0477F2C25C6EBAD005C5368 /* OpenInDefaultBrowserActivity.swift in Sources */,
|
||||
D0DD50CB256B1F24004A04F7 /* ReportView.swift in Sources */,
|
||||
D07F4D9825D493E300F61133 /* MuteView.swift in Sources */,
|
||||
D0477F1525C68BAC005C5368 /* PrefetchRequestModifier.swift in Sources */,
|
||||
D097F41B25BE3E1A00859F2C /* SearchScope+Extensions.swift in Sources */,
|
||||
D0CEC10125E337C900FEF5A6 /* AnimatedTextAttachment.swift in Sources */,
|
||||
D035F8B325B9616000DC75ED /* Timeline+Extensions.swift in Sources */,
|
||||
|
@ -1080,6 +1076,7 @@
|
|||
D021A60A25C36B32008A0C0D /* IdentityTableViewCell.swift in Sources */,
|
||||
D0849C7F25903C4900A5EBCC /* Status+Extensions.swift in Sources */,
|
||||
D0F4362D25C10B9600E4F896 /* AddIdentityViewController.swift in Sources */,
|
||||
D035D8F925E4338D00E597C9 /* ImageDiskCache.swift in Sources */,
|
||||
D0625E59250F092900502611 /* StatusTableViewCell.swift in Sources */,
|
||||
D0E569DB2529319100FA1D72 /* LoadMoreView.swift in Sources */,
|
||||
D05936FF25AA94EA00754FDF /* MarkAttachmentsSensitiveView.swift in Sources */,
|
||||
|
@ -1136,7 +1133,6 @@
|
|||
D036AA0C254B612B009094DF /* NotificationContentConfiguration.swift in Sources */,
|
||||
D08B8D3D253F929E00B1EBEF /* ImageViewController.swift in Sources */,
|
||||
D035F86925B7F2ED00DC75ED /* MainNavigationViewController.swift in Sources */,
|
||||
D025B14625C4D26B001C69A8 /* ImageCacheSerializer.swift in Sources */,
|
||||
D0B8510C25259E56004E0744 /* LoadMoreTableViewCell.swift in Sources */,
|
||||
D08E52612579D2E100FA2C5F /* DomainBlocksView.swift in Sources */,
|
||||
D01F41E424F8889700D55A2D /* AttachmentsView.swift in Sources */,
|
||||
|
@ -1226,8 +1222,8 @@
|
|||
D088406E25AFBBE200BB749B /* EmojiPickerViewController.swift in Sources */,
|
||||
D0E39B8725D9B7FD009C10F8 /* AutocompleteDataSource.swift in Sources */,
|
||||
D00CB23325C92F2D008EF267 /* Attachment+Extensions.swift in Sources */,
|
||||
D035D8FE25E4339800E597C9 /* ImageDiskCache.swift in Sources */,
|
||||
D0D93ECA25D9C76500C622ED /* AutocompleteItemView.swift in Sources */,
|
||||
D025B14725C4D26B001C69A8 /* ImageCacheSerializer.swift in Sources */,
|
||||
D036EBB8259FE29800EC1CFC /* Status+Extensions.swift in Sources */,
|
||||
D021A6A625C3E584008A0C0D /* EditAttachmentView.swift in Sources */,
|
||||
D0D93ED925D9CBE200C622ED /* AutocompleteItemCollectionViewCell.swift in Sources */,
|
||||
|
@ -1241,9 +1237,9 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D035D90325E4388800E597C9 /* ImageDiskCache.swift in Sources */,
|
||||
D0E5361C24E3EB4D00FB1CE1 /* NotificationService.swift in Sources */,
|
||||
D025B15B25C4EA7D001C69A8 /* ImageCacheConfiguration.swift in Sources */,
|
||||
D025B16025C4EA81001C69A8 /* ImageCacheSerializer.swift in Sources */,
|
||||
D059376125ABE2E800754FDF /* XMLUnescaper.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -1642,12 +1638,12 @@
|
|||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
D0F5880325A7E4C500E3A49C /* XCRemoteSwiftPackageReference "Kingfisher" */ = {
|
||||
D04F34B425E42ABE00714251 /* XCRemoteSwiftPackageReference "SDWebImage" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/onevcat/Kingfisher";
|
||||
repositoryURL = "https://github.com/SDWebImage/SDWebImage";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 6.1.0;
|
||||
minimumVersion = 5.10.4;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
@ -1657,10 +1653,20 @@
|
|||
isa = XCSwiftPackageProductDependency;
|
||||
productName = ServiceLayer;
|
||||
};
|
||||
D025B16F25C4EB58001C69A8 /* Kingfisher */ = {
|
||||
D04F34B525E42ABE00714251 /* SDWebImage */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = D0F5880325A7E4C500E3A49C /* XCRemoteSwiftPackageReference "Kingfisher" */;
|
||||
productName = Kingfisher;
|
||||
package = D04F34B425E42ABE00714251 /* XCRemoteSwiftPackageReference "SDWebImage" */;
|
||||
productName = SDWebImage;
|
||||
};
|
||||
D04F34BB25E42ADC00714251 /* SDWebImage */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = D04F34B425E42ABE00714251 /* XCRemoteSwiftPackageReference "SDWebImage" */;
|
||||
productName = SDWebImage;
|
||||
};
|
||||
D04F34C125E42AE500714251 /* SDWebImage */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = D04F34B425E42ABE00714251 /* XCRemoteSwiftPackageReference "SDWebImage" */;
|
||||
productName = SDWebImage;
|
||||
};
|
||||
D04F9E8D259E9C950081B0C9 /* ViewModels */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
|
@ -1670,16 +1676,6 @@
|
|||
isa = XCSwiftPackageProductDependency;
|
||||
productName = ViewModels;
|
||||
};
|
||||
D0F5880425A7E4C500E3A49C /* Kingfisher */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = D0F5880325A7E4C500E3A49C /* XCRemoteSwiftPackageReference "Kingfisher" */;
|
||||
productName = Kingfisher;
|
||||
};
|
||||
D0F5880E25A7E6CC00E3A49C /* Kingfisher */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = D0F5880325A7E4C500E3A49C /* XCRemoteSwiftPackageReference "Kingfisher" */;
|
||||
productName = Kingfisher;
|
||||
};
|
||||
D0FE7C7F25C4C79F00203957 /* PreviewViewModels */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = PreviewViewModels;
|
||||
|
|
|
@ -20,12 +20,12 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"package": "Kingfisher",
|
||||
"repositoryURL": "https://github.com/onevcat/Kingfisher",
|
||||
"package": "SDWebImage",
|
||||
"repositoryURL": "https://github.com/SDWebImage/SDWebImage",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "daebf8ddf974164d1b9a050c8231e263f3106b09",
|
||||
"version": "6.1.0"
|
||||
"revision": "a6b6e44eadf0d39250c10a7cc0e3b91d0bdb0e94",
|
||||
"version": "5.10.4"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import Mastodon
|
||||
import SDWebImage
|
||||
import ServiceLayer
|
||||
import UserNotifications
|
||||
|
||||
final class NotificationService: UNNotificationServiceExtension {
|
||||
private let environment = AppEnvironment.live(
|
||||
userNotificationCenter: .current(),
|
||||
reduceMotion: { false })
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
try? ImageCacheConfiguration(environment: Self.environment).configure()
|
||||
}
|
||||
|
||||
var contentHandler: ((UNNotificationContent) -> Void)?
|
||||
|
@ -25,7 +23,7 @@ final class NotificationService: UNNotificationServiceExtension {
|
|||
|
||||
guard let bestAttemptContent = bestAttemptContent else { return }
|
||||
|
||||
let parsingService = PushNotificationParsingService(environment: environment)
|
||||
let parsingService = PushNotificationParsingService(environment: Self.environment)
|
||||
let decryptedJSON: Data
|
||||
let identityId: Identity.Id
|
||||
let pushNotification: PushNotification
|
||||
|
@ -43,14 +41,14 @@ final class NotificationService: UNNotificationServiceExtension {
|
|||
bestAttemptContent.title = pushNotification.title
|
||||
bestAttemptContent.body = XMLUnescaper(string: pushNotification.body).unescape()
|
||||
|
||||
let appPreferences = AppPreferences(environment: environment)
|
||||
let appPreferences = AppPreferences(environment: Self.environment)
|
||||
|
||||
if appPreferences.notificationSounds.contains(pushNotification.notificationType) {
|
||||
bestAttemptContent.sound = .default
|
||||
}
|
||||
|
||||
if appPreferences.notificationAccountName,
|
||||
let accountName = try? AllIdentitiesService(environment: environment).identity(id: identityId)?.handle {
|
||||
let accountName = try? AllIdentitiesService(environment: Self.environment).identity(id: identityId)?.handle {
|
||||
bestAttemptContent.subtitle = accountName
|
||||
}
|
||||
|
||||
|
@ -71,6 +69,10 @@ final class NotificationService: UNNotificationServiceExtension {
|
|||
}
|
||||
|
||||
private extension NotificationService {
|
||||
private static let environment = AppEnvironment.live(
|
||||
userNotificationCenter: .current(),
|
||||
reduceMotion: { false })
|
||||
|
||||
static func addImage(url: URL,
|
||||
bestAttemptContent: UNMutableNotificationContent,
|
||||
contentHandler: @escaping (UNNotificationContent) -> Void) {
|
||||
|
@ -78,31 +80,17 @@ private extension NotificationService {
|
|||
let fileURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
|
||||
.appendingPathComponent(fileName)
|
||||
|
||||
KingfisherManager.shared.retrieveImage(with: url) {
|
||||
switch $0 {
|
||||
case let .success(result):
|
||||
let format: ImageFormat
|
||||
|
||||
switch fileURL.pathExtension.lowercased() {
|
||||
case "jpg", "jpeg":
|
||||
format = .JPEG
|
||||
case "gif":
|
||||
format = .GIF
|
||||
case "png":
|
||||
format = .PNG
|
||||
default:
|
||||
format = .unknown
|
||||
}
|
||||
|
||||
SDWebImageManager.shared.loadImage(with: url, options: [], progress: nil) { _, data, _, _, _, _ in
|
||||
if let data = data {
|
||||
do {
|
||||
try result.image.kf.data(format: format)?.write(to: fileURL)
|
||||
try data.write(to: fileURL)
|
||||
bestAttemptContent.attachments =
|
||||
[try UNNotificationAttachment(identifier: fileName, url: fileURL)]
|
||||
contentHandler(bestAttemptContent)
|
||||
} catch {
|
||||
contentHandler(bestAttemptContent)
|
||||
}
|
||||
case .failure:
|
||||
} else {
|
||||
contentHandler(bestAttemptContent)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Base16
|
||||
import CryptoKit
|
||||
import Foundation
|
||||
import Secrets
|
||||
|
@ -20,4 +21,8 @@ public extension ImageSerializationService {
|
|||
func deserialize(data: Data) throws -> Data {
|
||||
try ChaChaPoly.open(.init(combined: data), using: key)
|
||||
}
|
||||
|
||||
func cacheKey(forKey key: String) -> String {
|
||||
Data(SHA256.hash(data: Data(key.utf8))).base16EncodedString()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import AVKit
|
||||
import Kingfisher
|
||||
import ServiceLayer
|
||||
import SwiftUI
|
||||
import ViewModels
|
||||
|
@ -30,9 +29,4 @@ private extension MetatextApp {
|
|||
static let environment = AppEnvironment.live(
|
||||
userNotificationCenter: .current(),
|
||||
reduceMotion: { UIAccessibility.isReduceMotionEnabled })
|
||||
static let imageCacheName = "Images"
|
||||
static let imageCacheDirectoryURL = FileManager.default.containerURL(
|
||||
forSecurityApplicationGroupIdentifier: AppEnvironment.appGroup)?
|
||||
.appendingPathComponent("Library")
|
||||
.appendingPathComponent("Caches")
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Combine
|
||||
import Kingfisher
|
||||
import Mastodon
|
||||
import SafariServices
|
||||
import SDWebImage
|
||||
import SwiftUI
|
||||
import ViewModels
|
||||
|
||||
|
@ -18,7 +18,7 @@ final class AddIdentityViewController: UIViewController {
|
|||
private let welcomeLabel = UILabel()
|
||||
private let instanceAndButtonsStackView = UIStackView()
|
||||
private let instanceStackView = UIStackView()
|
||||
private let instanceImageView = AnimatedImageView()
|
||||
private let instanceImageView = SDAnimatedImageView()
|
||||
private let instanceTitleLabel = UILabel()
|
||||
private let instanceURLLabel = UILabel()
|
||||
private let buttonsStackView = UIStackView()
|
||||
|
@ -110,7 +110,7 @@ private extension AddIdentityViewController {
|
|||
instanceImageView.contentMode = .scaleAspectFill
|
||||
instanceImageView.layer.cornerRadius = .defaultCornerRadius
|
||||
instanceImageView.clipsToBounds = true
|
||||
instanceImageView.kf.indicatorType = .activity
|
||||
instanceImageView.sd_imageIndicator = SDWebImageActivityIndicator.large
|
||||
|
||||
buttonsStackView.axis = .vertical
|
||||
buttonsStackView.spacing = .defaultSpacing
|
||||
|
@ -259,7 +259,7 @@ private extension AddIdentityViewController {
|
|||
if let instance = instance {
|
||||
self.instanceTitleLabel.text = instance.title
|
||||
self.instanceURLLabel.text = instance.uri
|
||||
self.instanceImageView.kf.setImage(with: instance.thumbnail)
|
||||
self.instanceImageView.sd_setImage(with: instance.thumbnail)
|
||||
self.instanceStackView.isHidden_stackViewSafe = false
|
||||
|
||||
if instance.registrations {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import AVFoundation
|
||||
import Kingfisher
|
||||
import Mastodon
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
import ViewModels
|
||||
|
||||
final class ImageViewController: UIViewController {
|
||||
let scrollView = UIScrollView()
|
||||
let imageView = AnimatedImageView()
|
||||
let imageView = SDAnimatedImageView()
|
||||
let playerView = PlayerView()
|
||||
|
||||
private let viewModel: AttachmentViewModel?
|
||||
|
@ -55,7 +55,8 @@ final class ImageViewController: UIViewController {
|
|||
contentView.addSubview(imageView)
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.contentMode = .scaleAspectFit
|
||||
imageView.kf.indicatorType = .activity
|
||||
imageView.sd_imageIndicator = SDWebImageActivityIndicator.large
|
||||
imageView.autoPlayAnimatedImage = false
|
||||
|
||||
contentView.addSubview(playerView)
|
||||
playerView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
@ -109,20 +110,11 @@ final class ImageViewController: UIViewController {
|
|||
case .image:
|
||||
imageView.tag = viewModel.tag
|
||||
playerView.isHidden = true
|
||||
imageView.kf.setImage(
|
||||
with: viewModel.attachment.previewUrl,
|
||||
options: [.onlyFromCache],
|
||||
completionHandler: { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
if case .success = $0 {
|
||||
self.imageView.kf.indicatorType = .none
|
||||
}
|
||||
let placeholderKey = viewModel.attachment.previewUrl?.absoluteString
|
||||
let placeholderImage = SDImageCache.shared.imageFromCache(forKey: placeholderKey)
|
||||
|
||||
self.imageView.kf.setImage(
|
||||
with: viewModel.attachment.url,
|
||||
options: [.keepCurrentImageWhileLoading])
|
||||
})
|
||||
imageView.sd_setImage(with: viewModel.attachment.url, placeholderImage: placeholderImage)
|
||||
case .gifv:
|
||||
playerView.tag = viewModel.tag
|
||||
imageView.isHidden = true
|
||||
|
@ -143,7 +135,7 @@ final class ImageViewController: UIViewController {
|
|||
} else if let imageURL = imageURL {
|
||||
imageView.tag = imageURL.hashValue
|
||||
playerView.isHidden = true
|
||||
imageView.kf.setImage(with: imageURL)
|
||||
imageView.sd_setImage(with: imageURL)
|
||||
}
|
||||
|
||||
contentView.accessibilityLabel = viewModel?.attachment.type.accessibilityName
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
import AVFoundation
|
||||
import Combine
|
||||
import Kingfisher
|
||||
import PhotosUI
|
||||
import SwiftUI
|
||||
import UniformTypeIdentifiers
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
import AVKit
|
||||
import Combine
|
||||
import Kingfisher
|
||||
import Mastodon
|
||||
import SafariServices
|
||||
import SDWebImage
|
||||
import SwiftUI
|
||||
import ViewModels
|
||||
|
||||
|
@ -280,13 +280,8 @@ extension TableViewController: UITableViewDataSourcePrefetching {
|
|||
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
|
||||
let urls = indexPaths.compactMap(dataSource.itemIdentifier(for:))
|
||||
.reduce(Set<URL>()) { $0.union($1.mediaPrefetchURLs(identityContext: viewModel.identityContext)) }
|
||||
var imageOptions = KingfisherManager.shared.defaultOptions
|
||||
|
||||
imageOptions.append(.requestModifier(PrefetchRequestModifier()))
|
||||
|
||||
for url in urls {
|
||||
KingfisherManager.shared.retrieveImage(with: url, completionHandler: nil)
|
||||
}
|
||||
SDWebImagePrefetcher.shared.prefetchURLs(Array(urls))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import SwiftUI
|
||||
import ViewModels
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import SwiftUI
|
||||
import ViewModels
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import SwiftUI
|
||||
import ViewModels
|
||||
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
import ViewModels
|
||||
|
||||
// swiftlint:disable file_length
|
||||
final class AccountHeaderView: UIView {
|
||||
let headerImageBackgroundView = UIView()
|
||||
let headerImageView = AnimatedImageView()
|
||||
let headerImageView = SDAnimatedImageView()
|
||||
let headerButton = UIButton()
|
||||
let avatarBackgroundView = UIView()
|
||||
let avatarImageView = AnimatedImageView()
|
||||
let avatarImageView = SDAnimatedImageView()
|
||||
let avatarButton = UIButton()
|
||||
let relationshipButtonsStackView = UIStackView()
|
||||
let followButton = UIButton(type: .system)
|
||||
|
@ -37,8 +37,8 @@ final class AccountHeaderView: UIView {
|
|||
var viewModel: ProfileViewModel {
|
||||
didSet {
|
||||
if let accountViewModel = viewModel.accountViewModel {
|
||||
headerImageView.kf.setImage(with: accountViewModel.headerURL) { [weak self] in
|
||||
if case let .success(result) = $0, result.image.size != Self.missingHeaderImageSize {
|
||||
headerImageView.sd_setImage(with: accountViewModel.headerURL) { [weak self] image, _, _, _ in
|
||||
if let image = image, image.size != Self.missingHeaderImageSize {
|
||||
self?.headerButton.isEnabled = true
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ final class AccountHeaderView: UIView {
|
|||
headerButton.accessibilityLabel = String.localizedStringWithFormat(
|
||||
NSLocalizedString("account.header.accessibility-label-%@", comment: ""),
|
||||
accountViewModel.displayName)
|
||||
avatarImageView.kf.setImage(with: accountViewModel.avatarURL(profile: true))
|
||||
avatarImageView.sd_setImage(with: accountViewModel.avatarURL(profile: true))
|
||||
avatarImageView.tag = accountViewModel.avatarURL(profile: true).hashValue
|
||||
avatarButton.accessibilityLabel = String.localizedStringWithFormat(
|
||||
NSLocalizedString("account.avatar.accessibility-label-%@", comment: ""),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
|
||||
final class AnimatedAttachmentLabel: UILabel, EmojiInsertable {
|
||||
|
@ -18,7 +18,7 @@ final class AnimatedAttachmentLabel: UILabel, EmojiInsertable {
|
|||
|
||||
guard let attributedText = attributedText else { return }
|
||||
|
||||
var attachmentImageViews = Set<AnimatedImageView>()
|
||||
var attachmentImageViews = Set<SDAnimatedImageView>()
|
||||
|
||||
attributedText.enumerateAttribute(
|
||||
.attachment,
|
||||
|
@ -29,7 +29,7 @@ final class AnimatedAttachmentLabel: UILabel, EmojiInsertable {
|
|||
}
|
||||
|
||||
for subview in subviews {
|
||||
guard let attachmentImageView = subview as? AnimatedImageView else { continue }
|
||||
guard let attachmentImageView = subview as? SDAnimatedImageView else { continue }
|
||||
|
||||
if !attachmentImageViews.contains(attachmentImageView) {
|
||||
attachmentImageView.removeFromSuperview()
|
||||
|
@ -49,6 +49,7 @@ final class AnimatedAttachmentLabel: UILabel, EmojiInsertable {
|
|||
animatedAttachment.imageView.image = animatedAttachment.image
|
||||
animatedAttachment.imageView.contentMode = .scaleAspectFit
|
||||
animatedAttachment.imageView.center.y = center.y
|
||||
animatedAttachment.imageView.sd_setImage(with: animatedAttachment.imageURL)
|
||||
|
||||
if animatedAttachment.imageView.superview != self {
|
||||
addSubview(animatedAttachment.imageView)
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
|
||||
final class AnimatedTextAttachment: NSTextAttachment {
|
||||
var imageView = AnimatedImageView()
|
||||
var imageURL: URL?
|
||||
var imageView = SDAnimatedImageView()
|
||||
var imageBounds: CGRect?
|
||||
|
||||
override func image(forBounds imageBounds: CGRect,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
|
||||
final class AnimatingLayoutManager: NSLayoutManager {
|
||||
|
@ -13,7 +13,7 @@ final class AnimatingLayoutManager: NSLayoutManager {
|
|||
return
|
||||
}
|
||||
|
||||
var attachmentImageViews = Set<AnimatedImageView>()
|
||||
var attachmentImageViews = Set<SDAnimatedImageView>()
|
||||
|
||||
textStorage.enumerateAttribute(
|
||||
.attachment,
|
||||
|
@ -24,7 +24,7 @@ final class AnimatingLayoutManager: NSLayoutManager {
|
|||
}
|
||||
|
||||
for subview in view?.subviews ?? [] {
|
||||
guard let attachmentImageView = subview as? AnimatedImageView else { continue }
|
||||
guard let attachmentImageView = subview as? SDAnimatedImageView else { continue }
|
||||
|
||||
if !attachmentImageViews.contains(attachmentImageView) {
|
||||
attachmentImageView.removeFromSuperview()
|
||||
|
@ -42,6 +42,7 @@ final class AnimatingLayoutManager: NSLayoutManager {
|
|||
animatedAttachment.imageView.frame = boundingRect(forGlyphRange: range, in: textContainer)
|
||||
animatedAttachment.imageView.image = animatedAttachment.image
|
||||
animatedAttachment.imageView.contentMode = .scaleAspectFit
|
||||
animatedAttachment.imageView.sd_setImage(with: animatedAttachment.imageURL)
|
||||
|
||||
if animatedAttachment.imageView.superview != view {
|
||||
view?.addSubview(animatedAttachment.imageView)
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
import AVKit
|
||||
import Combine
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
import ViewModels
|
||||
|
||||
final class AttachmentView: UIView {
|
||||
let playerView = PlayerView()
|
||||
let imageView = AnimatedImageView()
|
||||
let imageView = SDAnimatedImageView()
|
||||
let removeButton = UIButton(type: .close)
|
||||
let editIcon = UIImageView()
|
||||
let selectionButton = UIButton()
|
||||
|
@ -105,6 +105,7 @@ private extension AttachmentView {
|
|||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.contentMode = .scaleAspectFill
|
||||
imageView.clipsToBounds = true
|
||||
imageView.autoPlayAnimatedImage = false
|
||||
imageView.tag = viewModel.tag
|
||||
|
||||
let blurEffect = UIBlurEffect(style: .systemUltraThinMaterial)
|
||||
|
@ -168,11 +169,9 @@ private extension AttachmentView {
|
|||
|
||||
switch viewModel.attachment.type {
|
||||
case .image, .video, .gifv:
|
||||
imageView.kf.setImage(
|
||||
with: viewModel.attachment.previewUrl,
|
||||
completionHandler: { [weak self] _ in
|
||||
self?.layoutSubviews()
|
||||
})
|
||||
imageView.sd_setImage(with: viewModel.attachment.previewUrl) { [weak self] _, _, _, _ in
|
||||
self?.layoutSubviews()
|
||||
}
|
||||
case .audio:
|
||||
playImageView.image = UIImage(systemName: "waveform.circle",
|
||||
withConfiguration: UIImage.SymbolConfiguration(textStyle: .largeTitle))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import Mastodon
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
import ViewModels
|
||||
|
||||
|
@ -20,7 +20,7 @@ final class CardView: UIView {
|
|||
.appendingWithSeparator(viewModel.title)
|
||||
|
||||
imageView.isHidden = viewModel.imageURL == nil
|
||||
imageView.kf.setImage(with: viewModel.imageURL)
|
||||
imageView.sd_setImage(with: viewModel.imageURL)
|
||||
|
||||
titleLabel.text = viewModel.title
|
||||
descriptionLabel.text = viewModel.description
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Combine
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
import ViewModels
|
||||
|
||||
final class CompositionView: UIView {
|
||||
let avatarImageView = AnimatedImageView()
|
||||
let avatarImageView = SDAnimatedImageView()
|
||||
let changeIdentityButton = UIButton()
|
||||
let spoilerTextField = UITextField()
|
||||
let textView = ImagePastableTextView()
|
||||
|
@ -199,7 +199,7 @@ private extension CompositionView {
|
|||
? $0.identity.account?.avatar
|
||||
: $0.identity.account?.avatarStatic
|
||||
|
||||
self.avatarImageView.kf.setImage(with: avatarURL)
|
||||
self.avatarImageView.sd_setImage(with: avatarURL)
|
||||
self.changeIdentityButton.accessibilityLabel = $0.identity.handle
|
||||
self.changeIdentityButton.accessibilityHint =
|
||||
NSLocalizedString("compose.change-identity-button.accessibility-hint", comment: "")
|
||||
|
@ -290,10 +290,11 @@ private extension CompositionView {
|
|||
}
|
||||
|
||||
func changeIdentityMenu(identities: [Identity]) -> UIMenu {
|
||||
let processor = RoundCornerImageProcessor(radius: .widthFraction(0.5))
|
||||
var imageOptions = KingfisherManager.shared.defaultOptions
|
||||
|
||||
imageOptions.append(.processor(processor))
|
||||
let imageTransformer = SDImageRoundCornerTransformer(
|
||||
radius: .greatestFiniteMagnitude,
|
||||
corners: .allCorners,
|
||||
borderWidth: 0,
|
||||
borderColor: nil)
|
||||
|
||||
return UIMenu(children: identities.map { identity in
|
||||
UIDeferredMenuElement { completion in
|
||||
|
@ -302,10 +303,12 @@ private extension CompositionView {
|
|||
}
|
||||
|
||||
if let image = identity.image {
|
||||
KingfisherManager.shared.retrieveImage(with: image, options: imageOptions) {
|
||||
if case let .success(value) = $0 {
|
||||
action.image = value.image
|
||||
}
|
||||
SDWebImageManager.shared.loadImage(
|
||||
with: image,
|
||||
options: [.transformAnimatedImage],
|
||||
context: [.imageTransformer: imageTransformer],
|
||||
progress: nil) { (image, _, _, _, _, _) in
|
||||
action.image = image
|
||||
|
||||
completion([action])
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
|
||||
final class EmojiView: UIView {
|
||||
private let imageView = AnimatedImageView()
|
||||
private let imageView = SDAnimatedImageView()
|
||||
private let emojiLabel = UILabel()
|
||||
private var emojiConfiguration: EmojiContentConfiguration
|
||||
|
||||
|
@ -74,7 +74,8 @@ private extension EmojiView {
|
|||
imageView.isHidden = false
|
||||
emojiLabel.isHidden = true
|
||||
|
||||
imageView.kf.setImage(with: emoji.url)
|
||||
// TODO: Use static URL if emoji animation preference is false
|
||||
imageView.sd_setImage(with: emoji.url)
|
||||
accessibilityLabel = emoji.shortcode
|
||||
} else {
|
||||
imageView.isHidden = true
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import Mastodon
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
import ViewModels
|
||||
|
||||
final class AccountView: UIView {
|
||||
let avatarImageView = AnimatedImageView()
|
||||
let avatarImageView = SDAnimatedImageView()
|
||||
let displayNameLabel = AnimatedAttachmentLabel()
|
||||
let accountLabel = UILabel()
|
||||
let noteTextView = TouchFallthroughTextView()
|
||||
|
@ -199,7 +199,7 @@ private extension AccountView {
|
|||
func applyAccountConfiguration() {
|
||||
let viewModel = accountConfiguration.viewModel
|
||||
|
||||
avatarImageView.kf.setImage(with: viewModel.avatarURL(profile: false))
|
||||
avatarImageView.sd_setImage(with: viewModel.avatarURL(profile: false))
|
||||
|
||||
let mutableDisplayName = NSMutableAttributedString(string: viewModel.displayName)
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
|
||||
final class AutocompleteItemView: UIView {
|
||||
private let imageView = AnimatedImageView()
|
||||
private let imageView = SDAnimatedImageView()
|
||||
private let primaryLabel = AnimatedAttachmentLabel()
|
||||
private let secondaryLabel = UILabel()
|
||||
private let stackView = UIStackView()
|
||||
|
@ -78,7 +78,7 @@ private extension AutocompleteItemView {
|
|||
? account.avatar
|
||||
: account.avatarStatic
|
||||
|
||||
imageView.kf.setImage(with: avatarURL)
|
||||
imageView.sd_setImage(with: avatarURL)
|
||||
imageView.isHidden = false
|
||||
|
||||
let mutableDisplayName = NSMutableAttributedString(string: account.displayName)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
|
||||
final class IdentityView: UIView {
|
||||
let imageView = AnimatedImageView()
|
||||
let imageView = SDAnimatedImageView()
|
||||
let nameLabel = AnimatedAttachmentLabel()
|
||||
let secondaryLabel = UILabel()
|
||||
|
||||
|
@ -84,7 +84,7 @@ private extension IdentityView {
|
|||
func applyIdentityConfiguration() {
|
||||
let viewModel = identityConfiguration.viewModel
|
||||
|
||||
imageView.kf.setImage(with: viewModel.identity.image)
|
||||
imageView.sd_setImage(with: viewModel.identity.image)
|
||||
imageView.autoPlayAnimatedImage = viewModel.identityContext.appPreferences.animateAvatars == .everywhere
|
||||
|
||||
if let displayName = viewModel.identity.account?.displayName,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
|
||||
final class InstanceView: UIView {
|
||||
private let imageView = AnimatedImageView()
|
||||
private let imageView = SDAnimatedImageView()
|
||||
private let titleLabel = UILabel()
|
||||
private let uriLabel = UILabel()
|
||||
private var instanceConfiguration: InstanceContentConfiguration
|
||||
|
@ -77,7 +77,8 @@ private extension InstanceView {
|
|||
func applyInstanceConfiguration() {
|
||||
let viewModel = instanceConfiguration.viewModel
|
||||
|
||||
imageView.kf.setImage(with: viewModel.instance.thumbnail)
|
||||
imageView.sd_setImage(with: viewModel.instance.thumbnail)
|
||||
imageView.autoPlayAnimatedImage = !UIAccessibility.isReduceMotionEnabled
|
||||
|
||||
titleLabel.text = viewModel.instance.title
|
||||
uriLabel.text = viewModel.instance.uri
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import Mastodon
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
import ViewModels
|
||||
|
||||
final class NotificationView: UIView {
|
||||
private let iconImageView = UIImageView()
|
||||
private let avatarImageView = AnimatedImageView()
|
||||
private let avatarImageView = SDAnimatedImageView()
|
||||
private let avatarButton = UIButton()
|
||||
private let typeLabel = AnimatedAttachmentLabel()
|
||||
private let timeLabel = UILabel()
|
||||
|
@ -166,7 +166,7 @@ private extension NotificationView {
|
|||
func applyNotificationConfiguration() {
|
||||
let viewModel = notificationConfiguration.viewModel
|
||||
|
||||
avatarImageView.kf.setImage(with: viewModel.accountViewModel.avatarURL())
|
||||
avatarImageView.sd_setImage(with: viewModel.accountViewModel.avatarURL())
|
||||
|
||||
switch viewModel.type {
|
||||
case .follow:
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
// swiftlint:disable file_length
|
||||
import Combine
|
||||
import Kingfisher
|
||||
import Mastodon
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
import ViewModels
|
||||
|
||||
final class StatusView: UIView {
|
||||
let avatarImageView = AnimatedImageView()
|
||||
let avatarImageView = SDAnimatedImageView()
|
||||
let avatarButton = UIButton()
|
||||
let infoIcon = UIImageView()
|
||||
let infoLabel = AnimatedAttachmentLabel()
|
||||
|
@ -417,7 +417,7 @@ private extension StatusView {
|
|||
|
||||
menuButton.menu = menu(viewModel: viewModel)
|
||||
|
||||
avatarImageView.kf.setImage(with: viewModel.avatarURL)
|
||||
avatarImageView.sd_setImage(with: viewModel.avatarURL)
|
||||
avatarButton.accessibilityLabel = String.localizedStringWithFormat(
|
||||
NSLocalizedString("account.avatar.accessibility-label-%@", comment: ""),
|
||||
viewModel.accountViewModel.displayName)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
import ViewModels
|
||||
|
||||
|
@ -23,11 +23,11 @@ final class ConversationAvatarsView: UIView {
|
|||
rightStackView.isHidden = accountCount == 1
|
||||
|
||||
for (index, accountViewModel) in accountViewModels.enumerated() {
|
||||
let imageView = AnimatedImageView()
|
||||
let imageView = SDAnimatedImageView()
|
||||
|
||||
imageView.contentMode = .scaleAspectFill
|
||||
imageView.clipsToBounds = true
|
||||
imageView.kf.setImage(with: accountViewModel.avatarURL())
|
||||
imageView.sd_setImage(with: accountViewModel.avatarURL())
|
||||
|
||||
if accountCount == 2 && index == 1
|
||||
|| accountCount == 3 && index != 0
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Combine
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
import ViewModels
|
||||
|
||||
final class EditThumbnailView: UIView {
|
||||
let playerView = PlayerView()
|
||||
let imageView = UIImageView()
|
||||
let previewImageView = UIImageView()
|
||||
let imageView = SDAnimatedImageView()
|
||||
let previewImageView = SDAnimatedImageView()
|
||||
let promptBackgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemChromeMaterial))
|
||||
let thumbnailPromptLabel = UILabel()
|
||||
|
||||
|
@ -94,7 +94,7 @@ private extension EditThumbnailView {
|
|||
addSubview(imageView)
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.contentMode = .scaleAspectFit
|
||||
imageView.kf.indicatorType = .activity
|
||||
imageView.sd_imageIndicator = SDWebImageActivityIndicator.large
|
||||
|
||||
addSubview(playerView)
|
||||
playerView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
@ -137,25 +137,16 @@ private extension EditThumbnailView {
|
|||
previewImageView.contentMode = .scaleAspectFill
|
||||
previewImageView.clipsToBounds = true
|
||||
previewImageView.layer.cornerRadius = .defaultCornerRadius
|
||||
previewImageView.kf.setImage(with: viewModel.attachment.previewUrl)
|
||||
previewImageView.sd_setImage(with: viewModel.attachment.previewUrl)
|
||||
|
||||
switch viewModel.attachment.type {
|
||||
case .image:
|
||||
playerView.isHidden = true
|
||||
imageView.kf.setImage(
|
||||
with: viewModel.attachment.previewUrl,
|
||||
options: [.onlyFromCache],
|
||||
completionHandler: { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
if case .success = $0 {
|
||||
self.imageView.kf.indicatorType = .none
|
||||
}
|
||||
let placeholderKey = viewModel.attachment.previewUrl?.absoluteString
|
||||
let placeholderImage = SDImageCache.shared.imageFromCache(forKey: placeholderKey)
|
||||
|
||||
self.imageView.kf.setImage(
|
||||
with: self.viewModel.attachment.url,
|
||||
options: [.keepCurrentImageWhileLoading])
|
||||
})
|
||||
imageView.sd_setImage(with: viewModel.attachment.url, placeholderImage: placeholderImage)
|
||||
case .gifv:
|
||||
imageView.isHidden = true
|
||||
let player = PlayerCache.shared.player(url: viewModel.attachment.url)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Combine
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
import ViewModels
|
||||
|
||||
|
@ -28,17 +28,18 @@ final class SecondaryNavigationButton: UIBarButtonItem {
|
|||
])
|
||||
|
||||
viewModel.identityContext.$identity.sink {
|
||||
button.kf.setImage(
|
||||
button.sd_setImage(
|
||||
with: $0.image,
|
||||
for: .normal,
|
||||
placeholder: UIImage(systemName: "line.horizontal.3"))
|
||||
placeholderImage: UIImage(systemName: "line.horizontal.3"))
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
let processor = RoundCornerImageProcessor(radius: .widthFraction(0.5))
|
||||
var imageOptions = KingfisherManager.shared.defaultOptions
|
||||
|
||||
imageOptions.append(.processor(processor))
|
||||
let imageTransformer = SDImageRoundCornerTransformer(
|
||||
radius: .greatestFiniteMagnitude,
|
||||
corners: .allCorners,
|
||||
borderWidth: 0,
|
||||
borderColor: nil)
|
||||
|
||||
viewModel.$recentIdentities.sink { identities in
|
||||
button.menu = UIMenu(children: identities.map { identity in
|
||||
|
@ -48,10 +49,12 @@ final class SecondaryNavigationButton: UIBarButtonItem {
|
|||
}
|
||||
|
||||
if let image = identity.image {
|
||||
KingfisherManager.shared.retrieveImage(with: image, options: imageOptions) {
|
||||
if case let .success(value) = $0 {
|
||||
action.image = value.image
|
||||
}
|
||||
SDWebImageManager.shared.loadImage(
|
||||
with: image,
|
||||
options: [.transformAnimatedImage],
|
||||
context: [.imageTransformer: imageTransformer],
|
||||
progress: nil) { (image, _, _, _, _, _) in
|
||||
action.image = image
|
||||
|
||||
completion([action])
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Kingfisher
|
||||
import SDWebImage
|
||||
import UIKit
|
||||
import ViewModels
|
||||
|
||||
final class SecondaryNavigationTitleView: UIView {
|
||||
private let viewModel: NavigationViewModel
|
||||
private let avatarImageView = AnimatedImageView()
|
||||
private let avatarImageView = SDAnimatedImageView()
|
||||
private let displayNameLabel = AnimatedAttachmentLabel()
|
||||
private let accountLabel = UILabel()
|
||||
private let stackView = UIStackView()
|
||||
|
@ -70,7 +70,7 @@ private extension SecondaryNavigationTitleView {
|
|||
? viewModel.identityContext.identity.account?.avatar
|
||||
: viewModel.identityContext.identity.account?.avatarStatic
|
||||
|
||||
avatarImageView.kf.setImage(with: avatarURL)
|
||||
avatarImageView.sd_setImage(with: avatarURL)
|
||||
|
||||
if let displayName = viewModel.identityContext.identity.account?.displayName,
|
||||
!displayName.isEmpty {
|
||||
|
|
Loading…
Reference in a new issue