mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-12-22 15:16:36 +00:00
Make max width more consistent on iPad fix #236
This commit is contained in:
parent
33a7bd57ff
commit
6ea2d9cb78
4 changed files with 99 additions and 90 deletions
|
@ -32,6 +32,8 @@ public struct AppAccountView: View {
|
|||
HStack {
|
||||
if let account = viewModel.account {
|
||||
AvatarView(url: account.avatar)
|
||||
} else {
|
||||
ProgressView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +49,8 @@ public struct AppAccountView: View {
|
|||
.offset(x: 5, y: -5)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ProgressView()
|
||||
}
|
||||
VStack(alignment: .leading) {
|
||||
if let account = viewModel.account {
|
||||
|
|
|
@ -10,62 +10,65 @@ public struct ConversationsListView: View {
|
|||
@EnvironmentObject private var watcher: StreamWatcher
|
||||
@EnvironmentObject private var client: Client
|
||||
@EnvironmentObject private var theme: Theme
|
||||
|
||||
|
||||
@StateObject private var viewModel = ConversationsListViewModel()
|
||||
|
||||
|
||||
public init() {}
|
||||
|
||||
|
||||
private var conversations: [Conversation] {
|
||||
if viewModel.isLoadingFirstPage {
|
||||
return Conversation.placeholders()
|
||||
}
|
||||
return viewModel.conversations
|
||||
}
|
||||
|
||||
|
||||
public var body: some View {
|
||||
ScrollView {
|
||||
LazyVStack {
|
||||
if !conversations.isEmpty || viewModel.isLoadingFirstPage {
|
||||
ForEach(conversations) { conversation in
|
||||
if viewModel.isLoadingFirstPage {
|
||||
ConversationsListRow(conversation: conversation, viewModel: viewModel)
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
.redacted(reason: .placeholder)
|
||||
.shimmering()
|
||||
} else {
|
||||
ConversationsListRow(conversation: conversation, viewModel: viewModel)
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
Group {
|
||||
if !conversations.isEmpty || viewModel.isLoadingFirstPage {
|
||||
ForEach(conversations) { conversation in
|
||||
if viewModel.isLoadingFirstPage {
|
||||
ConversationsListRow(conversation: conversation, viewModel: viewModel)
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
.redacted(reason: .placeholder)
|
||||
.shimmering()
|
||||
} else {
|
||||
ConversationsListRow(conversation: conversation, viewModel: viewModel)
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
}
|
||||
Divider()
|
||||
}
|
||||
Divider()
|
||||
}
|
||||
} else if conversations.isEmpty && !viewModel.isLoadingFirstPage && !viewModel.isError {
|
||||
EmptyView(iconName: "tray",
|
||||
title: "conversations.empty.title",
|
||||
message: "conversations.empty.message")
|
||||
} else if viewModel.isError {
|
||||
ErrorView(title: "conversations.error.title",
|
||||
message: "conversations.error.message",
|
||||
buttonTitle: "conversations.error.button") {
|
||||
Task {
|
||||
await viewModel.fetchConversations()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if viewModel.nextPage != nil {
|
||||
HStack {
|
||||
Spacer()
|
||||
ProgressView()
|
||||
Spacer()
|
||||
}
|
||||
.onAppear {
|
||||
if !viewModel.isLoadingNextPage {
|
||||
} else if conversations.isEmpty && !viewModel.isLoadingFirstPage && !viewModel.isError {
|
||||
EmptyView(iconName: "tray",
|
||||
title: "conversations.empty.title",
|
||||
message: "conversations.empty.message")
|
||||
} else if viewModel.isError {
|
||||
ErrorView(title: "conversations.error.title",
|
||||
message: "conversations.error.message",
|
||||
buttonTitle: "conversations.error.button") {
|
||||
Task {
|
||||
await viewModel.fetchNextPage()
|
||||
await viewModel.fetchConversations()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if viewModel.nextPage != nil {
|
||||
HStack {
|
||||
Spacer()
|
||||
ProgressView()
|
||||
Spacer()
|
||||
}
|
||||
.onAppear {
|
||||
if !viewModel.isLoadingNextPage {
|
||||
Task {
|
||||
await viewModel.fetchNextPage()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .maxColumnWidth)
|
||||
}
|
||||
.padding(.top, .layoutPadding)
|
||||
}
|
||||
|
|
|
@ -23,8 +23,7 @@ extension Color: RawRepresentable {
|
|||
let red = Double((rawValue & 0xFF0000) >> 16) / 0xFF
|
||||
let green = Double((rawValue & 0x00FF00) >> 8) / 0xFF
|
||||
let blue = Double(rawValue & 0x0000FF) / 0xFF
|
||||
let opacity = Double((rawValue & 0xFF000000) >> 24) / 0xFF
|
||||
self = Color(red: red, green: green, blue: blue, opacity: opacity == 0 ? 1 : 0)
|
||||
self = Color(red: red, green: green, blue: blue)
|
||||
}
|
||||
|
||||
public var rawValue: Int {
|
||||
|
@ -34,8 +33,7 @@ extension Color: RawRepresentable {
|
|||
let red = Int(coreImageColor.red * 255 + 0.5)
|
||||
let green = Int(coreImageColor.green * 255 + 0.5)
|
||||
let blue = Int(coreImageColor.blue * 255 + 0.5)
|
||||
let alpha = Int(coreImageColor.alpha * 255 + 0.5)
|
||||
return (alpha << 24) | (red << 16) | (green << 8) | blue
|
||||
return (red << 16) | (green << 8) | blue
|
||||
}
|
||||
|
||||
private var coreImageColor: CIColor? {
|
||||
|
|
|
@ -14,68 +14,72 @@ public struct StatusDetailView: View {
|
|||
@Environment(\.openURL) private var openURL
|
||||
@StateObject private var viewModel: StatusDetailViewModel
|
||||
@State private var isLoaded: Bool = false
|
||||
|
||||
|
||||
public init(statusId: String) {
|
||||
_viewModel = StateObject(wrappedValue: .init(statusId: statusId))
|
||||
}
|
||||
|
||||
|
||||
public init(remoteStatusURL: URL) {
|
||||
_viewModel = StateObject(wrappedValue: .init(remoteStatusURL: remoteStatusURL))
|
||||
}
|
||||
|
||||
|
||||
public var body: some View {
|
||||
ScrollViewReader { proxy in
|
||||
ScrollView {
|
||||
LazyVStack {
|
||||
switch viewModel.state {
|
||||
case .loading:
|
||||
ForEach(Status.placeholders()) { status in
|
||||
StatusRowView(viewModel: .init(status: status, isCompact: false))
|
||||
ZStack {
|
||||
ScrollView {
|
||||
LazyVStack {
|
||||
Group {
|
||||
switch viewModel.state {
|
||||
case .loading:
|
||||
ForEach(Status.placeholders()) { status in
|
||||
StatusRowView(viewModel: .init(status: status, isCompact: false))
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
.redacted(reason: .placeholder)
|
||||
.shimmering()
|
||||
Divider()
|
||||
.padding(.vertical, .dividerPadding)
|
||||
}
|
||||
case let .display(status, context):
|
||||
if !context.ancestors.isEmpty {
|
||||
ForEach(context.ancestors) { ancestor in
|
||||
StatusRowView(viewModel: .init(status: ancestor, isCompact: false))
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
Divider()
|
||||
.padding(.vertical, .dividerPadding)
|
||||
}
|
||||
}
|
||||
StatusRowView(viewModel: .init(status: status,
|
||||
isCompact: false,
|
||||
isFocused: true))
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
.redacted(reason: .placeholder)
|
||||
.shimmering()
|
||||
Divider()
|
||||
.padding(.vertical, .dividerPadding)
|
||||
}
|
||||
case let .display(status, context):
|
||||
if !context.ancestors.isEmpty {
|
||||
ForEach(context.ancestors) { ancestor in
|
||||
StatusRowView(viewModel: .init(status: ancestor, isCompact: false))
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
.id(status.id)
|
||||
Divider()
|
||||
.padding(.vertical, .dividerPadding)
|
||||
}
|
||||
}
|
||||
StatusRowView(viewModel: .init(status: status,
|
||||
isCompact: false,
|
||||
isFocused: true))
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
.id(status.id)
|
||||
Divider()
|
||||
.padding(.bottom, .dividerPadding * 2)
|
||||
if !context.descendants.isEmpty {
|
||||
ForEach(context.descendants) { descendant in
|
||||
StatusRowView(viewModel: .init(status: descendant, isCompact: false))
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
Divider()
|
||||
.padding(.vertical, .dividerPadding)
|
||||
}
|
||||
}
|
||||
|
||||
case .error:
|
||||
ErrorView(title: "status.error.title",
|
||||
message: "status.error.message",
|
||||
buttonTitle: "action.retry") {
|
||||
Task {
|
||||
await viewModel.fetch()
|
||||
.padding(.bottom, .dividerPadding * 2)
|
||||
if !context.descendants.isEmpty {
|
||||
ForEach(context.descendants) { descendant in
|
||||
StatusRowView(viewModel: .init(status: descendant, isCompact: false))
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
Divider()
|
||||
.padding(.vertical, .dividerPadding)
|
||||
}
|
||||
}
|
||||
|
||||
case .error:
|
||||
ErrorView(title: "status.error.title",
|
||||
message: "status.error.message",
|
||||
buttonTitle: "action.retry") {
|
||||
Task {
|
||||
await viewModel.fetch()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .maxColumnWidth)
|
||||
}
|
||||
.padding(.top, .layoutPadding)
|
||||
}
|
||||
.padding(.top, .layoutPadding)
|
||||
.background(theme.primaryBackgroundColor)
|
||||
}
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.primaryBackgroundColor)
|
||||
.task {
|
||||
guard !isLoaded else { return }
|
||||
isLoaded = true
|
||||
|
|
Loading…
Reference in a new issue