mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2025-01-05 13:58:40 +00:00
Run SwiftFormat
This commit is contained in:
parent
5991641d32
commit
a79c5691e0
49 changed files with 234 additions and 237 deletions
|
@ -220,7 +220,6 @@ class AppDelegate: NSObject, UIApplicationDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
func application(_: UIApplication, didFailToRegisterForRemoteNotificationsWithError _: Error) {}
|
func application(_: UIApplication, didFailToRegisterForRemoteNotificationsWithError _: Error) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ThemeObserverViewController: UIViewController {
|
class ThemeObserverViewController: UIViewController {
|
||||||
|
|
|
@ -84,7 +84,7 @@ struct SideBarView<Content: View>: View {
|
||||||
.frame(width: .sidebarWidth, height: 50)
|
.frame(width: .sidebarWidth, height: 50)
|
||||||
.padding(.vertical, 8)
|
.padding(.vertical, 8)
|
||||||
.background(selectedTab == .profile && account.id == appAccounts.currentAccount.id ?
|
.background(selectedTab == .profile && account.id == appAccounts.currentAccount.id ?
|
||||||
theme.secondaryBackgroundColor : .clear)
|
theme.secondaryBackgroundColor : .clear)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var tabsView: some View {
|
private var tabsView: some View {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import AppAccount
|
import AppAccount
|
||||||
import Env
|
import Env
|
||||||
|
import Models
|
||||||
import Network
|
import Network
|
||||||
import Notifications
|
import Notifications
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Timeline
|
import Timeline
|
||||||
import Models
|
|
||||||
|
|
||||||
struct NotificationsTab: View {
|
struct NotificationsTab: View {
|
||||||
@EnvironmentObject private var client: Client
|
@EnvironmentObject private var client: Client
|
||||||
|
|
|
@ -5,9 +5,9 @@ import Env
|
||||||
import Models
|
import Models
|
||||||
import Network
|
import Network
|
||||||
import NukeUI
|
import NukeUI
|
||||||
|
import SafariServices
|
||||||
import Shimmer
|
import Shimmer
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import SafariServices
|
|
||||||
|
|
||||||
struct AddAccountView: View {
|
struct AddAccountView: View {
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
@ -81,7 +81,7 @@ struct AddAccountView: View {
|
||||||
instanceNamePublisher.send(newValue)
|
instanceNamePublisher.send(newValue)
|
||||||
}
|
}
|
||||||
.onReceive(instanceNamePublisher.debounce(for: .milliseconds(500), scheduler: DispatchQueue.main)) { newValue in
|
.onReceive(instanceNamePublisher.debounce(for: .milliseconds(500), scheduler: DispatchQueue.main)) { newValue in
|
||||||
let newValue = newValue
|
let newValue = newValue
|
||||||
.replacingOccurrences(of: "http://", with: "")
|
.replacingOccurrences(of: "http://", with: "")
|
||||||
.replacingOccurrences(of: "https://", with: "")
|
.replacingOccurrences(of: "https://", with: "")
|
||||||
let client = Client(server: newValue)
|
let client = Client(server: newValue)
|
||||||
|
@ -171,8 +171,8 @@ struct AddAccountView: View {
|
||||||
(Text("instance.list.users-\(instance.users)")
|
(Text("instance.list.users-\(instance.users)")
|
||||||
+ Text(" ⸱ ")
|
+ Text(" ⸱ ")
|
||||||
+ Text("instance.list.posts-\(instance.statuses)"))
|
+ Text("instance.list.posts-\(instance.statuses)"))
|
||||||
.font(.scaledFootnote)
|
.font(.scaledFootnote)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
@ -235,11 +235,9 @@ struct AddAccountView: View {
|
||||||
struct SafariView: UIViewControllerRepresentable {
|
struct SafariView: UIViewControllerRepresentable {
|
||||||
let url: URL
|
let url: URL
|
||||||
|
|
||||||
func makeUIViewController(context: UIViewControllerRepresentableContext<SafariView>) -> SFSafariViewController {
|
func makeUIViewController(context _: UIViewControllerRepresentableContext<SafariView>) -> SFSafariViewController {
|
||||||
SFSafariViewController(url: url)
|
SFSafariViewController(url: url)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateUIViewController(_ uiViewController: SFSafariViewController, context: UIViewControllerRepresentableContext<SafariView>) {
|
func updateUIViewController(_: SFSafariViewController, context _: UIViewControllerRepresentableContext<SafariView>) {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
|
import Env
|
||||||
import Models
|
import Models
|
||||||
import Status
|
import Status
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Env
|
|
||||||
|
|
||||||
struct DisplaySettingsView: View {
|
struct DisplaySettingsView: View {
|
||||||
@EnvironmentObject private var theme: Theme
|
@EnvironmentObject private var theme: Theme
|
||||||
|
@ -16,15 +16,15 @@ struct DisplaySettingsView: View {
|
||||||
Toggle("settings.display.theme.systemColor", isOn: $theme.followSystemColorScheme)
|
Toggle("settings.display.theme.systemColor", isOn: $theme.followSystemColorScheme)
|
||||||
themeSelectorButton
|
themeSelectorButton
|
||||||
ColorPicker("settings.display.theme.tint", selection: $theme.tintColor)
|
ColorPicker("settings.display.theme.tint", selection: $theme.tintColor)
|
||||||
.onChange(of: theme.tintColor) { newValue in
|
.onChange(of: theme.tintColor) { _ in
|
||||||
theme.followSystemColorScheme = false
|
theme.followSystemColorScheme = false
|
||||||
}
|
}
|
||||||
ColorPicker("settings.display.theme.background", selection: $theme.primaryBackgroundColor)
|
ColorPicker("settings.display.theme.background", selection: $theme.primaryBackgroundColor)
|
||||||
.onChange(of: theme.primaryBackgroundColor) { newValue in
|
.onChange(of: theme.primaryBackgroundColor) { _ in
|
||||||
theme.followSystemColorScheme = false
|
theme.followSystemColorScheme = false
|
||||||
}
|
}
|
||||||
ColorPicker("settings.display.theme.secondary-background", selection: $theme.secondaryBackgroundColor)
|
ColorPicker("settings.display.theme.secondary-background", selection: $theme.secondaryBackgroundColor)
|
||||||
.onChange(of: theme.primaryBackgroundColor) { newValue in
|
.onChange(of: theme.primaryBackgroundColor) { _ in
|
||||||
theme.followSystemColorScheme = false
|
theme.followSystemColorScheme = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ struct DisplaySettingsView: View {
|
||||||
}
|
}
|
||||||
if ProcessInfo.processInfo.isiOSAppOnMac {
|
if ProcessInfo.processInfo.isiOSAppOnMac {
|
||||||
VStack {
|
VStack {
|
||||||
Slider(value: $userPreferences.fontSizeScale, in: 0.5...1.5, step: 0.1)
|
Slider(value: $userPreferences.fontSizeScale, in: 0.5 ... 1.5, step: 0.1)
|
||||||
Text("Font scaling: \(String(format: "%.1f", userPreferences.fontSizeScale))")
|
Text("Font scaling: \(String(format: "%.1f", userPreferences.fontSizeScale))")
|
||||||
.font(.scaledBody)
|
.font(.scaledBody)
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,11 +142,11 @@ struct SettingsTabs: View {
|
||||||
.tint(theme.labelColor)
|
.tint(theme.labelColor)
|
||||||
}
|
}
|
||||||
} header: {
|
} header: {
|
||||||
Text("settings.section.app")
|
Text("settings.section.app")
|
||||||
} footer: {
|
} footer: {
|
||||||
if let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
|
if let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
|
||||||
Text("App Version: \(appVersion)").frame(maxWidth: .infinity, alignment: .center)
|
Text("App Version: \(appVersion)").frame(maxWidth: .infinity, alignment: .center)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,8 +98,8 @@ struct AddRemoteTimelineView: View {
|
||||||
(Text("instance.list.users-\(instance.users)")
|
(Text("instance.list.users-\(instance.users)")
|
||||||
+ Text(" ⸱ ")
|
+ Text(" ⸱ ")
|
||||||
+ Text("instance.list.posts-\(instance.statuses)"))
|
+ Text("instance.list.posts-\(instance.statuses)"))
|
||||||
.font(.scaledFootnote)
|
.font(.scaledFootnote)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
|
|
@ -119,8 +119,8 @@ struct AccountDetailHeaderView: View {
|
||||||
relationship: relationship,
|
relationship: relationship,
|
||||||
shouldDisplayNotify: true,
|
shouldDisplayNotify: true,
|
||||||
relationshipUpdated: { relationship in
|
relationshipUpdated: { relationship in
|
||||||
viewModel.relationship = relationship
|
viewModel.relationship = relationship
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -377,7 +377,7 @@ public struct AccountDetailView: View {
|
||||||
if !viewModel.isCurrentUser {
|
if !viewModel.isCurrentUser {
|
||||||
Button {
|
Button {
|
||||||
routerPath.presentedSheet = .mentionStatusEditor(account: account,
|
routerPath.presentedSheet = .mentionStatusEditor(account: account,
|
||||||
visibility: preferences.serverPreferences?.postVisibility ?? .pub)
|
visibility: preferences.serverPreferences?.postVisibility ?? .pub)
|
||||||
} label: {
|
} label: {
|
||||||
Label("account.action.mention", systemImage: "at")
|
Label("account.action.mention", systemImage: "at")
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,14 +9,15 @@ public class FollowButtonViewModel: ObservableObject {
|
||||||
|
|
||||||
public let accountId: String
|
public let accountId: String
|
||||||
public let shouldDisplayNotify: Bool
|
public let shouldDisplayNotify: Bool
|
||||||
public let relationshipUpdated: ((Relationship) -> Void)
|
public let relationshipUpdated: (Relationship) -> Void
|
||||||
@Published public private(set) var relationship: Relationship
|
@Published public private(set) var relationship: Relationship
|
||||||
@Published public private(set) var isUpdating: Bool = false
|
@Published public private(set) var isUpdating: Bool = false
|
||||||
|
|
||||||
public init(accountId: String,
|
public init(accountId: String,
|
||||||
relationship: Relationship,
|
relationship: Relationship,
|
||||||
shouldDisplayNotify: Bool,
|
shouldDisplayNotify: Bool,
|
||||||
relationshipUpdated: @escaping ((Relationship) -> Void)) {
|
relationshipUpdated: @escaping ((Relationship) -> Void))
|
||||||
|
{
|
||||||
self.accountId = accountId
|
self.accountId = accountId
|
||||||
self.relationship = relationship
|
self.relationship = relationship
|
||||||
self.shouldDisplayNotify = shouldDisplayNotify
|
self.shouldDisplayNotify = shouldDisplayNotify
|
||||||
|
|
|
@ -20,7 +20,7 @@ struct ConversationsListRow: View {
|
||||||
VStack(alignment: .leading, spacing: 4) {
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
HStack {
|
HStack {
|
||||||
EmojiTextApp(.init(stringValue: conversation.accounts.map { $0.safeDisplayName }.joined(separator: ", ")),
|
EmojiTextApp(.init(stringValue: conversation.accounts.map { $0.safeDisplayName }.joined(separator: ", ")),
|
||||||
emojis: conversation.accounts.flatMap{ $0.emojis })
|
emojis: conversation.accounts.flatMap { $0.emojis })
|
||||||
.font(.scaledSubheadline)
|
.font(.scaledSubheadline)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundColor(theme.labelColor)
|
.foregroundColor(theme.labelColor)
|
||||||
|
|
|
@ -43,8 +43,7 @@ class ConversationsListViewModel: ObservableObject {
|
||||||
nextPage = nil
|
nextPage = nil
|
||||||
}
|
}
|
||||||
isLoadingNextPage = false
|
isLoadingNextPage = false
|
||||||
} catch {
|
} catch {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
public let availableColorsSets: [ColorSetCouple] =
|
public let availableColorsSets: [ColorSetCouple] =
|
||||||
[.init(light: IceCubeLight(), dark: IceCubeDark()),
|
[.init(light: IceCubeLight(), dark: IceCubeDark()),
|
||||||
.init(light: IceCubeNeonLight(), dark: IceCubeNeonDark()),
|
.init(light: IceCubeNeonLight(), dark: IceCubeNeonDark()),
|
||||||
.init(light: DesertLight(), dark: DesertDark()),
|
.init(light: DesertLight(), dark: DesertDark()),
|
||||||
.init(light: NemesisLight(), dark: NemesisDark()),
|
.init(light: NemesisLight(), dark: NemesisDark()),
|
||||||
.init(light: MediumLight(), dark: MediumDark())]
|
.init(light: MediumLight(), dark: MediumDark())]
|
||||||
|
|
||||||
public protocol ColorSet {
|
public protocol ColorSet {
|
||||||
var name: ColorSetName { get }
|
var name: ColorSetName { get }
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import SwiftUI
|
|
||||||
import Env
|
import Env
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
extension Font {
|
public extension Font {
|
||||||
|
static func userScaledFontSize(baseSize: CGFloat) -> CGFloat {
|
||||||
public static func userScaledFontSize(baseSize: CGFloat) -> CGFloat {
|
|
||||||
UIFontMetrics.default.scaledValue(for: baseSize * UserPreferences.shared.fontSizeScale)
|
UIFontMetrics.default.scaledValue(for: baseSize * UserPreferences.shared.fontSizeScale)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static var scaledTitle: Font {
|
static var scaledTitle: Font {
|
||||||
if ProcessInfo.processInfo.isiOSAppOnMac {
|
if ProcessInfo.processInfo.isiOSAppOnMac {
|
||||||
return .system(size: userScaledFontSize(baseSize: 28))
|
return .system(size: userScaledFontSize(baseSize: 28))
|
||||||
} else {
|
} else {
|
||||||
|
@ -16,7 +15,7 @@ extension Font {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static var scaledHeadline: Font {
|
static var scaledHeadline: Font {
|
||||||
if ProcessInfo.processInfo.isiOSAppOnMac {
|
if ProcessInfo.processInfo.isiOSAppOnMac {
|
||||||
return .system(size: userScaledFontSize(baseSize: 20), weight: .semibold)
|
return .system(size: userScaledFontSize(baseSize: 20), weight: .semibold)
|
||||||
} else {
|
} else {
|
||||||
|
@ -24,7 +23,7 @@ extension Font {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static var scaledBody: Font {
|
static var scaledBody: Font {
|
||||||
if ProcessInfo.processInfo.isiOSAppOnMac {
|
if ProcessInfo.processInfo.isiOSAppOnMac {
|
||||||
return .system(size: userScaledFontSize(baseSize: 19))
|
return .system(size: userScaledFontSize(baseSize: 19))
|
||||||
} else {
|
} else {
|
||||||
|
@ -32,7 +31,7 @@ extension Font {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static var scaledBodyUIFont: UIFont {
|
static var scaledBodyUIFont: UIFont {
|
||||||
if ProcessInfo.processInfo.isiOSAppOnMac {
|
if ProcessInfo.processInfo.isiOSAppOnMac {
|
||||||
return UIFont.systemFont(ofSize: userScaledFontSize(baseSize: 19))
|
return UIFont.systemFont(ofSize: userScaledFontSize(baseSize: 19))
|
||||||
} else {
|
} else {
|
||||||
|
@ -40,7 +39,7 @@ extension Font {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static var scaledCallout: Font {
|
static var scaledCallout: Font {
|
||||||
if ProcessInfo.processInfo.isiOSAppOnMac {
|
if ProcessInfo.processInfo.isiOSAppOnMac {
|
||||||
return .system(size: userScaledFontSize(baseSize: 17))
|
return .system(size: userScaledFontSize(baseSize: 17))
|
||||||
} else {
|
} else {
|
||||||
|
@ -48,7 +47,7 @@ extension Font {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static var scaledSubheadline: Font {
|
static var scaledSubheadline: Font {
|
||||||
if ProcessInfo.processInfo.isiOSAppOnMac {
|
if ProcessInfo.processInfo.isiOSAppOnMac {
|
||||||
return .system(size: userScaledFontSize(baseSize: 16))
|
return .system(size: userScaledFontSize(baseSize: 16))
|
||||||
} else {
|
} else {
|
||||||
|
@ -56,8 +55,7 @@ extension Font {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static var scaledFootnote: Font {
|
||||||
public static var scaledFootnote: Font {
|
|
||||||
if ProcessInfo.processInfo.isiOSAppOnMac {
|
if ProcessInfo.processInfo.isiOSAppOnMac {
|
||||||
return .system(size: userScaledFontSize(baseSize: 15))
|
return .system(size: userScaledFontSize(baseSize: 15))
|
||||||
} else {
|
} else {
|
||||||
|
@ -65,7 +63,7 @@ extension Font {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static var scaledCaption: Font {
|
static var scaledCaption: Font {
|
||||||
if ProcessInfo.processInfo.isiOSAppOnMac {
|
if ProcessInfo.processInfo.isiOSAppOnMac {
|
||||||
return .system(size: userScaledFontSize(baseSize: 14))
|
return .system(size: userScaledFontSize(baseSize: 14))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -29,12 +29,13 @@ struct ThemeApplier: ViewModifier {
|
||||||
.onAppear {
|
.onAppear {
|
||||||
// If theme is never set before set the default store. This should only execute once after install.
|
// If theme is never set before set the default store. This should only execute once after install.
|
||||||
if !theme.isThemePreviouslySet {
|
if !theme.isThemePreviouslySet {
|
||||||
theme.selectedSet = colorScheme == .dark ? .iceCubeDark : .iceCubeLight
|
theme.selectedSet = colorScheme == .dark ? .iceCubeDark : .iceCubeLight
|
||||||
theme.isThemePreviouslySet = true
|
theme.isThemePreviouslySet = true
|
||||||
} else if theme.followSystemColorScheme && theme.isThemePreviouslySet,
|
} else if theme.followSystemColorScheme, theme.isThemePreviouslySet,
|
||||||
let sets = availableColorsSets
|
let sets = availableColorsSets
|
||||||
.first(where: { $0.light.name == theme.selectedSet || $0.dark.name == theme.selectedSet }) {
|
.first(where: { $0.light.name == theme.selectedSet || $0.dark.name == theme.selectedSet })
|
||||||
theme.selectedSet = colorScheme == .dark ? sets.dark.name : sets.light.name
|
{
|
||||||
|
theme.selectedSet = colorScheme == .dark ? sets.dark.name : sets.light.name
|
||||||
}
|
}
|
||||||
setWindowTint(theme.tintColor)
|
setWindowTint(theme.tintColor)
|
||||||
setBarsColor(theme.primaryBackgroundColor)
|
setBarsColor(theme.primaryBackgroundColor)
|
||||||
|
@ -48,7 +49,8 @@ struct ThemeApplier: ViewModifier {
|
||||||
.onChange(of: colorScheme) { newColorScheme in
|
.onChange(of: colorScheme) { newColorScheme in
|
||||||
if theme.followSystemColorScheme,
|
if theme.followSystemColorScheme,
|
||||||
let sets = availableColorsSets
|
let sets = availableColorsSets
|
||||||
.first(where: { $0.light.name == theme.selectedSet || $0.dark.name == theme.selectedSet }) {
|
.first(where: { $0.light.name == theme.selectedSet || $0.dark.name == theme.selectedSet })
|
||||||
|
{
|
||||||
theme.selectedSet = newColorScheme == .dark ? sets.dark.name : sets.light.name
|
theme.selectedSet = newColorScheme == .dark ? sets.dark.name : sets.light.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,9 @@ public struct ExploreView: View {
|
||||||
loadingView
|
loadingView
|
||||||
} else if !viewModel.searchQuery.isEmpty {
|
} else if !viewModel.searchQuery.isEmpty {
|
||||||
if viewModel.isSearching {
|
if viewModel.isSearching {
|
||||||
HStack { }
|
HStack {}
|
||||||
.listRowBackground(theme.secondaryBackgroundColor)
|
.listRowBackground(theme.secondaryBackgroundColor)
|
||||||
.listRowSeparator(.hidden)
|
.listRowSeparator(.hidden)
|
||||||
} else if let results = viewModel.results[viewModel.searchQuery], !results.isEmpty {
|
} else if let results = viewModel.results[viewModel.searchQuery], !results.isEmpty {
|
||||||
makeSearchResultsView(results: results)
|
makeSearchResultsView(results: results)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -27,6 +27,7 @@ class ExploreViewModel: ObservableObject {
|
||||||
isSearching = true
|
isSearching = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Published var results: [String: SearchResults] = [:]
|
@Published var results: [String: SearchResults] = [:]
|
||||||
@Published var isLoaded = false
|
@Published var isLoaded = false
|
||||||
@Published var isSearching = false
|
@Published var isSearching = false
|
||||||
|
|
|
@ -20,6 +20,7 @@ public struct DeepLClient {
|
||||||
public let detectedSourceLanguage: String
|
public let detectedSourceLanguage: String
|
||||||
public let text: String
|
public let text: String
|
||||||
}
|
}
|
||||||
|
|
||||||
public let translations: [Translation]
|
public let translations: [Translation]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ public struct DeepLClient {
|
||||||
|
|
||||||
public init() {}
|
public init() {}
|
||||||
|
|
||||||
public func request(target: String, source: String?, text: String) async throws -> String {
|
public func request(target: String, source _: String?, text: String) async throws -> String {
|
||||||
do {
|
do {
|
||||||
var components = URLComponents(string: endpoint)!
|
var components = URLComponents(string: endpoint)!
|
||||||
var queryItems: [URLQueryItem] = []
|
var queryItems: [URLQueryItem] = []
|
||||||
|
|
|
@ -22,7 +22,7 @@ public struct NotificationsListView: View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
LazyVStack {
|
LazyVStack {
|
||||||
notificationsView
|
notificationsView
|
||||||
.frame(maxWidth: .maxColumnWidth)
|
.frame(maxWidth: .maxColumnWidth)
|
||||||
}
|
}
|
||||||
.padding(.top, .layoutPadding + 16)
|
.padding(.top, .layoutPadding + 16)
|
||||||
.background(theme.primaryBackgroundColor)
|
.background(theme.primaryBackgroundColor)
|
||||||
|
|
|
@ -43,8 +43,8 @@ class NotificationsViewModel: ObservableObject {
|
||||||
private var queryTypes: [String]? {
|
private var queryTypes: [String]? {
|
||||||
if let selectedType {
|
if let selectedType {
|
||||||
var excludedTypes = Models.Notification.NotificationType.allCases
|
var excludedTypes = Models.Notification.NotificationType.allCases
|
||||||
excludedTypes.removeAll(where: { $0 == selectedType})
|
excludedTypes.removeAll(where: { $0 == selectedType })
|
||||||
return excludedTypes.map{ $0.rawValue }
|
return excludedTypes.map { $0.rawValue }
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ class NotificationsViewModel: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleEvent(event: any StreamEvent) {
|
func handleEvent(event: any StreamEvent) {
|
||||||
if let event = event as? StreamEventNotification,
|
if let event = event as? StreamEventNotification,
|
||||||
!notifications.contains(where: { $0.id == event.notification.id })
|
!notifications.contains(where: { $0.id == event.notification.id })
|
||||||
{
|
{
|
||||||
if let selectedType, event.notification.type == selectedType.rawValue {
|
if let selectedType, event.notification.type == selectedType.rawValue {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
import Env
|
import Env
|
||||||
import Models
|
import Models
|
||||||
|
import NukeUI
|
||||||
import PhotosUI
|
import PhotosUI
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import NukeUI
|
|
||||||
|
|
||||||
struct StatusEditorAccessoryView: View {
|
struct StatusEditorAccessoryView: View {
|
||||||
@EnvironmentObject private var preferences: UserPreferences
|
@EnvironmentObject private var preferences: UserPreferences
|
||||||
|
|
|
@ -11,7 +11,7 @@ enum StatusEditorUTTypeSupported: String, CaseIterable {
|
||||||
case jpeg = "public.jpeg"
|
case jpeg = "public.jpeg"
|
||||||
case png = "public.png"
|
case png = "public.png"
|
||||||
|
|
||||||
static func types() -> [UTType] {
|
static func types() -> [UTType] {
|
||||||
[.url, .text, .plainText, .image, .jpeg, .png]
|
[.url, .text, .plainText, .image, .jpeg, .png]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,6 @@ public class StatusEditorViewModel: ObservableObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Status Text manipulations
|
// MARK: - Status Text manipulations
|
||||||
|
|
||||||
func insertStatusText(text: String) {
|
func insertStatusText(text: String) {
|
||||||
|
@ -245,7 +244,7 @@ public class StatusEditorViewModel: ObservableObject {
|
||||||
range: NSRange(location: range.location, length: range.length))
|
range: NSRange(location: range.location, length: range.length))
|
||||||
}
|
}
|
||||||
|
|
||||||
var mediaAdded: Bool = false
|
var mediaAdded = false
|
||||||
statusText.enumerateAttribute(.attachment, in: range) { attachment, range, _ in
|
statusText.enumerateAttribute(.attachment, in: range) { attachment, range, _ in
|
||||||
if let attachment = attachment as? NSTextAttachment, let image = attachment.image {
|
if let attachment = attachment as? NSTextAttachment, let image = attachment.image {
|
||||||
mediasImages.append(.init(image: image, mediaAttachment: nil, error: nil))
|
mediasImages.append(.init(image: image, mediaAttachment: nil, error: nil))
|
||||||
|
@ -262,6 +261,7 @@ public class StatusEditorViewModel: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Shar sheet / Item provider
|
// MARK: - Shar sheet / Item provider
|
||||||
|
|
||||||
private func processItemsProvider(items: [NSItemProvider]) {
|
private func processItemsProvider(items: [NSItemProvider]) {
|
||||||
Task {
|
Task {
|
||||||
var initialText: String = ""
|
var initialText: String = ""
|
||||||
|
@ -302,7 +302,6 @@ public class StatusEditorViewModel: ObservableObject {
|
||||||
return options.isEmpty ? nil : options
|
return options.isEmpty ? nil : options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Embeds
|
// MARK: - Embeds
|
||||||
|
|
||||||
private func checkEmbed() {
|
private func checkEmbed() {
|
||||||
|
@ -447,7 +446,7 @@ public class StatusEditorViewModel: ObservableObject {
|
||||||
if let index = indexOf(container: container) {
|
if let index = indexOf(container: container) {
|
||||||
do {
|
do {
|
||||||
let media: MediaAttachment = try await client.put(endpoint: Media.media(id: attachment.id,
|
let media: MediaAttachment = try await client.put(endpoint: Media.media(id: attachment.id,
|
||||||
description: description))
|
description: description))
|
||||||
mediasImages[index] = .init(image: nil, mediaAttachment: media, error: nil)
|
mediasImages[index] = .init(image: nil, mediaAttachment: media, error: nil)
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
@ -464,11 +463,12 @@ public class StatusEditorViewModel: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Custom emojis
|
// MARK: - Custom emojis
|
||||||
|
|
||||||
func fetchCustomEmojis() async {
|
func fetchCustomEmojis() async {
|
||||||
guard let client else { return }
|
guard let client else { return }
|
||||||
do {
|
do {
|
||||||
customEmojis = try await client.get(endpoint: CustomEmojis.customEmojis) ?? []
|
customEmojis = try await client.get(endpoint: CustomEmojis.customEmojis) ?? []
|
||||||
} catch { }
|
} catch {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import SwiftUI
|
import DesignSystem
|
||||||
import Models
|
import Models
|
||||||
import Network
|
import Network
|
||||||
import DesignSystem
|
import SwiftUI
|
||||||
|
|
||||||
public struct StatusEditHistoryView: View {
|
public struct StatusEditHistoryView: View {
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
@ -23,13 +23,13 @@ public struct StatusEditHistoryView: View {
|
||||||
Section {
|
Section {
|
||||||
if let history {
|
if let history {
|
||||||
ForEach(history) { edit in
|
ForEach(history) { edit in
|
||||||
VStack(alignment: .leading, spacing: 8){
|
VStack(alignment: .leading, spacing: 8) {
|
||||||
EmojiTextApp(edit.content, emojis: edit.emojis)
|
EmojiTextApp(edit.content, emojis: edit.emojis)
|
||||||
.font(.scaledBody)
|
.font(.scaledBody)
|
||||||
Group {
|
Group {
|
||||||
Text(edit.createdAt.asDate, style: .date) +
|
Text(edit.createdAt.asDate, style: .date) +
|
||||||
Text("status.summary.at-time") +
|
Text("status.summary.at-time") +
|
||||||
Text(edit.createdAt.asDate, style: .time)
|
Text(edit.createdAt.asDate, style: .time)
|
||||||
}
|
}
|
||||||
.font(.footnote)
|
.font(.footnote)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
|
|
|
@ -101,9 +101,9 @@ struct StatusActionsView: View {
|
||||||
Divider()
|
Divider()
|
||||||
HStack {
|
HStack {
|
||||||
Text(viewModel.status.createdAt.asDate, style: .date) +
|
Text(viewModel.status.createdAt.asDate, style: .date) +
|
||||||
Text("status.summary.at-time") +
|
Text("status.summary.at-time") +
|
||||||
Text(viewModel.status.createdAt.asDate, style: .time) +
|
Text(viewModel.status.createdAt.asDate, style: .time) +
|
||||||
Text(" ·")
|
Text(" ·")
|
||||||
Image(systemName: viewModel.status.visibility.iconName)
|
Image(systemName: viewModel.status.visibility.iconName)
|
||||||
Spacer()
|
Spacer()
|
||||||
Text(viewModel.status.application?.name ?? "")
|
Text(viewModel.status.application?.name ?? "")
|
||||||
|
@ -121,9 +121,9 @@ struct StatusActionsView: View {
|
||||||
Divider()
|
Divider()
|
||||||
HStack {
|
HStack {
|
||||||
Text("status.summary.edited-time") +
|
Text("status.summary.edited-time") +
|
||||||
Text(editedAt.asDate, style: .date) +
|
Text(editedAt.asDate, style: .date) +
|
||||||
Text("status.summary.at-time") +
|
Text("status.summary.at-time") +
|
||||||
Text(editedAt.asDate, style: .time)
|
Text(editedAt.asDate, style: .time)
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
import Env
|
import Env
|
||||||
import Models
|
import Models
|
||||||
|
import Nuke
|
||||||
import NukeUI
|
import NukeUI
|
||||||
import Shimmer
|
import Shimmer
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Nuke
|
|
||||||
|
|
||||||
public struct StatusMediaPreviewView: View {
|
public struct StatusMediaPreviewView: View {
|
||||||
@Environment(\.openURL) private var openURL
|
@Environment(\.openURL) private var openURL
|
||||||
|
@ -175,7 +175,6 @@ public struct StatusMediaPreviewView: View {
|
||||||
.fill(Color.gray)
|
.fill(Color.gray)
|
||||||
.frame(maxHeight: isNotifications || theme.statusDisplayStyle == .compact ? imageMaxHeight : nil)
|
.frame(maxHeight: isNotifications || theme.statusDisplayStyle == .compact ? imageMaxHeight : nil)
|
||||||
.shimmering()
|
.shimmering()
|
||||||
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -197,7 +196,6 @@ public struct StatusMediaPreviewView: View {
|
||||||
isAltAlertDisplayed = true
|
isAltAlertDisplayed = true
|
||||||
} label: {
|
} label: {
|
||||||
Text("ALT")
|
Text("ALT")
|
||||||
|
|
||||||
}
|
}
|
||||||
.padding(8)
|
.padding(8)
|
||||||
.background(.thinMaterial)
|
.background(.thinMaterial)
|
||||||
|
@ -298,7 +296,6 @@ public struct StatusMediaPreviewView: View {
|
||||||
Label("status.media.sensitive.show", systemImage: "eye")
|
Label("status.media.sensitive.show", systemImage: "eye")
|
||||||
} else {
|
} else {
|
||||||
Label("status.media.content.show", systemImage: "eye")
|
Label("status.media.content.show", systemImage: "eye")
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.buttonStyle(.borderedProminent)
|
.buttonStyle(.borderedProminent)
|
||||||
|
@ -307,14 +304,14 @@ public struct StatusMediaPreviewView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private var cornerSensitiveButton: some View {
|
private var cornerSensitiveButton: some View {
|
||||||
HStack{
|
HStack {
|
||||||
Button {
|
Button {
|
||||||
withAnimation {
|
withAnimation {
|
||||||
isHidingMedia = true
|
isHidingMedia = true
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
Image(systemName: "eye.slash")
|
Image(systemName: "eye.slash")
|
||||||
.frame(minHeight:21) // Match the alt button in case it is also present
|
.frame(minHeight: 21) // Match the alt button in case it is also present
|
||||||
}
|
}
|
||||||
.padding(10)
|
.padding(10)
|
||||||
.buttonStyle(.borderedProminent)
|
.buttonStyle(.borderedProminent)
|
||||||
|
@ -337,7 +334,7 @@ public struct StatusMediaPreviewView: View {
|
||||||
do {
|
do {
|
||||||
let image = try await ImagePipeline.shared.image(for: url).image
|
let image = try await ImagePipeline.shared.image(for: url).image
|
||||||
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
|
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
|
||||||
} catch { }
|
} catch {}
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
Label("status.media.contextmenu.save", systemImage: "square.and.arrow.down")
|
Label("status.media.contextmenu.save", systemImage: "square.and.arrow.down")
|
||||||
|
@ -347,7 +344,7 @@ public struct StatusMediaPreviewView: View {
|
||||||
do {
|
do {
|
||||||
let image = try await ImagePipeline.shared.image(for: url).image
|
let image = try await ImagePipeline.shared.image(for: url).image
|
||||||
UIPasteboard.general.image = image
|
UIPasteboard.general.image = image
|
||||||
} catch { }
|
} catch {}
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
Label("status.media.contextmenu.copy", systemImage: "doc.on.doc")
|
Label("status.media.contextmenu.copy", systemImage: "doc.on.doc")
|
||||||
|
|
|
@ -67,31 +67,31 @@ public struct StatusRowView: View {
|
||||||
viewModel.displaySpoiler = false
|
viewModel.displaySpoiler = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.contextMenu {
|
.contextMenu {
|
||||||
StatusRowContextMenu(viewModel: viewModel)
|
StatusRowContextMenu(viewModel: viewModel)
|
||||||
}
|
}
|
||||||
.accessibilityElement(children: viewModel.isFocused ? .contain : .combine)
|
.accessibilityElement(children: viewModel.isFocused ? .contain : .combine)
|
||||||
.accessibilityActions {
|
.accessibilityActions {
|
||||||
// Add the individual mentions as accessibility actions
|
// Add the individual mentions as accessibility actions
|
||||||
ForEach(viewModel.status.mentions, id: \.id) { mention in
|
ForEach(viewModel.status.mentions, id: \.id) { mention in
|
||||||
Button("@\(mention.username)") {
|
Button("@\(mention.username)") {
|
||||||
routerPath.navigate(to: .accountDetail(id: mention.id))
|
routerPath.navigate(to: .accountDetail(id: mention.id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Button(viewModel.displaySpoiler ? "status.show-more" : "status.show-less") {
|
Button(viewModel.displaySpoiler ? "status.show-more" : "status.show-less") {
|
||||||
withAnimation {
|
withAnimation {
|
||||||
viewModel.displaySpoiler.toggle()
|
viewModel.displaySpoiler.toggle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Button("@\(viewModel.status.account.username)") {
|
Button("@\(viewModel.status.account.username)") {
|
||||||
routerPath.navigate(to: .accountDetail(id: viewModel.status.account.id))
|
routerPath.navigate(to: .accountDetail(id: viewModel.status.account.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusRowContextMenu(viewModel: viewModel)
|
StatusRowContextMenu(viewModel: viewModel)
|
||||||
}
|
}
|
||||||
.background {
|
.background {
|
||||||
Color.clear
|
Color.clear
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
|
@ -125,15 +125,15 @@ public struct StatusRowView: View {
|
||||||
Text("status.row.was-boosted")
|
Text("status.row.was-boosted")
|
||||||
} else {
|
} else {
|
||||||
Text("status.row.you-boosted")
|
Text("status.row.you-boosted")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.accessibilityElement()
|
.accessibilityElement()
|
||||||
.accessibilityLabel(
|
.accessibilityLabel(
|
||||||
Text("\(viewModel.status.account.safeDisplayName)")
|
Text("\(viewModel.status.account.safeDisplayName)")
|
||||||
+ Text(" ")
|
+ Text(" ")
|
||||||
+ Text(viewModel.status.account.username != account.account?.username ? "status.row.was-boosted" : "status.row.you-boosted")
|
+ Text(viewModel.status.account.username != account.account?.username ? "status.row.was-boosted" : "status.row.you-boosted")
|
||||||
)
|
)
|
||||||
.font(.scaledFootnote)
|
.font(.scaledFootnote)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
|
@ -192,22 +192,22 @@ public struct StatusRowView: View {
|
||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
Spacer()
|
Spacer()
|
||||||
menuButton
|
menuButton
|
||||||
.accessibilityHidden(true)
|
.accessibilityHidden(true)
|
||||||
}
|
}
|
||||||
.accessibilityElement()
|
.accessibilityElement()
|
||||||
.accessibilityLabel(Text("\(status.account.displayName), \(status.createdAt.formatted)"))
|
.accessibilityLabel(Text("\(status.account.displayName), \(status.createdAt.formatted)"))
|
||||||
}
|
}
|
||||||
makeStatusContentView(status: status)
|
makeStatusContentView(status: status)
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
viewModel.navigateToDetail(routerPath: routerPath)
|
viewModel.navigateToDetail(routerPath: routerPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.accessibilityElement(children: viewModel.isFocused ? .contain : .combine)
|
.accessibilityElement(children: viewModel.isFocused ? .contain : .combine)
|
||||||
.accessibilityAction {
|
.accessibilityAction {
|
||||||
viewModel.navigateToDetail(routerPath: routerPath)
|
viewModel.navigateToDetail(routerPath: routerPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func makeStatusContentView(status: AnyStatus) -> some View {
|
private func makeStatusContentView(status: AnyStatus) -> some View {
|
||||||
|
@ -243,7 +243,7 @@ public struct StatusRowView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
makeMediasView(status: status)
|
makeMediasView(status: status)
|
||||||
.accessibilityHidden(!viewModel.isFocused)
|
.accessibilityHidden(!viewModel.isFocused)
|
||||||
makeCardView(status: status)
|
makeCardView(status: status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,7 +289,8 @@ public struct StatusRowView: View {
|
||||||
status.language != nil,
|
status.language != nil,
|
||||||
userLang != status.language,
|
userLang != status.language,
|
||||||
!status.content.asRawText.isEmpty,
|
!status.content.asRawText.isEmpty,
|
||||||
viewModel.translation == nil {
|
viewModel.translation == nil
|
||||||
|
{
|
||||||
Button {
|
Button {
|
||||||
Task {
|
Task {
|
||||||
await viewModel.translate(userLang: userLang)
|
await viewModel.translate(userLang: userLang)
|
||||||
|
|
Loading…
Reference in a new issue