Show individual attachments uncropped inline in statuses

This commit is contained in:
Shadowfacts 2022-12-25 14:13:59 -05:00
parent 15a7cd5f65
commit 16cd045588
9 changed files with 45 additions and 22 deletions

View File

@ -14,7 +14,7 @@ extension CollapseState {
func resolveFor(status: StatusMO, height: CGFloat, textLength: Int? = nil) { func resolveFor(status: StatusMO, height: CGFloat, textLength: Int? = nil) {
let longEnoughToCollapse: Bool let longEnoughToCollapse: Bool
if Preferences.shared.collapseLongPosts, if Preferences.shared.collapseLongPosts,
height > 500 || (textLength != nil && textLength! > 500) { height > 600 || (textLength != nil && textLength! > 500) {
longEnoughToCollapse = true longEnoughToCollapse = true
} else { } else {
longEnoughToCollapse = false longEnoughToCollapse = false

View File

@ -61,6 +61,7 @@ class Preferences: Codable, ObservableObject {
} }
self.blurMediaBehindContentWarning = try container.decodeIfPresent(Bool.self, forKey: .blurMediaBehindContentWarning) ?? true self.blurMediaBehindContentWarning = try container.decodeIfPresent(Bool.self, forKey: .blurMediaBehindContentWarning) ?? true
self.automaticallyPlayGifs = try container.decode(Bool.self, forKey: .automaticallyPlayGifs) self.automaticallyPlayGifs = try container.decode(Bool.self, forKey: .automaticallyPlayGifs)
self.showUncroppedMediaInline = try container.decodeIfPresent(Bool.self, forKey: .showUncroppedMediaInline) ?? true
self.openLinksInApps = try container.decode(Bool.self, forKey: .openLinksInApps) self.openLinksInApps = try container.decode(Bool.self, forKey: .openLinksInApps)
self.useInAppSafari = try container.decode(Bool.self, forKey: .useInAppSafari) self.useInAppSafari = try container.decode(Bool.self, forKey: .useInAppSafari)
@ -108,6 +109,7 @@ class Preferences: Codable, ObservableObject {
try container.encode(attachmentBlurMode, forKey: .attachmentBlurMode) try container.encode(attachmentBlurMode, forKey: .attachmentBlurMode)
try container.encode(blurMediaBehindContentWarning, forKey: .blurMediaBehindContentWarning) try container.encode(blurMediaBehindContentWarning, forKey: .blurMediaBehindContentWarning)
try container.encode(automaticallyPlayGifs, forKey: .automaticallyPlayGifs) try container.encode(automaticallyPlayGifs, forKey: .automaticallyPlayGifs)
try container.encode(showUncroppedMediaInline, forKey: .showUncroppedMediaInline)
try container.encode(openLinksInApps, forKey: .openLinksInApps) try container.encode(openLinksInApps, forKey: .openLinksInApps)
try container.encode(useInAppSafari, forKey: .useInAppSafari) try container.encode(useInAppSafari, forKey: .useInAppSafari)
@ -163,6 +165,7 @@ class Preferences: Codable, ObservableObject {
} }
@Published var blurMediaBehindContentWarning = true @Published var blurMediaBehindContentWarning = true
@Published var automaticallyPlayGifs = true @Published var automaticallyPlayGifs = true
@Published var showUncroppedMediaInline = true
// MARK: Behavior // MARK: Behavior
@Published var openLinksInApps = true @Published var openLinksInApps = true
@ -213,6 +216,7 @@ class Preferences: Codable, ObservableObject {
case attachmentBlurMode case attachmentBlurMode
case blurMediaBehindContentWarning case blurMediaBehindContentWarning
case automaticallyPlayGifs case automaticallyPlayGifs
case showUncroppedMediaInline
case openLinksInApps case openLinksInApps
case useInAppSafari case useInAppSafari

View File

@ -37,6 +37,10 @@ struct MediaPrefsView: View {
Toggle(isOn: $preferences.automaticallyPlayGifs) { Toggle(isOn: $preferences.automaticallyPlayGifs) {
Text("Automatically Play GIFs") Text("Automatically Play GIFs")
} }
Toggle(isOn: $preferences.showUncroppedMediaInline) {
Text("Show Uncropped Media Inline")
}
} }
} }
} }

