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