Add blurhash support for main status image.
This commit is contained in:
parent
8a5552b21a
commit
68351897b0
|
@ -53,6 +53,7 @@
|
|||
F86B7214296BFDCE00EE59EC /* UserProfileHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = F86B7213296BFDCE00EE59EC /* UserProfileHeader.swift */; };
|
||||
F86B7216296BFFDA00EE59EC /* UserProfileStatuses.swift in Sources */ = {isa = PBXBuildFile; fileRef = F86B7215296BFFDA00EE59EC /* UserProfileStatuses.swift */; };
|
||||
F86B7218296C27C100EE59EC /* ActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F86B7217296C27C100EE59EC /* ActionButton.swift */; };
|
||||
F86B721C296C394000EE59EC /* Status+ImageSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = F86B721B296C394000EE59EC /* Status+ImageSize.swift */; };
|
||||
F88ABD9229686F1C004EF61E /* MemoryCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88ABD9129686F1C004EF61E /* MemoryCache.swift */; };
|
||||
F88ABD9429687CA4004EF61E /* ComposeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88ABD9329687CA4004EF61E /* ComposeView.swift */; };
|
||||
F88C246C295C37B80006098B /* VernissageApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88C246B295C37B80006098B /* VernissageApp.swift */; };
|
||||
|
@ -129,6 +130,7 @@
|
|||
F86B7213296BFDCE00EE59EC /* UserProfileHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileHeader.swift; sourceTree = "<group>"; };
|
||||
F86B7215296BFFDA00EE59EC /* UserProfileStatuses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileStatuses.swift; sourceTree = "<group>"; };
|
||||
F86B7217296C27C100EE59EC /* ActionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionButton.swift; sourceTree = "<group>"; };
|
||||
F86B721B296C394000EE59EC /* Status+ImageSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Status+ImageSize.swift"; sourceTree = "<group>"; };
|
||||
F88ABD9129686F1C004EF61E /* MemoryCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryCache.swift; sourceTree = "<group>"; };
|
||||
F88ABD9329687CA4004EF61E /* ComposeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeView.swift; sourceTree = "<group>"; };
|
||||
F88ABD9529687D4D004EF61E /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||
|
@ -218,6 +220,7 @@
|
|||
F8210DE62966E1D1001D9973 /* Color+Assets.swift */,
|
||||
F8C14393296AF21B001FE31D /* Double+Round.swift */,
|
||||
F8984E4C296B648000A2610F /* UIImage+Blurhash.swift */,
|
||||
F86B721B296C394000EE59EC /* Status+ImageSize.swift */,
|
||||
);
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
|
@ -456,6 +459,7 @@
|
|||
F80048082961E6DE00E6868A /* StatusDataHandler.swift in Sources */,
|
||||
F866F6A0296040A8002E8F88 /* ApplicationSettings+CoreDataClass.swift in Sources */,
|
||||
F8210DEA2966E4F9001D9973 /* AnimatePlaceholderModifier.swift in Sources */,
|
||||
F86B721C296C394000EE59EC /* Status+ImageSize.swift in Sources */,
|
||||
F8984E4D296B648000A2610F /* UIImage+Blurhash.swift in Sources */,
|
||||
F897978A2968314A00B22335 /* LoadingIndicator.swift in Sources */,
|
||||
F8210DE52966E160001D9973 /* Color+SystemColors.swift in Sources */,
|
||||
|
|
|
@ -17,5 +17,13 @@ extension AttachmentData {
|
|||
self.remoteUrl = attachment.remoteUrl
|
||||
self.text = attachment.description
|
||||
self.type = attachment.type.rawValue
|
||||
|
||||
if let width = (attachment.meta as? ImageMetadata)?.original?.width {
|
||||
self.metaImageWidth = Int32(width)
|
||||
}
|
||||
|
||||
if let height = (attachment.meta as? ImageMetadata)?.original?.height {
|
||||
self.metaImageHeight = Int32(height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,12 @@
|
|||
// Licensed under the MIT License.
|
||||
//
|
||||
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
|
||||
extension AttachmentData {
|
||||
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<AttachmentData> {
|
||||
|
@ -15,6 +18,10 @@ extension AttachmentData {
|
|||
|
||||
@NSManaged public var blurhash: String?
|
||||
@NSManaged public var data: Data
|
||||
@NSManaged public var exifCamera: String?
|
||||
@NSManaged public var exifCreatedDate: String?
|
||||
@NSManaged public var exifExposure: String?
|
||||
@NSManaged public var exifLens: String?
|
||||
@NSManaged public var id: String
|
||||
@NSManaged public var previewUrl: URL?
|
||||
@NSManaged public var remoteUrl: URL?
|
||||
|
@ -22,13 +29,12 @@ extension AttachmentData {
|
|||
@NSManaged public var text: String?
|
||||
@NSManaged public var type: String
|
||||
@NSManaged public var url: URL
|
||||
@NSManaged public var exifCamera: String?
|
||||
@NSManaged public var exifLens: String?
|
||||
@NSManaged public var exifExposure: String?
|
||||
@NSManaged public var exifCreatedDate: String?
|
||||
@NSManaged public var metaImageWidth: Int32
|
||||
@NSManaged public var metaImageHeight: Int32
|
||||
@NSManaged public var statusRelation: StatusData?
|
||||
|
||||
}
|
||||
|
||||
extension AttachmentData : Identifiable {
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// https://mczachurski.dev
|
||||
// Copyright © 2023 Marcin Czachurski and the repository contributors.
|
||||
// Licensed under the MIT License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import MastodonSwift
|
||||
|
||||
extension Status {
|
||||
public func getImageWidth() -> Int32? {
|
||||
if let width = (self.mediaAttachments.first?.meta as? ImageMetadata)?.original?.width {
|
||||
return Int32(width)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public func getImageHeight() -> Int32? {
|
||||
if let height = (self.mediaAttachments.first?.meta as? ImageMetadata)?.original?.height {
|
||||
return Int32(height)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,6 +32,8 @@
|
|||
<attribute name="exifExposure" optional="YES" attributeType="String"/>
|
||||
<attribute name="exifLens" optional="YES" attributeType="String"/>
|
||||
<attribute name="id" attributeType="String"/>
|
||||
<attribute name="metaImageHeight" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="metaImageWidth" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="previewUrl" optional="YES" attributeType="URI"/>
|
||||
<attribute name="remoteUrl" optional="YES" attributeType="URI"/>
|
||||
<attribute name="statusId" attributeType="String"/>
|
||||
|
|
|
@ -22,7 +22,10 @@ struct HomeFeedView: View {
|
|||
ScrollView {
|
||||
LazyVGrid(columns: gridColumns) {
|
||||
ForEach(dbStatuses, id: \.self) { item in
|
||||
NavigationLink(destination: StatusView(statusId: item.id)
|
||||
NavigationLink(destination: StatusView(statusId: item.id,
|
||||
imageBlurhash: item.attachments().first?.blurhash,
|
||||
imageWidth: item.attachments().first?.metaImageWidth,
|
||||
imageHeight: item.attachments().first?.metaImageHeight)
|
||||
.environmentObject(applicationState)) {
|
||||
ImageRow(attachments: item.attachments())
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@ import AVFoundation
|
|||
struct StatusView: View {
|
||||
@EnvironmentObject var applicationState: ApplicationState
|
||||
@State var statusId: String
|
||||
@State var imageBlurhash: String?
|
||||
@State var imageWidth: Int32?
|
||||
@State var imageHeight: Int32?
|
||||
|
||||
@State private var showCompose = false
|
||||
@State private var statusData: StatusData?
|
||||
|
@ -84,9 +87,16 @@ struct StatusView: View {
|
|||
}
|
||||
} else {
|
||||
VStack (alignment: .leading) {
|
||||
if let imageBlurhash, let uiImage = UIImage(blurHash: imageBlurhash, size: CGSize(width: 32, height: 32)) {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.frame(width: UIScreen.main.bounds.width, height: self.getImageHeight())
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(Color.placeholderText)
|
||||
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.width)
|
||||
.frame(width: UIScreen.main.bounds.width, height: self.getImageHeight())
|
||||
.redacted(reason: .placeholder)
|
||||
}
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
UsernameRow(accountDisplayName: "Verylong Displayname",
|
||||
|
@ -103,12 +113,13 @@ struct StatusView: View {
|
|||
LabelIcon(iconName: "camera.aperture", value: "Viltrox 24mm F1.8 E")
|
||||
LabelIcon(iconName: "timelapse", value: "24.0 mm, f/1.8, 1/640s, ISO 100")
|
||||
LabelIcon(iconName: "calendar", value: "2 Oct 2022")
|
||||
}.padding(8)
|
||||
}
|
||||
.padding(8)
|
||||
.redacted(reason: .placeholder)
|
||||
.animatePlaceholder(isLoading: .constant(true))
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationBarTitle("Details")
|
||||
.sheet(isPresented: $showCompose, content: {
|
||||
ComposeView()
|
||||
|
@ -143,6 +154,19 @@ struct StatusView: View {
|
|||
exifCreatedDate = attachmentData.exifCreatedDate
|
||||
exifLens = attachmentData.exifLens
|
||||
}
|
||||
|
||||
private func getImageHeight() -> Double {
|
||||
if let imageHeight = self.imageHeight, let imageWidth = self.imageWidth, imageHeight > 0 && imageWidth > 0 {
|
||||
return self.calculateHeight(width: Double(imageWidth), height: Double(imageHeight))
|
||||
}
|
||||
|
||||
return UIScreen.main.bounds.width * 0.75
|
||||
}
|
||||
|
||||
private func calculateHeight(width: Double, height: Double) -> CGFloat {
|
||||
let divider = width / UIScreen.main.bounds.size.width
|
||||
return height / divider
|
||||
}
|
||||
}
|
||||
|
||||
struct StatusView_Previews: PreviewProvider {
|
||||
|
|
|
@ -20,7 +20,10 @@ struct UserProfileStatuses: View {
|
|||
VStack(alignment: .center) {
|
||||
if firstLoadFinished == true {
|
||||
ForEach(self.statuses, id: \.id) { item in
|
||||
NavigationLink(destination: StatusView(statusId: item.id)
|
||||
NavigationLink(destination: StatusView(statusId: item.id,
|
||||
imageBlurhash: item.mediaAttachments.first?.blurhash,
|
||||
imageWidth: item.getImageWidth(),
|
||||
imageHeight: item.getImageHeight())
|
||||
.environmentObject(applicationState)) {
|
||||
ImageRowAsync(attachments: item.mediaAttachments)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue