Add avatar position setting (#14)
Co-authored-by: Jérôme Danthinne <jerome.danthinne@smile.eu>
This commit is contained in:
parent
315a57b447
commit
810e9fbe6b
|
@ -71,11 +71,17 @@ struct SettingsTabs: View {
|
|||
ColorPicker("Tint color", selection: $theme.tintColor)
|
||||
ColorPicker("Background color", selection: $theme.primaryBackgroundColor)
|
||||
ColorPicker("Secondary Background color", selection: $theme.secondaryBackgroundColor)
|
||||
Picker("Avatar position", selection: $theme.avatarPosition) {
|
||||
ForEach(Theme.AvatarPosition.allCases, id: \.rawValue) { position in
|
||||
Text(position.description).tag(position)
|
||||
}
|
||||
}
|
||||
Button {
|
||||
theme.colorScheme = "dark"
|
||||
theme.tintColor = .brand
|
||||
theme.primaryBackgroundColor = .primaryBackground
|
||||
theme.secondaryBackgroundColor = .secondaryBackground
|
||||
theme.avatarPosition = .top
|
||||
} label: {
|
||||
Text("Restore default")
|
||||
}
|
||||
|
|
|
@ -4,5 +4,6 @@ public struct DS {
|
|||
public enum Constants {
|
||||
public static let layoutPadding: CGFloat = 20
|
||||
public static let dividerPadding: CGFloat = 4
|
||||
public static let statusColumnsSpacing: CGFloat = 8
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,23 @@
|
|||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
public class Theme: ObservableObject {
|
||||
enum ThemeKey: String {
|
||||
case colorScheme, tint, label, primaryBackground, secondaryBackground
|
||||
case avatarPosition
|
||||
}
|
||||
|
||||
public enum AvatarPosition: String, CaseIterable {
|
||||
case leading, top
|
||||
|
||||
public var description: LocalizedStringKey {
|
||||
switch self {
|
||||
case .leading:
|
||||
return "Leading"
|
||||
case .top:
|
||||
return "Top"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AppStorage("is_previously_set") var isSet: Bool = false
|
||||
|
@ -19,12 +34,27 @@ public class Theme: ObservableObject {
|
|||
@AppStorage(ThemeKey.primaryBackground.rawValue) public var primaryBackgroundColor: Color = .white
|
||||
@AppStorage(ThemeKey.secondaryBackground.rawValue) public var secondaryBackgroundColor: Color = .gray
|
||||
@AppStorage(ThemeKey.label.rawValue) public var labelColor: Color = .black
|
||||
@AppStorage(ThemeKey.avatarPosition.rawValue) var rawAvatarPosition: String = AvatarPosition.top.rawValue
|
||||
|
||||
@Published public var avatarPosition: AvatarPosition = .top
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
public init() {
|
||||
if !isSet {
|
||||
setColor(set: DarkSet())
|
||||
isSet.toggle()
|
||||
}
|
||||
|
||||
avatarPosition = AvatarPosition(rawValue: rawAvatarPosition) ?? .top
|
||||
|
||||
$avatarPosition
|
||||
.dropFirst()
|
||||
.map(\.rawValue)
|
||||
.sink { [weak self] position in
|
||||
self?.rawAvatarPosition = position
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
public func setColor(set: ColorSet) {
|
||||
|
|
|
@ -6,7 +6,7 @@ public struct AvatarView: View {
|
|||
public enum Size {
|
||||
case account, status, embed, badge, boost
|
||||
|
||||
var size: CGSize {
|
||||
public var size: CGSize {
|
||||
switch self {
|
||||
case .account:
|
||||
return .init(width: 80, height: 80)
|
||||
|
|
|
@ -7,6 +7,7 @@ import DesignSystem
|
|||
|
||||
public struct StatusMediaPreviewView: View {
|
||||
@EnvironmentObject private var quickLook: QuickLook
|
||||
@EnvironmentObject private var theme: Theme
|
||||
|
||||
public let attachements: [MediaAttachement]
|
||||
public let isCompact: Bool
|
||||
|
@ -95,8 +96,10 @@ public struct StatusMediaPreviewView: View {
|
|||
switch attachement.supportedType {
|
||||
case .image:
|
||||
if let size = size(for: attachement) {
|
||||
let avatarColumnWidth = theme.avatarPosition == .leading ? AvatarView.Size.status.size.width + DS.Constants.statusColumnsSpacing : 0
|
||||
let availableWidth = UIScreen.main.bounds.width - (DS.Constants.layoutPadding * 2) - avatarColumnWidth
|
||||
let newSize = imageSize(from: size,
|
||||
newWidth: UIScreen.main.bounds.width - (DS.Constants.layoutPadding * 2))
|
||||
newWidth: availableWidth)
|
||||
LazyImage(url: attachement.url) { state in
|
||||
if let image = state.image {
|
||||
image
|
||||
|
|
|
@ -18,6 +18,12 @@ public struct StatusRowView: View {
|
|||
}
|
||||
|
||||
public var body: some View {
|
||||
HStack(alignment: .top, spacing: DS.Constants.statusColumnsSpacing) {
|
||||
if !viewModel.isCompact,
|
||||
theme.avatarPosition == .leading,
|
||||
let status: AnyStatus = viewModel.status.reblog ?? viewModel.status {
|
||||
AvatarView(url: status.account.avatar, size: .status)
|
||||
}
|
||||
VStack(alignment: .leading) {
|
||||
if !viewModel.isCompact {
|
||||
reblogView
|
||||
|
@ -34,6 +40,7 @@ public struct StatusRowView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
viewModel.client = client
|
||||
if !viewModel.isCompact, viewModel.embededStatus == nil {
|
||||
|
@ -155,7 +162,9 @@ public struct StatusRowView: View {
|
|||
@ViewBuilder
|
||||
private func accountView(status: AnyStatus) -> some View {
|
||||
HStack(alignment: .center) {
|
||||
if theme.avatarPosition == .top {
|
||||
AvatarView(url: status.account.avatar, size: .status)
|
||||
}
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
status.account.displayNameWithEmojis
|
||||
.font(.headline)
|
||||
|
|
Loading…
Reference in New Issue