Add a compact style for status

This commit is contained in:
Thomas Ricouard 2023-01-07 17:44:25 +01:00
parent 785ea85297
commit 12fc8cd475
5 changed files with 42 additions and 16 deletions

View file

@ -34,6 +34,12 @@ struct DisplaySettingsView: View {
Text(buttonStyle.description).tag(buttonStyle) Text(buttonStyle.description).tag(buttonStyle)
} }
} }
Picker("Status media style", selection: $theme.statusDisplayStyle) {
ForEach(Theme.StatusDisplayStyle.allCases, id: \.rawValue) { buttonStyle in
Text(buttonStyle.description).tag(buttonStyle)
}
}
} }
.listRowBackground(theme.primaryBackgroundColor) .listRowBackground(theme.primaryBackgroundColor)

View file

@ -4,7 +4,7 @@ import SwiftUI
public class Theme: ObservableObject { public class Theme: ObservableObject {
enum ThemeKey: String { enum ThemeKey: String {
case colorScheme, tint, label, primaryBackground, secondaryBackground case colorScheme, tint, label, primaryBackground, secondaryBackground
case avatarPosition, avatarShape, statusActionsDisplay case avatarPosition, avatarShape, statusActionsDisplay, statusDisplayStyle
case selectedSet, selectedScheme case selectedSet, selectedScheme
} }
@ -49,6 +49,19 @@ public class Theme: ObservableObject {
} }
} }
public enum StatusDisplayStyle: String, CaseIterable {
case large, compact
public var description: LocalizedStringKey {
switch self {
case .large:
return "Large"
case .compact:
return "Compact"
}
}
}
@AppStorage("is_previously_set") private var isSet: Bool = false @AppStorage("is_previously_set") private var isSet: Bool = false
@AppStorage(ThemeKey.selectedScheme.rawValue) public var selectedScheme: ColorScheme = .dark @AppStorage(ThemeKey.selectedScheme.rawValue) public var selectedScheme: ColorScheme = .dark
@AppStorage(ThemeKey.tint.rawValue) public var tintColor: Color = .black @AppStorage(ThemeKey.tint.rawValue) public var tintColor: Color = .black
@ -59,6 +72,7 @@ public class Theme: ObservableObject {
@AppStorage(ThemeKey.avatarShape.rawValue) var rawAvatarShape: String = AvatarShape.rounded.rawValue @AppStorage(ThemeKey.avatarShape.rawValue) var rawAvatarShape: String = AvatarShape.rounded.rawValue
@AppStorage(ThemeKey.selectedSet.rawValue) var storedSet: ColorSetName = .iceCubeDark @AppStorage(ThemeKey.selectedSet.rawValue) var storedSet: ColorSetName = .iceCubeDark
@AppStorage(ThemeKey.statusActionsDisplay.rawValue) public var statusActionsDisplay: StatusActionsDisplay = .full @AppStorage(ThemeKey.statusActionsDisplay.rawValue) public var statusActionsDisplay: StatusActionsDisplay = .full
@AppStorage(ThemeKey.statusDisplayStyle.rawValue) public var statusDisplayStyle: StatusDisplayStyle = .large
@Published public var avatarPosition: AvatarPosition = .top @Published public var avatarPosition: AvatarPosition = .top
@Published public var avatarShape: AvatarShape = .rounded @Published public var avatarShape: AvatarShape = .rounded

View file

@ -16,7 +16,7 @@ public struct StatusCardView: View {
public var body: some View { public var body: some View {
if let title = card.title { if let title = card.title {
VStack(alignment: .leading) { VStack(alignment: .leading) {
if let imageURL = card.image { if let imageURL = card.image, theme.statusDisplayStyle == .large {
LazyImage(url: imageURL) { state in LazyImage(url: imageURL) { state in
if let image = state.image { if let image = state.image {
image image
@ -30,7 +30,6 @@ public struct StatusCardView: View {
} }
.frame(height: 200) .frame(height: 200)
} }
Spacer()
HStack { HStack {
VStack(alignment: .leading, spacing: 6) { VStack(alignment: .leading, spacing: 6) {
Text(title) Text(title)

View file

@ -10,7 +10,7 @@ public struct StatusMediaPreviewView: View {
@EnvironmentObject private var theme: Theme @EnvironmentObject private var theme: Theme
public let attachements: [MediaAttachement] public let attachements: [MediaAttachement]
public let isCompact: Bool public let isNotifications: Bool
@State private var isQuickLookLoading: Bool = false @State private var isQuickLookLoading: Bool = false
@State private var width: CGFloat = 0 @State private var width: CGFloat = 0
@ -18,9 +18,12 @@ public struct StatusMediaPreviewView: View {
@State private var isAltAlertDisplayed: Bool = false @State private var isAltAlertDisplayed: Bool = false
private var imageMaxHeight: CGFloat { private var imageMaxHeight: CGFloat {
if isCompact { if isNotifications {
return 50 return 50
} }
if theme.statusDisplayStyle == .compact {
return 100
}
if attachements.count == 1 { if attachements.count == 1 {
return 300 return 300
} }
@ -28,9 +31,12 @@ public struct StatusMediaPreviewView: View {
} }
private func size(for media: MediaAttachement) -> CGSize? { private func size(for media: MediaAttachement) -> CGSize? {
if isCompact { if isNotifications {
return .init(width: 50, height: 50) return .init(width: 50, height: 50)
} }
if theme.statusDisplayStyle == .compact {
return .init(width: 100, height: 100)
}
if let width = media.meta?.original?.width, if let width = media.meta?.original?.width,
let height = media.meta?.original?.height { let height = media.meta?.original?.height {
return .init(width: CGFloat(width), height: CGFloat(height)) return .init(width: CGFloat(width), height: CGFloat(height))
@ -39,7 +45,7 @@ public struct StatusMediaPreviewView: View {
} }
private func imageSize(from: CGSize, newWidth: CGFloat) -> CGSize { private func imageSize(from: CGSize, newWidth: CGFloat) -> CGSize {
if isCompact { if isNotifications {
return .init(width: 50, height: 50) return .init(width: 50, height: 50)
} }
let ratio = newWidth / from.width let ratio = newWidth / from.width
@ -57,7 +63,7 @@ public struct StatusMediaPreviewView: View {
} }
} }
} else { } else {
if isCompact { if isNotifications || theme.statusDisplayStyle == .compact {
HStack { HStack {
makeAttachementView(for: 0) makeAttachementView(for: 0)
makeAttachementView(for: 1) makeAttachementView(for: 1)
@ -104,7 +110,8 @@ public struct StatusMediaPreviewView: View {
private func makeFeaturedImagePreview(attachement: MediaAttachement) -> some View { private func makeFeaturedImagePreview(attachement: MediaAttachement) -> some View {
switch attachement.supportedType { switch attachement.supportedType {
case .image: case .image:
if let size = size(for: attachement), if theme.statusDisplayStyle == .large,
let size = size(for: attachement),
UIDevice.current.userInterfaceIdiom != .pad, UIDevice.current.userInterfaceIdiom != .pad,
UIDevice.current.userInterfaceIdiom != .mac { UIDevice.current.userInterfaceIdiom != .mac {
let avatarColumnWidth = theme.avatarPosition == .leading ? AvatarView.Size.status.size.width + .statusColumnsSpacing : 0 let avatarColumnWidth = theme.avatarPosition == .leading ? AvatarView.Size.status.size.width + .statusColumnsSpacing : 0
@ -125,7 +132,7 @@ public struct StatusMediaPreviewView: View {
.shimmering() .shimmering()
} }
} }
if let alt = attachement.description, !alt.isEmpty, !isCompact { if let alt = attachement.description, !alt.isEmpty, !isNotifications {
Button { Button {
altTextDisplayed = alt altTextDisplayed = alt
isAltAlertDisplayed = true isAltAlertDisplayed = true
@ -183,13 +190,13 @@ public struct StatusMediaPreviewView: View {
RoundedRectangle(cornerRadius: 4) RoundedRectangle(cornerRadius: 4)
.fill(Color.gray) .fill(Color.gray)
.frame(maxHeight: imageMaxHeight) .frame(maxHeight: imageMaxHeight)
.frame(width: isCompact ? imageMaxHeight : proxy.frame(in: .local).width) .frame(width: isNotifications ? imageMaxHeight : proxy.frame(in: .local).width)
.shimmering() .shimmering()
} }
} }
.frame(width: isCompact ? imageMaxHeight : proxy.frame(in: .local).width) .frame(width: isNotifications ? imageMaxHeight : proxy.frame(in: .local).width)
.frame(height: imageMaxHeight) .frame(height: imageMaxHeight)
if let alt = attachement.description, !alt.isEmpty, !isCompact { if let alt = attachement.description, !alt.isEmpty, !isNotifications {
Button { Button {
altTextDisplayed = alt altTextDisplayed = alt
isAltAlertDisplayed = true isAltAlertDisplayed = true
@ -205,12 +212,12 @@ public struct StatusMediaPreviewView: View {
case .gifv, .video: case .gifv, .video:
if let url = attachement.url { if let url = attachement.url {
VideoPlayerView(viewModel: .init(url: url)) VideoPlayerView(viewModel: .init(url: url))
.frame(width: isCompact ? imageMaxHeight : proxy.frame(in: .local).width) .frame(width: isNotifications ? imageMaxHeight : proxy.frame(in: .local).width)
.frame(height: imageMaxHeight) .frame(height: imageMaxHeight)
} }
} }
} }
.frame(width: isCompact ? imageMaxHeight : nil) .frame(width: isNotifications ? imageMaxHeight : nil)
.frame(height: imageMaxHeight) .frame(height: imageMaxHeight)
} }
.onTapGesture { .onTapGesture {

View file

@ -188,7 +188,7 @@ public struct StatusRowView: View {
} }
if !status.mediaAttachments.isEmpty { if !status.mediaAttachments.isEmpty {
StatusMediaPreviewView(attachements: status.mediaAttachments, isCompact: viewModel.isCompact) StatusMediaPreviewView(attachements: status.mediaAttachments, isNotifications: viewModel.isCompact)
.padding(.vertical, 4) .padding(.vertical, 4)
} }
if let card = status.card, viewModel.embededStatus?.url != status.card?.url, !viewModel.isEmbedLoading { if let card = status.card, viewModel.embededStatus?.url != status.card?.url, !viewModel.isEmbedLoading {