diff --git a/IceCubesApp/App/AppRouter.swift b/IceCubesApp/App/AppRouter.swift index 1daa9319..d801434a 100644 --- a/IceCubesApp/App/AppRouter.swift +++ b/IceCubesApp/App/AppRouter.swift @@ -3,12 +3,12 @@ import AppAccount import Conversations import DesignSystem import Env +import LinkPresentation import Lists +import Models import Status import SwiftUI import Timeline -import LinkPresentation -import Models @MainActor extension View { @@ -46,7 +46,7 @@ extension View { } } } - + func withSheetDestinations(sheetDestinations: Binding) -> some View { sheet(item: sheetDestinations) { destination in switch destination { @@ -99,7 +99,7 @@ extension View { } } } - + func withEnvironments() -> some View { environmentObject(CurrentAccount.shared) .environmentObject(UserPreferences.shared) @@ -114,38 +114,39 @@ extension View { struct ActivityView: UIViewControllerRepresentable { let image: UIImage let status: Status - + class LinkDelegate: NSObject, UIActivityItemSource { let image: UIImage let status: Status - + init(image: UIImage, status: Status) { self.image = image self.status = status } - - func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? { + + func activityViewControllerLinkMetadata(_: UIActivityViewController) -> LPLinkMetadata? { let imageProvider = NSItemProvider(object: image) let metadata = LPLinkMetadata() metadata.imageProvider = imageProvider metadata.title = status.reblog?.content.asRawText ?? status.content.asRawText return metadata } - - func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any { + + func activityViewControllerPlaceholderItem(_: UIActivityViewController) -> Any { image } - - func activityViewController(_ activityViewController: UIActivityViewController, - itemForActivityType activityType: UIActivity.ActivityType?) -> Any? { + + func activityViewController(_: UIActivityViewController, + itemForActivityType _: UIActivity.ActivityType?) -> Any? + { nil } } - - func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIActivityViewController { + + func makeUIViewController(context _: UIViewControllerRepresentableContext) -> UIActivityViewController { return UIActivityViewController(activityItems: [image, LinkDelegate(image: image, status: status)], applicationActivities: nil) } - - func updateUIViewController(_ uiViewController: UIActivityViewController, context: UIViewControllerRepresentableContext) {} + + func updateUIViewController(_: UIActivityViewController, context _: UIViewControllerRepresentableContext) {} } diff --git a/IceCubesApp/App/IceCubesApp.swift b/IceCubesApp/App/IceCubesApp.swift index a18a49ff..a8aec878 100644 --- a/IceCubesApp/App/IceCubesApp.swift +++ b/IceCubesApp/App/IceCubesApp.swift @@ -100,7 +100,8 @@ struct IceCubesApp: App { private func badgeFor(tab: Tab) -> Int { if tab == .notifications && selectedTab != tab, - let token = appAccountsManager.currentAccount.oauthToken { + let token = appAccountsManager.currentAccount.oauthToken + { return watcher.unreadNotificationsCount + userPreferences.getNotificationsCount(for: token) } return 0 @@ -169,7 +170,8 @@ struct IceCubesApp: App { } selectedTab = newTab if selectedTab == .notifications, - let token = appAccountsManager.currentAccount.oauthToken { + let token = appAccountsManager.currentAccount.oauthToken + { userPreferences.setNotification(count: 0, token: token) watcher.unreadNotificationsCount = 0 } diff --git a/IceCubesApp/App/SafariRouter.swift b/IceCubesApp/App/SafariRouter.swift index 5079ba95..3a1ebe49 100644 --- a/IceCubesApp/App/SafariRouter.swift +++ b/IceCubesApp/App/SafariRouter.swift @@ -15,7 +15,7 @@ private struct SafariRouter: ViewModifier { @EnvironmentObject private var routerPath: RouterPath @StateObject private var safariManager = InAppSafariManager() - + func body(content: Content) -> some View { content .environment(\.openURL, OpenURLAction { url in @@ -58,48 +58,48 @@ private struct SafariRouter: ViewModifier { private class InAppSafariManager: NSObject, ObservableObject, SFSafariViewControllerDelegate { var windowScene: UIWindowScene? - let viewController: UIViewController = UIViewController() + let viewController: UIViewController = .init() var window: UIWindow? @MainActor func open(_ url: URL) -> OpenURLAction.Result { guard let windowScene = windowScene else { return .systemAction } - - self.window = setupWindow(windowScene: windowScene) - + + window = setupWindow(windowScene: windowScene) + let configuration = SFSafariViewController.Configuration() configuration.entersReaderIfAvailable = UserPreferences.shared.inAppBrowserReaderView - + let safari = SFSafariViewController(url: url, configuration: configuration) safari.preferredBarTintColor = UIColor(Theme.shared.primaryBackgroundColor) safari.preferredControlTintColor = UIColor(Theme.shared.tintColor) safari.delegate = self - + DispatchQueue.main.async { [weak self] in self?.viewController.present(safari, animated: true) } - + return .handled } func setupWindow(windowScene: UIWindowScene) -> UIWindow { let window = self.window ?? UIWindow(windowScene: windowScene) - + window.rootViewController = viewController window.makeKeyAndVisible() - + switch Theme.shared.selectedScheme { case .dark: window.overrideUserInterfaceStyle = .dark case .light: window.overrideUserInterfaceStyle = .light } - + self.window = window return window } - func safariViewControllerDidFinish(_ controller: SFSafariViewController) { + func safariViewControllerDidFinish(_: SFSafariViewController) { window?.resignKey() window?.isHidden = false window = nil @@ -109,31 +109,30 @@ private class InAppSafariManager: NSObject, ObservableObject, SFSafariViewContro private struct WindowReader: UIViewRepresentable { var onUpdate: (UIWindow) -> Void - func makeUIView(context: Context) -> InjectView { + func makeUIView(context _: Context) -> InjectView { InjectView(onUpdate: onUpdate) } - func updateUIView(_ uiView: InjectView, context: Context) { - } + func updateUIView(_: InjectView, context _: Context) {} class InjectView: UIView { var onUpdate: (UIWindow) -> Void - + init(onUpdate: @escaping (UIWindow) -> Void) { self.onUpdate = onUpdate super.init(frame: .zero) isHidden = true isUserInteractionEnabled = false } - + @available(*, unavailable) - required init?(coder: NSCoder) { + required init?(coder _: NSCoder) { fatalError("init(coder:) has not been implemented") } - + override func willMove(toWindow newWindow: UIWindow?) { super.willMove(toWindow: newWindow) - + if let window = newWindow { onUpdate(window) } else { diff --git a/IceCubesApp/App/SideBarView.swift b/IceCubesApp/App/SideBarView.swift index 769047ed..ba3af48b 100644 --- a/IceCubesApp/App/SideBarView.swift +++ b/IceCubesApp/App/SideBarView.swift @@ -20,12 +20,13 @@ struct SideBarView: View { private func badgeFor(tab: Tab) -> Int { if tab == .notifications && selectedTab != tab, - let token = appAccounts.currentAccount.oauthToken { + let token = appAccounts.currentAccount.oauthToken + { return watcher.unreadNotificationsCount + userPreferences.getNotificationsCount(for: token) } return 0 } - + private func makeIconForTab(tab: Tab) -> some View { ZStack(alignment: .topTrailing) { SideBarIcon(systemIconName: tab.iconName, @@ -37,7 +38,7 @@ struct SideBarView: View { .contentShape(Rectangle()) .frame(width: .sidebarWidth, height: 50) } - + private func makeBadgeView(count: Int) -> some View { ZStack { Circle() @@ -78,8 +79,9 @@ struct SideBarView: View { ZStack(alignment: .topTrailing) { AppAccountView(viewModel: .init(appAccount: account, isCompact: true)) if showBadge, - let token = account.oauthToken, - userPreferences.getNotificationsCount(for: token) > 0 { + let token = account.oauthToken, + userPreferences.getNotificationsCount(for: token) > 0 + { makeBadgeView(count: userPreferences.getNotificationsCount(for: token)) } } diff --git a/IceCubesApp/App/Tabs/Settings/DisplaySettingsView.swift b/IceCubesApp/App/Tabs/Settings/DisplaySettingsView.swift index c7767965..d7ffbbf9 100644 --- a/IceCubesApp/App/Tabs/Settings/DisplaySettingsView.swift +++ b/IceCubesApp/App/Tabs/Settings/DisplaySettingsView.swift @@ -60,7 +60,7 @@ struct DisplaySettingsView: View { theme.chosenFont = UIFont(name: "OpenDyslexic", size: 1) case .hyperLegible: theme.chosenFont = UIFont(name: "Atkinson Hyperlegible", size: 1) - case.SFRounded: + case .SFRounded: theme.chosenFont = UIFont.systemFont(ofSize: 1).rounded() case .custom: isFontSelectorPresented = true diff --git a/IceCubesNotifications/NotificationService.swift b/IceCubesNotifications/NotificationService.swift index 269ce1b1..f484a291 100644 --- a/IceCubesNotifications/NotificationService.swift +++ b/IceCubesNotifications/NotificationService.swift @@ -64,7 +64,7 @@ class NotificationService: UNNotificationServiceExtension { bestAttemptContent.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "glass.caf")) let preferences = UserPreferences.shared - if let token = AppAccountsManager.shared.availableAccounts.first(where: { $0.oauthToken?.accessToken == notification.accessToken})?.oauthToken { + if let token = AppAccountsManager.shared.availableAccounts.first(where: { $0.oauthToken?.accessToken == notification.accessToken })?.oauthToken { var currentCount = preferences.getNotificationsCount(for: token) currentCount += 1 preferences.setNotification(count: currentCount, token: token) diff --git a/Packages/Account/Sources/Account/AccountDetailHeaderView.swift b/Packages/Account/Sources/Account/AccountDetailHeaderView.swift index 3bfa80e8..8ff8c086 100644 --- a/Packages/Account/Sources/Account/AccountDetailHeaderView.swift +++ b/Packages/Account/Sources/Account/AccountDetailHeaderView.swift @@ -150,9 +150,10 @@ struct AccountDetailHeaderView: View { } } } - + if let note = viewModel.relationship?.note, !note.isEmpty, - !viewModel.isCurrentUser { + !viewModel.isCurrentUser + { makeNoteView(note) } @@ -162,7 +163,7 @@ struct AccountDetailHeaderView: View { .environment(\.openURL, OpenURLAction { url in routerPath.handle(url: url) }) - + fieldsView } .padding(.horizontal, .layoutPadding) @@ -204,7 +205,7 @@ struct AccountDetailHeaderView: View { .padding(.top, 6) } } - + @ViewBuilder private func makeNoteView(_ note: String) -> some View { VStack(alignment: .leading, spacing: 4) { @@ -221,7 +222,7 @@ struct AccountDetailHeaderView: View { ) } } - + @ViewBuilder private var fieldsView: some View { if !viewModel.fields.isEmpty { diff --git a/Packages/Account/Sources/Account/AccountDetailView.swift b/Packages/Account/Sources/Account/AccountDetailView.swift index 8b43afd7..0963c63c 100644 --- a/Packages/Account/Sources/Account/AccountDetailView.swift +++ b/Packages/Account/Sources/Account/AccountDetailView.swift @@ -485,8 +485,7 @@ public struct AccountDetailView: View { private extension View { func applyAccountDetailsRowStyle(theme: Theme) -> some View { - self - .listRowInsets(.init()) + listRowInsets(.init()) .listRowSeparator(.hidden) .listRowBackground(theme.primaryBackgroundColor) } diff --git a/Packages/Account/Sources/Account/Edit/EditRelationshipNoteView.swift b/Packages/Account/Sources/Account/Edit/EditRelationshipNoteView.swift index 067d33bc..c8032e87 100644 --- a/Packages/Account/Sources/Account/Edit/EditRelationshipNoteView.swift +++ b/Packages/Account/Sources/Account/Edit/EditRelationshipNoteView.swift @@ -6,12 +6,12 @@ public struct EditRelationshipNoteView: View { @Environment(\.dismiss) private var dismiss @EnvironmentObject private var theme: Theme @EnvironmentObject private var client: Client - + // need this model to refresh after storing the new note on mastodon var accountDetailViewModel: AccountDetailViewModel - + @StateObject private var viewModel = EditRelationshipNoteViewModel() - + public var body: some View { NavigationStack { Form { @@ -31,8 +31,8 @@ public struct EditRelationshipNoteView: View { .alert("account.relation.note.edit.error.save.title", isPresented: $viewModel.saveError, actions: { - Button("alert.button.ok", action: {}) - }, message: { Text("account.relation.note.edit.error.save.message") }) + Button("alert.button.ok", action: {}) + }, message: { Text("account.relation.note.edit.error.save.message") }) .task { viewModel.client = client viewModel.relatedAccountId = accountDetailViewModel.accountId @@ -40,7 +40,7 @@ public struct EditRelationshipNoteView: View { } } } - + @ToolbarContentBuilder private var toolbarContent: some ToolbarContent { ToolbarItem(placement: .navigationBarLeading) { @@ -48,7 +48,7 @@ public struct EditRelationshipNoteView: View { dismiss() } } - + ToolbarItem(placement: .navigationBarTrailing) { Button { Task { diff --git a/Packages/Account/Sources/Account/Edit/EditRelationshipNoteViewModel.swift b/Packages/Account/Sources/Account/Edit/EditRelationshipNoteViewModel.swift index abdf6b1a..8b10f599 100644 --- a/Packages/Account/Sources/Account/Edit/EditRelationshipNoteViewModel.swift +++ b/Packages/Account/Sources/Account/Edit/EditRelationshipNoteViewModel.swift @@ -6,15 +6,16 @@ class EditRelationshipNoteViewModel: ObservableObject { public var note: String = "" public var relatedAccountId: String? public var client: Client? - + @Published var isSaving: Bool = false @Published var saveError: Bool = false - + init() {} - + func save() async { if relatedAccountId != nil, - client != nil { + client != nil + { isSaving = true do { let _ = try await client!.post(endpoint: Accounts.relationshipNote(id: relatedAccountId!, json: RelationshipNoteData(note: note))) diff --git a/Packages/AppAccount/Sources/AppAccount/AppAccountsSelectorView.swift b/Packages/AppAccount/Sources/AppAccount/AppAccountsSelectorView.swift index 91809a7d..5e3da11b 100644 --- a/Packages/AppAccount/Sources/AppAccount/AppAccountsSelectorView.swift +++ b/Packages/AppAccount/Sources/AppAccount/AppAccountsSelectorView.swift @@ -92,7 +92,8 @@ public struct AppAccountsSelectorView: View { Image(uiImage: image) } if let token = viewModel.appAccount.oauthToken, - preferences.getNotificationsCount(for: token) > 0 { + preferences.getNotificationsCount(for: token) > 0 + { Text("\(viewModel.account?.displayName ?? "") (\(preferences.getNotificationsCount(for: token)))") } else { Text("\(viewModel.account?.displayName ?? "")") diff --git a/Packages/DesignSystem/Sources/DesignSystem/Font.swift b/Packages/DesignSystem/Sources/DesignSystem/Font.swift index a8fcf474..c6458711 100644 --- a/Packages/DesignSystem/Sources/DesignSystem/Font.swift +++ b/Packages/DesignSystem/Sources/DesignSystem/Font.swift @@ -15,12 +15,10 @@ public extension Font { private static let onMac = ProcessInfo.processInfo.isiOSAppOnMac private static func customFont(size: CGFloat, relativeTo textStyle: TextStyle) -> Font { - if let chosenFont = Theme.shared.chosenFont { if chosenFont.fontName == ".AppleSystemUIFontRounded-Regular" { return .system(size: size, design: .rounded) - } - else { + } else { return .custom(chosenFont.fontName, size: size, relativeTo: textStyle) } } @@ -72,13 +70,11 @@ public extension Font { } } - - -extension UIFont { - public func rounded() -> UIFont { - guard let descriptor = fontDescriptor.withDesign(.rounded) else { - return self - } - return UIFont(descriptor: descriptor, size: pointSize) +public extension UIFont { + func rounded() -> UIFont { + guard let descriptor = fontDescriptor.withDesign(.rounded) else { + return self } + return UIFont(descriptor: descriptor, size: pointSize) + } } diff --git a/Packages/DesignSystem/Sources/DesignSystem/Theme.swift b/Packages/DesignSystem/Sources/DesignSystem/Theme.swift index 30e8f0f5..c66bde3e 100644 --- a/Packages/DesignSystem/Sources/DesignSystem/Theme.swift +++ b/Packages/DesignSystem/Sources/DesignSystem/Theme.swift @@ -27,7 +27,7 @@ public class Theme: ObservableObject { case .hyperLegible: return "Hyper Legible" case .SFRounded: - return "SF Rounded" + return "SF Rounded" case .custom: return "settings.display.font.custom" } @@ -87,7 +87,7 @@ public class Theme: ObservableObject { } } } - + public var chosenFont: UIFont? { get { guard let chosenFontData, diff --git a/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift b/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift index be099625..deb24e22 100644 --- a/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift +++ b/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift @@ -1,5 +1,5 @@ -import NukeUI import Nuke +import NukeUI import Shimmer import SwiftUI @@ -97,17 +97,17 @@ public struct AvatarView: View { } private struct AvatarPlaceholderView: View { - let size: AvatarView.Size + let size: AvatarView.Size - var body: some View { - if size == .badge { - Circle() - .fill(.gray) - .frame(width: size.size.width, height: size.size.height) - } else { - RoundedRectangle(cornerRadius: size.cornerRadius) - .fill(.gray) - .frame(width: size.size.width, height: size.size.height) - } + var body: some View { + if size == .badge { + Circle() + .fill(.gray) + .frame(width: size.size.width, height: size.size.height) + } else { + RoundedRectangle(cornerRadius: size.cornerRadius) + .fill(.gray) + .frame(width: size.size.width, height: size.size.height) } + } } diff --git a/Packages/Env/Sources/Env/CustomEnvValues.swift b/Packages/Env/Sources/Env/CustomEnvValues.swift index 95684881..528822b5 100644 --- a/Packages/Env/Sources/Env/CustomEnvValues.swift +++ b/Packages/Env/Sources/Env/CustomEnvValues.swift @@ -32,7 +32,7 @@ public extension EnvironmentValues { get { self[IsCompact.self] } set { self[IsCompact.self] = newValue } } - + var isInCaptureMode: Bool { get { self[IsInCaptureMode.self] } set { self[IsInCaptureMode.self] = newValue } diff --git a/Packages/Env/Sources/Env/UserPreferences.swift b/Packages/Env/Sources/Env/UserPreferences.swift index cf698df1..db6272df 100644 --- a/Packages/Env/Sources/Env/UserPreferences.swift +++ b/Packages/Env/Sources/Env/UserPreferences.swift @@ -96,13 +96,13 @@ public class UserPreferences: ObservableObject { public func setNotification(count: Int, token: OauthToken) { Self.sharedDefault?.set(count, forKey: "push_notifications_count_\(token.createdAt)") } - + public func getNotificationsCount(for token: OauthToken) -> Int { Self.sharedDefault?.integer(forKey: "push_notifications_count_\(token.createdAt)") ?? 0 } - + public func getNotificationsTotalCount(for tokens: [OauthToken]) -> Int { - var count: Int = 0 + var count = 0 for token in tokens { count += getNotificationsCount(for: token) } @@ -134,6 +134,3 @@ public class UserPreferences: ObservableObject { recentlyUsedLanguages = Array(copy.prefix(3)) } } - - - diff --git a/Packages/Models/Sources/Models/Poll.swift b/Packages/Models/Sources/Models/Poll.swift index ba1ed599..31f6cd7e 100644 --- a/Packages/Models/Sources/Models/Poll.swift +++ b/Packages/Models/Sources/Models/Poll.swift @@ -28,13 +28,11 @@ public struct Poll: Codable, Equatable, Hashable { public let voted: Bool? public let ownVotes: [Int]? public let options: [Option] - + // the votersCount can be null according to the docs when multiple is false. // Didn't find that to be true, but we make sure - public var safeVotersCount: Int { - get { - return votersCount ?? votesCount - } + public var safeVotersCount: Int { + return votersCount ?? votesCount } } diff --git a/Packages/Models/Sources/Models/Status.swift b/Packages/Models/Sources/Models/Status.swift index aada579f..0d170aaa 100644 --- a/Packages/Models/Sources/Models/Status.swift +++ b/Packages/Models/Sources/Models/Status.swift @@ -56,8 +56,8 @@ public protocol AnyStatus { } public struct StatusViewId: Hashable { - let id: String - let editedAt: ServerDate? + let id: String + let editedAt: ServerDate? } public extension AnyStatus { diff --git a/Packages/Network/Sources/Network/Endpoint/Accounts.swift b/Packages/Network/Sources/Network/Endpoint/Accounts.swift index 6104fdf9..db73d8d7 100644 --- a/Packages/Network/Sources/Network/Endpoint/Accounts.swift +++ b/Packages/Network/Sources/Network/Endpoint/Accounts.swift @@ -164,7 +164,7 @@ public struct MuteData: Encodable, Sendable { public struct RelationshipNoteData: Encodable, Sendable { public let comment: String - + public init(note comment: String) { self.comment = comment } diff --git a/Packages/Status/Sources/Status/Poll/StatusPollView.swift b/Packages/Status/Sources/Status/Poll/StatusPollView.swift index 35e76a60..55ba54de 100644 --- a/Packages/Status/Sources/Status/Poll/StatusPollView.swift +++ b/Packages/Status/Sources/Status/Poll/StatusPollView.swift @@ -26,7 +26,7 @@ public struct StatusPollView: View { return 0 } } - + private func percentForOption(option: Poll.Option) -> Int { let percent = ratioForOption(option: option) * 100 return Int(round(percent)) diff --git a/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift b/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift index 0f4af945..3ca02552 100644 --- a/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift +++ b/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift @@ -43,10 +43,10 @@ public class StatusRowViewModel: ObservableObject { var filter: Filtered? { status.reblog?.filtered?.first ?? status.filtered?.first } - + var isThread: Bool { status.reblog?.inReplyToId != nil || status.reblog?.inReplyToAccountId != nil || - status.inReplyToId != nil || status.inReplyToAccountId != nil + status.inReplyToId != nil || status.inReplyToAccountId != nil } var highlightRowColor: Color { diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift index 1042ef27..ab745ffc 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift @@ -8,11 +8,11 @@ struct StatusRowActionsView: View { @EnvironmentObject private var theme: Theme @EnvironmentObject private var currentAccount: CurrentAccount @ObservedObject var viewModel: StatusRowViewModel - + func privateBoost() -> Bool { - return self.viewModel.status.visibility == .priv && self.viewModel.status.account.id == self.currentAccount.account?.id + return viewModel.status.visibility == .priv && viewModel.status.account.id == currentAccount.account?.id } - + @MainActor enum Actions: CaseIterable { case respond, boost, favorite, bookmark, share @@ -22,10 +22,10 @@ struct StatusRowActionsView: View { case .respond: return "arrowshape.turn.up.left" case .boost: - if (privateBoost) { + if privateBoost { return viewModel.isReblogged ? "arrow.left.arrow.right.circle.fill" : "lock.rotation" } - + return viewModel.isReblogged ? "arrow.left.arrow.right.circle.fill" : "arrow.left.arrow.right.circle" case .favorite: return viewModel.isFavorited ? "star.fill" : "star" @@ -96,7 +96,7 @@ struct StatusRowActionsView: View { } .buttonStyle(.borderless) .disabled(action == .boost && - (viewModel.status.visibility == .direct || viewModel.status.visibility == .priv && viewModel.status.account.id != currentAccount.account?.id)) + (viewModel.status.visibility == .direct || viewModel.status.visibility == .priv && viewModel.status.account.id != currentAccount.account?.id)) Spacer() } } diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowCardView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowCardView.swift index b647a2d2..dec04926 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowCardView.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowCardView.swift @@ -8,7 +8,7 @@ import SwiftUI public struct StatusRowCardView: View { @Environment(\.openURL) private var openURL @Environment(\.isInCaptureMode) private var isInCaptureMode: Bool - + @EnvironmentObject private var theme: Theme let card: Card diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowContextMenu.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowContextMenu.swift index 9f98858f..c5b248e4 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowContextMenu.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowContextMenu.swift @@ -1,19 +1,19 @@ +import DesignSystem import Env import Foundation -import SwiftUI -import DesignSystem import Network +import SwiftUI struct StatusRowContextMenu: View { @Environment(\.displayScale) var displayScale - + @EnvironmentObject private var sceneDelegate: SceneDelegate @EnvironmentObject private var preferences: UserPreferences @EnvironmentObject private var account: CurrentAccount @EnvironmentObject private var currentInstance: CurrentInstance @ObservedObject var viewModel: StatusRowViewModel - + var boostLabel: some View { if self.viewModel.status.visibility == .priv && self.viewModel.status.account.id == self.account.account?.id { if self.viewModel.isReblogged { @@ -21,13 +21,13 @@ struct StatusRowContextMenu: View { } return Label("status.action.boost-to-followers", systemImage: "lock.rotation") } - + if self.viewModel.isReblogged { return Label("status.action.unboost", systemImage: "arrow.left.arrow.right.circle") } return Label("status.action.boost", systemImage: "arrow.left.arrow.right.circle") } - + var body: some View { if !viewModel.isRemote { Button { Task { @@ -85,11 +85,11 @@ struct StatusRowContextMenu: View { message: Text(viewModel.status.reblog?.content.asRawText ?? viewModel.status.content.asRawText)) { Label("status.action.share", systemImage: "square.and.arrow.up") } - + ShareLink(item: url) { Label("status.action.share-link", systemImage: "link") } - + Button { let view = HStack { StatusRowView(viewModel: viewModel) @@ -200,10 +200,10 @@ struct StatusRowContextMenu: View { struct ActivityView: UIViewControllerRepresentable { let image: Image - - func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIActivityViewController { + + func makeUIViewController(context _: UIViewControllerRepresentableContext) -> UIActivityViewController { return UIActivityViewController(activityItems: [image], applicationActivities: nil) } - - func updateUIViewController(_ uiViewController: UIActivityViewController, context: UIViewControllerRepresentableContext) {} + + func updateUIViewController(_: UIActivityViewController, context _: UIViewControllerRepresentableContext) {} } diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowHeaderView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowHeaderView.swift index 00f481c7..e7a840b1 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowHeaderView.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowHeaderView.swift @@ -1,7 +1,7 @@ import DesignSystem +import Env import Models import SwiftUI -import Env struct StatusRowHeaderView: View { @Environment(\.isInCaptureMode) private var isInCaptureMode: Bool @@ -57,19 +57,19 @@ struct StatusRowHeaderView: View { } if theme.avatarPosition == .top { dateView - .font(.scaledFootnote) - .foregroundColor(.gray) - .lineLimit(1) + .font(.scaledFootnote) + .foregroundColor(.gray) + .lineLimit(1) } } } } - + private var dateView: Text { Text(viewModel.status.account.bot ? "🤖 " : "") + - Text(status.createdAt.relativeFormatted) + - Text(" ⸱ ") + - Text(Image(systemName: viewModel.status.visibility.iconName)) + Text(status.createdAt.relativeFormatted) + + Text(" ⸱ ") + + Text(Image(systemName: viewModel.status.visibility.iconName)) } @ViewBuilder diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift index 8bde6ffb..4c9c5740 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift @@ -156,7 +156,8 @@ public struct StatusRowMediaPreviewView: View { case .image: if isInCaptureMode, let image = Nuke.ImagePipeline.shared.cache.cachedImage(for: .init(url: attachment.url, - processors: processors))?.image { + processors: processors))?.image + { Image(uiImage: image) .resizable() .aspectRatio(contentMode: .fill) @@ -243,10 +244,11 @@ public struct StatusRowMediaPreviewView: View { cornerSensitiveButton } if !isInCaptureMode, - let alt = attachment.description, + let alt = attachment.description, !alt.isEmpty, !isNotifications, - preferences.showAltTextForMedia { + preferences.showAltTextForMedia + { Button { altTextDisplayed = alt isAltAlertDisplayed = true diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowTextView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowTextView.swift index 795a782a..f4de959f 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowTextView.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowTextView.swift @@ -4,7 +4,7 @@ import SwiftUI struct StatusRowTextView: View { @EnvironmentObject private var theme: Theme - + let status: AnyStatus let viewModel: StatusRowViewModel diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowTranslateView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowTranslateView.swift index 3e3185ef..461b1921 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowTranslateView.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowTranslateView.swift @@ -5,7 +5,7 @@ import SwiftUI struct StatusRowTranslateView: View { @Environment(\.isInCaptureMode) private var isInCaptureMode: Bool - + @EnvironmentObject private var preferences: UserPreferences let status: AnyStatus @@ -27,7 +27,7 @@ struct StatusRowTranslateView: View { var body: some View { if !isInCaptureMode, - let userLang = preferences.serverPreferences?.postLanguage, + let userLang = preferences.serverPreferences?.postLanguage, shouldShowTranslateButton { Button { diff --git a/Packages/Timeline/Sources/Timeline/TimelineDatasource.swift b/Packages/Timeline/Sources/Timeline/TimelineDatasource.swift index a9be83c5..79983e4c 100644 --- a/Packages/Timeline/Sources/Timeline/TimelineDatasource.swift +++ b/Packages/Timeline/Sources/Timeline/TimelineDatasource.swift @@ -3,51 +3,51 @@ import Models actor TimelineDatasource { private var statuses: [Status] = [] - + var isEmpty: Bool { statuses.isEmpty } - + func get() -> [Status] { statuses } - + func reset() { statuses = [] } - + func indexOf(statusId: String) -> Int? { statuses.firstIndex(where: { $0.id == statusId }) } - + func contains(statusId: String) -> Bool { statuses.contains(where: { $0.id == statusId }) } - + func set(_ statuses: [Status]) { self.statuses = statuses } - + func append(_ status: Status) { statuses.append(status) } - + func append(contentOf: [Status]) { statuses.append(contentsOf: contentOf) } - + func insert(_ status: Status, at: Int) { statuses.insert(status, at: at) } - + func insert(contentOf: [Status], at: Int) { statuses.insert(contentsOf: contentOf, at: at) } - + func replace(_ status: Status, at: Int) { statuses[at] = status } - + func remove(_ statusId: String) { statuses.removeAll(where: { $0.id == statusId }) } diff --git a/Packages/Timeline/Sources/Timeline/TimelinePrefetcher.swift b/Packages/Timeline/Sources/Timeline/TimelinePrefetcher.swift index 166dec1a..68020c18 100644 --- a/Packages/Timeline/Sources/Timeline/TimelinePrefetcher.swift +++ b/Packages/Timeline/Sources/Timeline/TimelinePrefetcher.swift @@ -1,25 +1,25 @@ -import SwiftUI -import UIKit import Models import Nuke +import SwiftUI +import UIKit final class TimelinePrefetcher: NSObject, ObservableObject, UICollectionViewDataSourcePrefetching { private let prefetcher = ImagePrefetcher() weak var viewModel: TimelineViewModel? - func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) { + func collectionView(_: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) { let imageURLs = getImageURLs(for: indexPaths) prefetcher.startPrefetching(with: imageURLs) } - func collectionView(_ collectionView: UICollectionView, cancelPrefetchingForItemsAt indexPaths: [IndexPath]) { + func collectionView(_: UICollectionView, cancelPrefetchingForItemsAt indexPaths: [IndexPath]) { let imageURLs = getImageURLs(for: indexPaths) prefetcher.stopPrefetching(with: imageURLs) } private func getImageURLs(for indexPaths: [IndexPath]) -> [URL] { - guard let viewModel, case .display(let statuses, _) = viewModel.statusesState else { + guard let viewModel, case let .display(statuses, _) = viewModel.statusesState else { return [] } return indexPaths.compactMap { diff --git a/Packages/Timeline/Sources/Timeline/TimelineViewModel.swift b/Packages/Timeline/Sources/Timeline/TimelineViewModel.swift index a54e9319..14509629 100644 --- a/Packages/Timeline/Sources/Timeline/TimelineViewModel.swift +++ b/Packages/Timeline/Sources/Timeline/TimelineViewModel.swift @@ -92,7 +92,7 @@ class TimelineViewModel: ObservableObject { tag = try await client.get(endpoint: Tags.tag(id: id)) } catch {} } - + func reset() async { await datasource.reset() } @@ -214,7 +214,7 @@ extension TimelineViewModel: StatusesFetcher { updateMentionsToBeHighlighted(&statuses) ReblogCache.shared.removeDuplicateReblogs(&statuses) - + await datasource.set(statuses) await cacheHome() @@ -231,7 +231,7 @@ extension TimelineViewModel: StatusesFetcher { var newStatuses: [Status] = await fetchNewPages(minId: latestStatus.id, maxPages: 10) // Dedup statuses, a status with the same id could have been streamed in. - let ids = await datasource.get().map{ $0.id } + let ids = await datasource.get().map { $0.id } newStatuses = newStatuses.filter { status in !ids.contains(where: { $0 == status.id }) } @@ -322,10 +322,10 @@ extension TimelineViewModel: StatusesFetcher { var latestMinId = minId do { while var newStatuses: [Status] = - try await client.get(endpoint: timeline.endpoint(sinceId: nil, - maxId: nil, - minId: latestMinId, - offset: datasource.get().count)), + try await client.get(endpoint: timeline.endpoint(sinceId: nil, + maxId: nil, + minId: latestMinId, + offset: datasource.get().count)), !newStatuses.isEmpty, pagesLoaded < maxPages {