View File

@ -141,17 +141,20 @@ class AttachmentView: GIFImageView {
} }
} }
private func blurHashSize() -> CGSize { var attachmentAspectRatio: CGFloat? {
if let meta = self.attachment.meta { if let meta = self.attachment.meta {
let aspectRatio: CGFloat
if let width = meta.width, let height = meta.height { if let width = meta.width, let height = meta.height {
aspectRatio = CGFloat(width) / CGFloat(height) return CGFloat(width) / CGFloat(height)
} else if let orig = meta.original, } else if let orig = meta.original,
let width = orig.width, let height = orig.height { let width = orig.width, let height = orig.height {
aspectRatio = CGFloat(width) / CGFloat(height) return CGFloat(width) / CGFloat(height)
} else {
return CGSize(width: 32, height: 32)
} }
}
return nil
}
private func blurHashSize() -> CGSize {
if let aspectRatio = attachmentAspectRatio {
if aspectRatio > 1 { if aspectRatio > 1 {
return CGSize(width: 32, height: 32 / aspectRatio) return CGSize(width: 32, height: 32 / aspectRatio)
} else { } else {

View File

@ -21,6 +21,7 @@ class AttachmentsContainerView: UIView {
let attachmentViews: NSHashTable<AttachmentView> = .weakObjects() let attachmentViews: NSHashTable<AttachmentView> = .weakObjects()
let attachmentStacks: NSHashTable<UIStackView> = .weakObjects() let attachmentStacks: NSHashTable<UIStackView> = .weakObjects()
var moreView: UIView? var moreView: UIView?
private var aspectRatioConstraint: NSLayoutConstraint?
var blurView: UIVisualEffectView? var blurView: UIVisualEffectView?
var hideButtonView: UIVisualEffectView? var hideButtonView: UIVisualEffectView?
@ -78,6 +79,8 @@ class AttachmentsContainerView: UIView {
if attachments.count > 0 { if attachments.count > 0 {
self.isHidden = false self.isHidden = false
var aspectRatio: CGFloat = 16/9
switch attachments.count { switch attachments.count {
case 1: case 1:
let attachmentView = createAttachmentView(index: 0, hSize: .full, vSize: .full) let attachmentView = createAttachmentView(index: 0, hSize: .full, vSize: .full)
@ -86,6 +89,9 @@ class AttachmentsContainerView: UIView {
fillView(attachmentView) fillView(attachmentView)
sendSubviewToBack(attachmentView) sendSubviewToBack(attachmentView)
accessibilityElements.append(attachmentView) accessibilityElements.append(attachmentView)
if let attachmentAspectRatio = attachmentView.attachmentAspectRatio {
aspectRatio = attachmentAspectRatio
}
case 2: case 2:
let left = createAttachmentView(index: 0, hSize: .half, vSize: .full) let left = createAttachmentView(index: 0, hSize: .half, vSize: .full)
left.layer.cornerRadius = 5 left.layer.cornerRadius = 5
@ -242,7 +248,19 @@ class AttachmentsContainerView: UIView {
accessibilityElements.append(topRight) accessibilityElements.append(topRight)
accessibilityElements.append(bottomLeft) accessibilityElements.append(bottomLeft)
accessibilityElements.append(moreView) accessibilityElements.append(moreView)
}
if Preferences.shared.showUncroppedMediaInline {
if aspectRatioConstraint?.multiplier != aspectRatio {
aspectRatioConstraint?.isActive = false
aspectRatioConstraint = widthAnchor.constraint(equalTo: heightAnchor, multiplier: aspectRatio)
aspectRatioConstraint!.isActive = true
}
} else {
if aspectRatioConstraint == nil {
aspectRatioConstraint = widthAnchor.constraint(equalTo: heightAnchor, multiplier: 16/9)
aspectRatioConstraint!.isActive = true
}
} }
} else { } else {
self.isHidden = true self.isHidden = true

View File

@ -104,9 +104,6 @@
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IF9-9U-Gk0" customClass="AttachmentsContainerView" customModule="Tusker" customModuleProvider="target"> <view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IF9-9U-Gk0" customClass="AttachmentsContainerView" customModule="Tusker" customModuleProvider="target">
<rect key="frame" x="0.0" y="128.5" width="343" height="0.0"/> <rect key="frame" x="0.0" y="128.5" width="343" height="0.0"/>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/> <color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" secondItem="IF9-9U-Gk0" secondAttribute="width" multiplier="9:16" priority="999" id="5oh-eK-J5d"/>
</constraints>
</view> </view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TLv-Xu-tT1" customClass="StatusPollView" customModule="Tusker" customModuleProvider="target"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TLv-Xu-tT1" customClass="StatusPollView" customModule="Tusker" customModuleProvider="target">
<rect key="frame" x="0.0" y="132.5" width="343" height="39.5"/> <rect key="frame" x="0.0" y="132.5" width="343" height="39.5"/>

View File

@ -107,7 +107,7 @@ extension StatusCollectionViewCell {
if statusState.unknown { if statusState.unknown {
// layout so that we can take the content height into consideration when deciding whether to collapse // layout so that we can take the content height into consideration when deciding whether to collapse
layoutIfNeeded() layoutIfNeeded()
statusState.resolveFor(status: status, height: contentContainer.contentTextView.bounds.height) statusState.resolveFor(status: status, height: contentContainer.visibleSubviewHeight)
if statusState.collapsible! && showStatusAutomatically { if statusState.collapsible! && showStatusAutomatically {
statusState.collapsed = false statusState.collapsed = false
} }

View File

@ -24,11 +24,7 @@ class StatusContentContainer: UIView {
]) ])
} }
let attachmentsView = AttachmentsContainerView().configure { let attachmentsView = AttachmentsContainerView()
NSLayoutConstraint.activate([
$0.heightAnchor.constraint(equalTo: $0.widthAnchor, multiplier: 9/16),
])
}
let pollView = StatusPollView() let pollView = StatusPollView()
@ -44,6 +40,10 @@ class StatusContentContainer: UIView {
private var isCollapsed = false private var isCollapsed = false
var visibleSubviewHeight: CGFloat {
subviews.filter { !$0.isHidden }.map(\.bounds.height).reduce(0, +)
}
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/> <device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@ -132,9 +132,6 @@
<view hidden="YES" contentMode="scaleToFill" verticalCompressionResistancePriority="1" translatesAutoresizingMaskIntoConstraints="NO" id="nbq-yr-2mA" customClass="AttachmentsContainerView" customModule="Tusker" customModuleProvider="target"> <view hidden="YES" contentMode="scaleToFill" verticalCompressionResistancePriority="1" translatesAutoresizingMaskIntoConstraints="NO" id="nbq-yr-2mA" customClass="AttachmentsContainerView" customModule="Tusker" customModuleProvider="target">
<rect key="frame" x="0.0" y="171.5" width="277" height="0.0"/> <rect key="frame" x="0.0" y="171.5" width="277" height="0.0"/>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/> <color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" secondItem="nbq-yr-2mA" secondAttribute="width" multiplier="9:16" priority="999" id="Rvt-zs-fkd"/>
</constraints>
</view> </view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="x3b-Zl-9F0" customClass="StatusPollView" customModule="Tusker" customModuleProvider="target"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="x3b-Zl-9F0" customClass="StatusPollView" customModule="Tusker" customModuleProvider="target">
<rect key="frame" x="0.0" y="173.5" width="277" height="0.0"/> <rect key="frame" x="0.0" y="173.5" width="277" height="0.0"/>