mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2025-02-03 16:07:31 +01:00
Various optimizations to views & images rendering
This commit is contained in:
parent
881816730c
commit
f09781582f
@ -135,9 +135,7 @@ struct IceCubesApp: App {
|
||||
userPreferences.showiPadSecondaryColumn
|
||||
{
|
||||
Divider().edgesIgnoringSafeArea(.all)
|
||||
NotificationsTab(popToRootTab: $popToRootTab, lockedType: nil)
|
||||
.environment(\.isSecondaryColumn, true)
|
||||
.frame(maxWidth: 360)
|
||||
notificationsSecondaryColumn
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -145,6 +143,13 @@ struct IceCubesApp: App {
|
||||
sideBarLoadedTabs.removeAll()
|
||||
}
|
||||
}
|
||||
|
||||
private var notificationsSecondaryColumn: some View {
|
||||
NotificationsTab(popToRootTab: $popToRootTab, lockedType: nil)
|
||||
.environment(\.isSecondaryColumn, true)
|
||||
.frame(maxWidth: 360)
|
||||
.id(appAccountsManager.currentAccount.id)
|
||||
}
|
||||
|
||||
private var tabBarView: some View {
|
||||
TabView(selection: .init(get: {
|
||||
|
@ -55,9 +55,10 @@ public struct AvatarView: View {
|
||||
.frame(width: size.size.width, height: size.size.height)
|
||||
} else {
|
||||
LazyImage(url: url) { state in
|
||||
if let image = state.image {
|
||||
image
|
||||
.resizingMode(.aspectFit)
|
||||
if let image = state.imageContainer?.image {
|
||||
SwiftUI.Image(uiImage: image)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
} else {
|
||||
placeholderView
|
||||
}
|
||||
|
@ -5,9 +5,27 @@ private struct SecondaryColumnKey: EnvironmentKey {
|
||||
static let defaultValue = false
|
||||
}
|
||||
|
||||
private struct ExtraLeadingInset: EnvironmentKey {
|
||||
static let defaultValue: CGFloat = 0
|
||||
}
|
||||
|
||||
private struct IsCompact: EnvironmentKey {
|
||||
static let defaultValue: Bool = false
|
||||
}
|
||||
|
||||
public extension EnvironmentValues {
|
||||
var isSecondaryColumn: Bool {
|
||||
get { self[SecondaryColumnKey.self] }
|
||||
set { self[SecondaryColumnKey.self] = newValue }
|
||||
}
|
||||
|
||||
var extraLeadingInset: CGFloat {
|
||||
get { self[ExtraLeadingInset.self] }
|
||||
set { self[ExtraLeadingInset.self] = newValue }
|
||||
}
|
||||
|
||||
var isCompact: Bool {
|
||||
get { self[IsCompact.self] }
|
||||
set { self[IsCompact.self] = newValue }
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ public struct ExploreView: View {
|
||||
|
||||
private var loadingView: some View {
|
||||
ForEach(Status.placeholders()) { status in
|
||||
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath, isCompact: false))
|
||||
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath))
|
||||
.padding(.vertical, 8)
|
||||
.redacted(reason: .placeholder)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
@ -184,7 +184,7 @@ public struct ExploreView: View {
|
||||
Section("explore.section.trending.posts") {
|
||||
ForEach(viewModel.trendingStatuses
|
||||
.prefix(upTo: viewModel.trendingStatuses.count > 3 ? 3 : viewModel.trendingStatuses.count)) { status in
|
||||
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath, isCompact: false))
|
||||
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath))
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
.padding(.vertical, 8)
|
||||
}
|
||||
@ -192,7 +192,7 @@ public struct ExploreView: View {
|
||||
NavigationLink {
|
||||
List {
|
||||
ForEach(viewModel.trendingStatuses) { status in
|
||||
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath, isCompact: false))
|
||||
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath))
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
.padding(.vertical, 8)
|
||||
}
|
||||
|
@ -6,24 +6,31 @@
|
||||
//
|
||||
|
||||
import Models
|
||||
import Foundation
|
||||
|
||||
extension Array where Element == Notification {
|
||||
func consolidated(selectedType: Notification.NotificationType?) -> [ConsolidatedNotification] {
|
||||
Dictionary(grouping: self) { $0.consolidationId(selectedType: selectedType) }
|
||||
.values
|
||||
.compactMap { notifications in
|
||||
guard let notification = notifications.first,
|
||||
let supportedType = notification.supportedType
|
||||
else { return nil }
|
||||
extension Array where Element == Models.Notification {
|
||||
func consolidated(selectedType: Models.Notification.NotificationType?) async -> [ConsolidatedNotification] {
|
||||
await withCheckedContinuation({ result in
|
||||
DispatchQueue.global().async {
|
||||
let notifications: [ConsolidatedNotification] =
|
||||
Dictionary(grouping: self) { $0.consolidationId(selectedType: selectedType) }
|
||||
.values
|
||||
.compactMap { notifications in
|
||||
guard let notification = notifications.first,
|
||||
let supportedType = notification.supportedType
|
||||
else { return nil }
|
||||
|
||||
return ConsolidatedNotification(notifications: notifications,
|
||||
type: supportedType,
|
||||
createdAt: notification.createdAt,
|
||||
accounts: notifications.map(\.account),
|
||||
status: notification.status)
|
||||
}
|
||||
.sorted {
|
||||
$0.createdAt.asDate > $1.createdAt.asDate
|
||||
return ConsolidatedNotification(notifications: notifications,
|
||||
type: supportedType,
|
||||
createdAt: notification.createdAt,
|
||||
accounts: notifications.map(\.account),
|
||||
status: notification.status)
|
||||
}
|
||||
.sorted {
|
||||
$0.createdAt.asDate > $1.createdAt.asDate
|
||||
}
|
||||
result.resume(returning: notifications)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -7,13 +7,13 @@ import SwiftUI
|
||||
import Network
|
||||
|
||||
struct NotificationRowView: View {
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@Environment(\.redactionReasons) private var reasons
|
||||
|
||||
let notification: ConsolidatedNotification
|
||||
let client: Client
|
||||
let routerPath: RouterPath
|
||||
let followRequests: [Account]
|
||||
|
||||
var body: some View {
|
||||
HStack(alignment: .top, spacing: 8) {
|
||||
@ -28,8 +28,7 @@ struct NotificationRowView: View {
|
||||
makeMainLabel(type: notification.type)
|
||||
makeContent(type: notification.type)
|
||||
if notification.type == .follow_request,
|
||||
currentAccount.followRequests.map(\.id).contains(notification.accounts[0].id)
|
||||
{
|
||||
followRequests.map(\.id).contains(notification.accounts[0].id) {
|
||||
FollowRequestButtons(account: notification.accounts[0])
|
||||
}
|
||||
}
|
||||
@ -137,19 +136,18 @@ struct NotificationRowView: View {
|
||||
StatusRowView(viewModel: .init(status: status,
|
||||
client: client,
|
||||
routerPath: routerPath,
|
||||
isCompact: true,
|
||||
showActions: true))
|
||||
} else {
|
||||
StatusRowView(viewModel: .init(status: status,
|
||||
client: client,
|
||||
routerPath: routerPath,
|
||||
isCompact: true,
|
||||
showActions: false))
|
||||
.lineLimit(4)
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.environment(\.isCompact, true)
|
||||
} else {
|
||||
Group {
|
||||
Text("@\(notification.accounts[0].acct)")
|
||||
|
@ -84,7 +84,10 @@ public struct NotificationsListView: View {
|
||||
switch viewModel.state {
|
||||
case .loading:
|
||||
ForEach(ConsolidatedNotification.placeholders()) { notification in
|
||||
NotificationRowView(notification: notification, client: client, routerPath: routerPath)
|
||||
NotificationRowView(notification: notification,
|
||||
client: client,
|
||||
routerPath: routerPath,
|
||||
followRequests: account.followRequests)
|
||||
.redacted(reason: .placeholder)
|
||||
.listRowInsets(.init(top: 12,
|
||||
leading: .layoutPadding + 4,
|
||||
@ -103,13 +106,17 @@ public struct NotificationsListView: View {
|
||||
.listSectionSeparator(.hidden)
|
||||
} else {
|
||||
ForEach(notifications) { notification in
|
||||
NotificationRowView(notification: notification, client: client, routerPath: routerPath)
|
||||
NotificationRowView(notification: notification,
|
||||
client: client,
|
||||
routerPath: routerPath,
|
||||
followRequests: account.followRequests)
|
||||
.listRowInsets(.init(top: 12,
|
||||
leading: .layoutPadding + 4,
|
||||
bottom: 12,
|
||||
trailing: .layoutPadding))
|
||||
.listRowBackground(notification.type == .mention && lockedType != .mention ?
|
||||
theme.secondaryBackgroundColor : theme.primaryBackgroundColor)
|
||||
.id(notification.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ class NotificationsViewModel: ObservableObject {
|
||||
maxId: nil,
|
||||
types: queryTypes,
|
||||
limit: Constants.notificationLimit))
|
||||
consolidatedNotifications = notifications.consolidated(selectedType: selectedType)
|
||||
consolidatedNotifications = await notifications.consolidated(selectedType: selectedType)
|
||||
nextPageState = notifications.count < Constants.notificationLimit ? .none : .hasNextPage
|
||||
} else if let firstId = consolidatedNotifications.first?.id {
|
||||
var newNotifications: [Models.Notification] = await fetchNewPages(minId: firstId, maxPages: 10)
|
||||
@ -77,13 +77,15 @@ class NotificationsViewModel: ObservableObject {
|
||||
newNotifications = newNotifications.filter { notification in
|
||||
!consolidatedNotifications.contains(where: { $0.id == notification.id })
|
||||
}
|
||||
consolidatedNotifications.insert(
|
||||
await consolidatedNotifications.insert(
|
||||
contentsOf: newNotifications.consolidated(selectedType: selectedType),
|
||||
at: 0
|
||||
)
|
||||
}
|
||||
|
||||
await currentAccount.fetchFollowerRequests()
|
||||
if consolidatedNotifications.contains(where: { $0.type == .follow_request }) {
|
||||
await currentAccount.fetchFollowerRequests()
|
||||
}
|
||||
|
||||
withAnimation {
|
||||
state = .display(notifications: consolidatedNotifications,
|
||||
@ -129,8 +131,10 @@ class NotificationsViewModel: ObservableObject {
|
||||
maxId: lastId,
|
||||
types: queryTypes,
|
||||
limit: Constants.notificationLimit))
|
||||
consolidatedNotifications.append(contentsOf: newNotifications.consolidated(selectedType: selectedType))
|
||||
await currentAccount?.fetchFollowerRequests()
|
||||
await consolidatedNotifications.append(contentsOf: newNotifications.consolidated(selectedType: selectedType))
|
||||
if consolidatedNotifications.contains(where: { $0.type == .follow_request }) {
|
||||
await currentAccount?.fetchFollowerRequests()
|
||||
}
|
||||
state = .display(notifications: consolidatedNotifications,
|
||||
nextPageState: newNotifications.count < Constants.notificationLimit ? .none : .hasNextPage)
|
||||
} catch {
|
||||
@ -159,14 +163,14 @@ class NotificationsViewModel: ObservableObject {
|
||||
{
|
||||
// If the notification type can be consolidated, try to consolidate with the latest row
|
||||
let latestConsolidatedNotification = consolidatedNotifications.removeFirst()
|
||||
consolidatedNotifications.insert(
|
||||
await consolidatedNotifications.insert(
|
||||
contentsOf: ([event.notification] + latestConsolidatedNotification.notifications)
|
||||
.consolidated(selectedType: selectedType),
|
||||
at: 0
|
||||
)
|
||||
} else {
|
||||
// Otherwise, just insert the new notification
|
||||
consolidatedNotifications.insert(
|
||||
await consolidatedNotifications.insert(
|
||||
contentsOf: [event.notification].consolidated(selectedType: selectedType),
|
||||
at: 0
|
||||
)
|
||||
|
@ -104,18 +104,20 @@ public struct StatusDetailView: View {
|
||||
}
|
||||
let viewModel: StatusRowViewModel = .init(status: status,
|
||||
client: client,
|
||||
routerPath: routerPath,
|
||||
isCompact: false)
|
||||
return HStack {
|
||||
routerPath: routerPath)
|
||||
return HStack(spacing: 0) {
|
||||
if isReplyToPrevious {
|
||||
Rectangle()
|
||||
.fill(theme.tintColor)
|
||||
.frame(width: 2)
|
||||
Spacer(minLength: 8)
|
||||
}
|
||||
if self.viewModel.statusId == status.id {
|
||||
makeCurrentStatusView(status: status)
|
||||
.environment(\.extraLeadingInset, isReplyToPrevious ? 10 : 0)
|
||||
} else {
|
||||
StatusRowView(viewModel: viewModel)
|
||||
.environment(\.extraLeadingInset, isReplyToPrevious ? 10 : 0)
|
||||
}
|
||||
}
|
||||
.listRowBackground(viewModel.highlightRowColor)
|
||||
@ -130,7 +132,6 @@ public struct StatusDetailView: View {
|
||||
StatusRowView(viewModel: .init(status: status,
|
||||
client: client,
|
||||
routerPath: routerPath,
|
||||
isCompact: false,
|
||||
isFocused: !viewModel.isLoadingContext))
|
||||
.overlay {
|
||||
GeometryReader { reader in
|
||||
@ -157,7 +158,7 @@ public struct StatusDetailView: View {
|
||||
|
||||
private var loadingDetailView: some View {
|
||||
ForEach(Status.placeholders()) { status in
|
||||
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath, isCompact: false))
|
||||
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath))
|
||||
.redacted(reason: .placeholder)
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import Models
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
|
||||
struct StatusEditorMediaView: View {
|
||||
struct StatusEditorMediaView: View {
|
||||
@EnvironmentObject private var theme: Theme
|
||||
@EnvironmentObject private var currentInstance: CurrentInstance
|
||||
@ObservedObject var viewModel: StatusEditorViewModel
|
||||
|
@ -26,8 +26,8 @@ public struct StatusEmbeddedView: View {
|
||||
StatusRowView(viewModel: .init(status: status,
|
||||
client: client,
|
||||
routerPath: routerPath,
|
||||
isCompact: true,
|
||||
showActions: false))
|
||||
.environment(\.isCompact, true)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ public struct StatusesListView<Fetcher>: View where Fetcher: StatusesFetcher {
|
||||
switch fetcher.statusesState {
|
||||
case .loading:
|
||||
ForEach(Status.placeholders()) { status in
|
||||
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath, isCompact: false))
|
||||
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath))
|
||||
.redacted(reason: .placeholder)
|
||||
}
|
||||
case .error:
|
||||
@ -40,7 +40,7 @@ public struct StatusesListView<Fetcher>: View where Fetcher: StatusesFetcher {
|
||||
|
||||
case let .display(statuses, nextPageState):
|
||||
ForEach(statuses, id: \.viewId) { status in
|
||||
let viewModel = StatusRowViewModel(status: status, client: client, routerPath: routerPath, isCompact: false, isRemote: isRemote)
|
||||
let viewModel = StatusRowViewModel(status: status, client: client, routerPath: routerPath, isRemote: isRemote)
|
||||
if viewModel.filter?.filter.filterAction != .hide {
|
||||
StatusRowView(viewModel: viewModel)
|
||||
.id(status.id)
|
||||
|
@ -54,6 +54,7 @@ struct VideoPlayerView: View {
|
||||
}.onAppear {
|
||||
viewModel.preparePlayer(autoPlay: preferences.autoPlayVideo)
|
||||
}
|
||||
.cornerRadius(4)
|
||||
.onChange(of: scenePhase, perform: { scenePhase in
|
||||
switch scenePhase {
|
||||
case .background, .inactive:
|
||||
|
@ -8,6 +8,7 @@ import SwiftUI
|
||||
|
||||
public struct StatusRowView: View {
|
||||
@Environment(\.redactionReasons) private var reasons
|
||||
@Environment(\.isCompact) private var isCompact: Bool
|
||||
|
||||
@EnvironmentObject private var theme: Theme
|
||||
|
||||
@ -34,12 +35,12 @@ public struct StatusRowView: View {
|
||||
} else {
|
||||
let status: AnyStatus = viewModel.status.reblog ?? viewModel.status
|
||||
VStack(alignment: .leading) {
|
||||
if !viewModel.isCompact, theme.avatarPosition == .leading {
|
||||
if !isCompact, theme.avatarPosition == .leading {
|
||||
StatusRowReblogView(viewModel: viewModel)
|
||||
StatusRowReplyView(viewModel: viewModel)
|
||||
}
|
||||
HStack(alignment: .top, spacing: .statusColumnsSpacing) {
|
||||
if !viewModel.isCompact,
|
||||
if !isCompact,
|
||||
theme.avatarPosition == .leading {
|
||||
Button {
|
||||
viewModel.routerPath.navigate(to: .accountDetailWithAccount(account: status.account))
|
||||
@ -48,13 +49,13 @@ public struct StatusRowView: View {
|
||||
}
|
||||
}
|
||||
VStack(alignment: .leading) {
|
||||
if !viewModel.isCompact, theme.avatarPosition == .top {
|
||||
if !isCompact, theme.avatarPosition == .top {
|
||||
StatusRowReblogView(viewModel: viewModel)
|
||||
StatusRowReplyView(viewModel: viewModel)
|
||||
}
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
let status: AnyStatus = viewModel.status.reblog ?? viewModel.status
|
||||
if !viewModel.isCompact {
|
||||
if !isCompact {
|
||||
StatusRowHeaderView(status: status, viewModel: viewModel)
|
||||
}
|
||||
StatusRowContentView(status: status, viewModel: viewModel)
|
||||
@ -82,7 +83,7 @@ public struct StatusRowView: View {
|
||||
.onAppear {
|
||||
viewModel.markSeen()
|
||||
if reasons.isEmpty {
|
||||
if !viewModel.isCompact, viewModel.embeddedStatus == nil {
|
||||
if !isCompact, viewModel.embeddedStatus == nil {
|
||||
Task {
|
||||
await viewModel.loadEmbeddedStatus()
|
||||
}
|
||||
@ -93,12 +94,12 @@ public struct StatusRowView: View {
|
||||
contextMenu
|
||||
}
|
||||
.swipeActions(edge: .trailing) {
|
||||
if !viewModel.isCompact {
|
||||
if !isCompact {
|
||||
StatusRowSwipeView(viewModel: viewModel, mode: .trailing)
|
||||
}
|
||||
}
|
||||
.swipeActions(edge: .leading) {
|
||||
if !viewModel.isCompact {
|
||||
if !isCompact {
|
||||
StatusRowSwipeView(viewModel: viewModel, mode: .leading)
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import DesignSystem
|
||||
@MainActor
|
||||
public class StatusRowViewModel: ObservableObject {
|
||||
let status: Status
|
||||
let isCompact: Bool
|
||||
let isFocused: Bool
|
||||
let isRemote: Bool
|
||||
let showActions: Bool
|
||||
@ -61,7 +60,6 @@ public class StatusRowViewModel: ObservableObject {
|
||||
public init(status: Status,
|
||||
client: Client,
|
||||
routerPath: RouterPath,
|
||||
isCompact: Bool = false,
|
||||
isFocused: Bool = false,
|
||||
isRemote: Bool = false,
|
||||
showActions: Bool = true)
|
||||
@ -69,7 +67,6 @@ public class StatusRowViewModel: ObservableObject {
|
||||
self.status = status
|
||||
self.client = client
|
||||
self.routerPath = routerPath
|
||||
self.isCompact = isCompact
|
||||
self.isFocused = isFocused
|
||||
self.isRemote = isRemote
|
||||
self.showActions = showActions
|
||||
|
@ -18,9 +18,12 @@ public struct StatusRowCardView: View {
|
||||
VStack(alignment: .leading) {
|
||||
if let imageURL = card.image {
|
||||
LazyImage(url: imageURL) { state in
|
||||
if let image = state.image {
|
||||
image
|
||||
.resizingMode(.aspectFill)
|
||||
if let image = state.imageContainer?.image {
|
||||
SwiftUI.Image(uiImage: image)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(height: 200)
|
||||
.clipped()
|
||||
} else if state.isLoading {
|
||||
Rectangle()
|
||||
.fill(Color.gray)
|
||||
|
@ -5,6 +5,8 @@ import Env
|
||||
|
||||
struct StatusRowContentView: View {
|
||||
@Environment(\.redactionReasons) private var reasons
|
||||
@Environment(\.isCompact) private var isCompact
|
||||
|
||||
@EnvironmentObject private var theme: Theme
|
||||
|
||||
let status: AnyStatus
|
||||
@ -23,7 +25,7 @@ struct StatusRowContentView: View {
|
||||
}
|
||||
|
||||
if !reasons.contains(.placeholder),
|
||||
!viewModel.isCompact,
|
||||
!isCompact,
|
||||
(viewModel.isEmbedLoading || viewModel.embeddedStatus != nil) {
|
||||
StatusEmbeddedView(status: viewModel.embeddedStatus ?? Status.placeholder(),
|
||||
client: viewModel.client,
|
||||
@ -31,13 +33,14 @@ struct StatusRowContentView: View {
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.redacted(reason: viewModel.isEmbedLoading ? .placeholder : [])
|
||||
.shimmering(active: viewModel.isEmbedLoading)
|
||||
.transition(.opacity)
|
||||
}
|
||||
|
||||
if !status.mediaAttachments.isEmpty {
|
||||
HStack {
|
||||
StatusRowMediaPreviewView(attachments: status.mediaAttachments,
|
||||
sensitive: status.sensitive,
|
||||
isNotifications: viewModel.isCompact)
|
||||
isNotifications: isCompact)
|
||||
if theme.statusDisplayStyle == .compact {
|
||||
Spacer()
|
||||
}
|
||||
@ -47,7 +50,7 @@ struct StatusRowContentView: View {
|
||||
|
||||
if let card = status.card,
|
||||
!viewModel.isEmbedLoading,
|
||||
!viewModel.isCompact,
|
||||
!isCompact,
|
||||
theme.statusDisplayStyle == .large,
|
||||
status.content.statusesURLs.isEmpty,
|
||||
status.mediaAttachments.isEmpty
|
||||
|
@ -8,6 +8,7 @@ import SwiftUI
|
||||
public struct StatusRowMediaPreviewView: View {
|
||||
@Environment(\.openURL) private var openURL
|
||||
@Environment(\.isSecondaryColumn) private var isSecondaryColumn
|
||||
@Environment(\.extraLeadingInset) private var extraLeadingInset: CGFloat
|
||||
|
||||
@EnvironmentObject var sceneDelegate: SceneDelegate
|
||||
@EnvironmentObject private var preferences: UserPreferences
|
||||
@ -37,7 +38,7 @@ public struct StatusRowMediaPreviewView: View {
|
||||
if UIDevice.current.userInterfaceIdiom == .pad && sceneDelegate.windowWidth < (.maxColumnWidth + .sidebarWidth) {
|
||||
sidebarWidth = .sidebarWidth
|
||||
}
|
||||
return (.layoutPadding * 2) + avatarColumnWidth + sidebarWidth
|
||||
return (.layoutPadding * 2) + avatarColumnWidth + sidebarWidth + extraLeadingInset
|
||||
}
|
||||
|
||||
private var imageMaxHeight: CGFloat {
|
||||
@ -152,11 +153,13 @@ public struct StatusRowMediaPreviewView: View {
|
||||
switch attachment.supportedType {
|
||||
case .image:
|
||||
LazyImage(url: attachment.url) { state in
|
||||
if let image = state.image {
|
||||
image
|
||||
.resizingMode(.aspectFill)
|
||||
.cornerRadius(4)
|
||||
if let image = state.imageContainer?.image {
|
||||
SwiftUI.Image(uiImage: image)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: newSize.width, height: newSize.height)
|
||||
.clipped()
|
||||
.cornerRadius(4)
|
||||
} else {
|
||||
RoundedRectangle(cornerRadius: 4)
|
||||
.fill(Color.gray)
|
||||
@ -204,9 +207,13 @@ public struct StatusRowMediaPreviewView: View {
|
||||
case .image:
|
||||
ZStack(alignment: .bottomTrailing) {
|
||||
LazyImage(url: attachment.url) { state in
|
||||
if let image = state.image {
|
||||
image
|
||||
.resizingMode(.aspectFill)
|
||||
if let image = state.imageContainer?.image {
|
||||
SwiftUI.Image(uiImage: image)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(maxWidth: isNotifications ? imageMaxHeight : proxy.frame(in: .local).width)
|
||||
.frame(maxHeight: imageMaxHeight)
|
||||
.clipped()
|
||||
.cornerRadius(4)
|
||||
} else if state.isLoading {
|
||||
RoundedRectangle(cornerRadius: 4)
|
||||
@ -215,8 +222,6 @@ public struct StatusRowMediaPreviewView: View {
|
||||
.frame(maxWidth: isNotifications ? imageMaxHeight : proxy.frame(in: .local).width)
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: isNotifications ? imageMaxHeight : proxy.frame(in: .local).width)
|
||||
.frame(height: imageMaxHeight)
|
||||
if sensitive {
|
||||
cornerSensitiveButton
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user