mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-25 09:41:02 +00:00
Swiftformat
This commit is contained in:
parent
584a0d0432
commit
8a3c971402
120 changed files with 573 additions and 579 deletions
|
@ -155,8 +155,8 @@ struct ActivityView: UIViewControllerRepresentable {
|
|||
}
|
||||
|
||||
func makeUIViewController(context _: UIViewControllerRepresentableContext<ActivityView>) -> UIActivityViewController {
|
||||
return UIActivityViewController(activityItems: [image, LinkDelegate(image: image, status: status)],
|
||||
applicationActivities: nil)
|
||||
UIActivityViewController(activityItems: [image, LinkDelegate(image: image, status: status)],
|
||||
applicationActivities: nil)
|
||||
}
|
||||
|
||||
func updateUIViewController(_: UIActivityViewController, context _: UIViewControllerRepresentableContext<ActivityView>) {}
|
||||
|
|
|
@ -100,7 +100,7 @@ struct IceCubesApp: App {
|
|||
}
|
||||
|
||||
private func badgeFor(tab: Tab) -> Int {
|
||||
if tab == .notifications && selectedTab != tab,
|
||||
if tab == .notifications, selectedTab != tab,
|
||||
let token = appAccountsManager.currentAccount.oauthToken
|
||||
{
|
||||
return watcher.unreadNotificationsCount + userPreferences.getNotificationsCount(for: token)
|
||||
|
|
|
@ -13,7 +13,7 @@ struct QuickLookPreview: UIViewControllerRepresentable {
|
|||
let urls: [URL]
|
||||
|
||||
func makeUIViewController(context _: Context) -> UIViewController {
|
||||
return AppQLPreviewController(selectedURL: selectedURL, urls: urls)
|
||||
AppQLPreviewController(selectedURL: selectedURL, urls: urls)
|
||||
}
|
||||
|
||||
func updateUIViewController(
|
||||
|
@ -53,11 +53,11 @@ class AppQLPreviewController: UIViewController {
|
|||
|
||||
extension AppQLPreviewController: QLPreviewControllerDataSource {
|
||||
nonisolated func numberOfPreviewItems(in _: QLPreviewController) -> Int {
|
||||
return urls.count
|
||||
urls.count
|
||||
}
|
||||
|
||||
nonisolated func previewController(_: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
|
||||
return urls[index] as QLPreviewItem
|
||||
urls[index] as QLPreviewItem
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ extension AppQLPreviewController: QLPreviewControllerDelegate {
|
|||
|
||||
struct TransparentBackground: UIViewControllerRepresentable {
|
||||
public func makeUIViewController(context _: Context) -> UIViewController {
|
||||
return TransparentController()
|
||||
TransparentController()
|
||||
}
|
||||
|
||||
public func updateUIViewController(_: UIViewController, context _: Context) {}
|
||||
|
|
|
@ -51,7 +51,7 @@ private struct SafariRouter: ViewModifier {
|
|||
}
|
||||
.background {
|
||||
WindowReader { window in
|
||||
self.safariManager.windowScene = window.windowScene
|
||||
safariManager.windowScene = window.windowScene
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ private class InAppSafariManager: NSObject, ObservableObject, SFSafariViewContro
|
|||
|
||||
@MainActor
|
||||
func open(_ url: URL) -> OpenURLAction.Result {
|
||||
guard let windowScene = windowScene else { return .systemAction }
|
||||
guard let windowScene else { return .systemAction }
|
||||
|
||||
window = setupWindow(windowScene: windowScene)
|
||||
|
||||
|
@ -85,7 +85,7 @@ private class InAppSafariManager: NSObject, ObservableObject, SFSafariViewContro
|
|||
}
|
||||
|
||||
func setupWindow(windowScene: UIWindowScene) -> UIWindow {
|
||||
let window = self.window ?? UIWindow(windowScene: windowScene)
|
||||
let window = window ?? UIWindow(windowScene: windowScene)
|
||||
|
||||
window.rootViewController = viewController
|
||||
window.makeKeyAndVisible()
|
||||
|
|
|
@ -19,7 +19,7 @@ struct SideBarView<Content: View>: View {
|
|||
@ViewBuilder var content: () -> Content
|
||||
|
||||
private func badgeFor(tab: Tab) -> Int {
|
||||
if tab == .notifications && selectedTab != tab,
|
||||
if tab == .notifications, selectedTab != tab,
|
||||
let token = appAccounts.currentAccount.oauthToken
|
||||
{
|
||||
return watcher.unreadNotificationsCount + userPreferences.getNotificationsCount(for: token)
|
||||
|
|
|
@ -29,7 +29,7 @@ struct ExploreTab: View {
|
|||
AppAccountsSelectorView(routerPath: routerPath)
|
||||
}
|
||||
}
|
||||
if UIDevice.current.userInterfaceIdiom == .pad && !preferences.showiPadSecondaryColumn {
|
||||
if UIDevice.current.userInterfaceIdiom == .pad, !preferences.showiPadSecondaryColumn {
|
||||
SecondaryColumnToolbarItem()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,11 +100,11 @@ struct AddAccountView: View {
|
|||
Task {
|
||||
do {
|
||||
// bare bones preflight for domain validity
|
||||
if client.server.contains(".") && client.server.last != "." {
|
||||
if client.server.contains("."), client.server.last != "." {
|
||||
let instance: Instance = try await client.get(endpoint: Instances.instance)
|
||||
withAnimation {
|
||||
self.instance = instance
|
||||
self.instanceName = sanitizedName // clean up the text box, principally to chop off the username if present so it's clear that you might not wind up siging in as the thing in the box
|
||||
instanceName = sanitizedName // clean up the text box, principally to chop off the username if present so it's clear that you might not wind up siging in as the thing in the box
|
||||
}
|
||||
instanceFetchError = nil
|
||||
} else {
|
||||
|
@ -178,7 +178,7 @@ struct AddAccountView: View {
|
|||
} else {
|
||||
ForEach(sanitizedName.isEmpty ? instances : instances.filter { $0.name.contains(sanitizedName.lowercased()) }) { instance in
|
||||
Button {
|
||||
self.instanceName = instance.name
|
||||
instanceName = instance.name
|
||||
} label: {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(instance.name)
|
||||
|
|
|
@ -87,12 +87,13 @@ struct ContentSettingsView: View {
|
|||
Picker("settings.content.default-reply-visibility", selection: $userPreferences.appDefaultReplyVisibility) {
|
||||
ForEach(Visibility.allCases, id: \.rawValue) { vis in
|
||||
if UserPreferences.getIntOfVisibility(vis) <=
|
||||
UserPreferences.getIntOfVisibility(userPreferences.postVisibility) {
|
||||
UserPreferences.getIntOfVisibility(userPreferences.postVisibility)
|
||||
{
|
||||
Text(vis.title).tag(vis)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: userPreferences.postVisibility) { newValue in
|
||||
.onChange(of: userPreferences.postVisibility) { _ in
|
||||
userPreferences.conformReplyVisibilityConstraints()
|
||||
}
|
||||
|
||||
|
|
|
@ -32,9 +32,9 @@ struct IconSelectorView: View {
|
|||
var appIconName: String {
|
||||
switch self {
|
||||
case .primary:
|
||||
return "AppIcon"
|
||||
"AppIcon"
|
||||
default:
|
||||
return "AppIconAlternate\(rawValue)"
|
||||
"AppIconAlternate\(rawValue)"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,6 +120,6 @@ struct IconSelectorView: View {
|
|||
|
||||
extension String {
|
||||
var localized: String {
|
||||
return NSLocalizedString(self, comment: "")
|
||||
NSLocalizedString(self, comment: "")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ struct SettingsTabs: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
if UIDevice.current.userInterfaceIdiom == .pad && !preferences.showiPadSecondaryColumn {
|
||||
if UIDevice.current.userInterfaceIdiom == .pad, !preferences.showiPadSecondaryColumn {
|
||||
SecondaryColumnToolbarItem()
|
||||
}
|
||||
}
|
||||
|
@ -326,7 +326,6 @@ struct SettingsTabs: View {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private func moveTimelineItems(from source: IndexSet, to destination: Int) {
|
||||
preferences.remoteLocalTimelines.move(fromOffsets: source, toOffset: destination)
|
||||
}
|
||||
|
|
|
@ -19,30 +19,30 @@ struct SupportAppView: View {
|
|||
var title: LocalizedStringKey {
|
||||
switch self {
|
||||
case .one:
|
||||
return "settings.support.one.title"
|
||||
"settings.support.one.title"
|
||||
case .two:
|
||||
return "settings.support.two.title"
|
||||
"settings.support.two.title"
|
||||
case .three:
|
||||
return "settings.support.three.title"
|
||||
"settings.support.three.title"
|
||||
case .four:
|
||||
return "settings.support.four.title"
|
||||
"settings.support.four.title"
|
||||
case .supporter:
|
||||
return "settings.support.supporter.title"
|
||||
"settings.support.supporter.title"
|
||||
}
|
||||
}
|
||||
|
||||
var subtitle: LocalizedStringKey {
|
||||
switch self {
|
||||
case .one:
|
||||
return "settings.support.one.subtitle"
|
||||
"settings.support.one.subtitle"
|
||||
case .two:
|
||||
return "settings.support.two.subtitle"
|
||||
"settings.support.two.subtitle"
|
||||
case .three:
|
||||
return "settings.support.three.subtitle"
|
||||
"settings.support.three.subtitle"
|
||||
case .four:
|
||||
return "settings.support.four.subtitle"
|
||||
"settings.support.four.subtitle"
|
||||
case .supporter:
|
||||
return "settings.support.supporter.subtitle"
|
||||
"settings.support.supporter.subtitle"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,8 +103,8 @@ struct SupportAppView: View {
|
|||
}
|
||||
|
||||
private func fetchStoreProducts() {
|
||||
Purchases.shared.getProducts(Tip.allCases.map { $0.productId }) { products in
|
||||
self.subscription = products.first(where: { $0.productIdentifier == Tip.supporter.productId })
|
||||
Purchases.shared.getProducts(Tip.allCases.map(\.productId)) { products in
|
||||
subscription = products.first(where: { $0.productIdentifier == Tip.supporter.productId })
|
||||
self.products = products.filter { $0.productIdentifier != Tip.supporter.productId }.sorted(by: { $0.price < $1.price })
|
||||
withAnimation {
|
||||
loadingProducts = false
|
||||
|
@ -114,7 +114,7 @@ struct SupportAppView: View {
|
|||
|
||||
private func refreshUserInfo() {
|
||||
Purchases.shared.getCustomerInfo { info, _ in
|
||||
self.customerInfo = info
|
||||
customerInfo = info
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,7 +221,7 @@ struct SupportAppView: View {
|
|||
Spacer()
|
||||
Button {
|
||||
Purchases.shared.restorePurchases { info, _ in
|
||||
self.customerInfo = info
|
||||
customerInfo = info
|
||||
}
|
||||
} label: {
|
||||
Text("settings.support.restore-purchase.button")
|
||||
|
|
|
@ -68,7 +68,7 @@ struct SwipeActionsSettingsView: View {
|
|||
}
|
||||
|
||||
private func createStatusActionPicker(selection: Binding<StatusAction>, label: LocalizedStringKey) -> some View {
|
||||
return Picker(selection: selection, label: Text(label)) {
|
||||
Picker(selection: selection, label: Text(label)) {
|
||||
Section {
|
||||
Text(StatusAction.none.displayName()).tag(StatusAction.none)
|
||||
}
|
||||
|
|
|
@ -86,27 +86,27 @@ enum Tab: Int, Identifiable, Hashable {
|
|||
var iconName: String {
|
||||
switch self {
|
||||
case .timeline:
|
||||
return "rectangle.stack"
|
||||
"rectangle.stack"
|
||||
case .trending:
|
||||
return "chart.line.uptrend.xyaxis"
|
||||
"chart.line.uptrend.xyaxis"
|
||||
case .local:
|
||||
return "person.2"
|
||||
"person.2"
|
||||
case .federated:
|
||||
return "globe.americas"
|
||||
"globe.americas"
|
||||
case .notifications:
|
||||
return "bell"
|
||||
"bell"
|
||||
case .mentions:
|
||||
return "at"
|
||||
"at"
|
||||
case .explore:
|
||||
return "magnifyingglass"
|
||||
"magnifyingglass"
|
||||
case .messages:
|
||||
return "tray"
|
||||
"tray"
|
||||
case .settings:
|
||||
return "gear"
|
||||
"gear"
|
||||
case .profile:
|
||||
return "person.crop.circle"
|
||||
"person.crop.circle"
|
||||
case .other:
|
||||
return ""
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ struct AddRemoteTimelineView: View {
|
|||
isInstanceURLFieldFocused = true
|
||||
let client = InstanceSocialClient()
|
||||
Task {
|
||||
self.instances = await client.fetchInstances()
|
||||
instances = await client.fetchInstances()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ struct AddRemoteTimelineView: View {
|
|||
} else {
|
||||
ForEach(instanceName.isEmpty ? instances : instances.filter { $0.name.contains(instanceName.lowercased()) }) { instance in
|
||||
Button {
|
||||
self.instanceName = instance.name
|
||||
instanceName = instance.name
|
||||
} label: {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(instance.name)
|
||||
|
|
|
@ -171,7 +171,8 @@ struct EditTagGroupView: View {
|
|||
additional: toSave
|
||||
)
|
||||
if let editingTagGroup,
|
||||
let index = preferences.tagGroups.firstIndex(of: editingTagGroup) {
|
||||
let index = preferences.tagGroups.firstIndex(of: editingTagGroup)
|
||||
{
|
||||
preferences.tagGroups[index] = tagGroup
|
||||
} else {
|
||||
preferences.tagGroups.append(tagGroup)
|
||||
|
@ -183,7 +184,7 @@ struct EditTagGroupView: View {
|
|||
|
||||
@ViewBuilder
|
||||
private var symbolsSuggestionView: some View {
|
||||
if focusedField == .symbol && !sfSymbolName.isEmpty {
|
||||
if focusedField == .symbol, !sfSymbolName.isEmpty {
|
||||
let filteredMatches = allSymbols
|
||||
.filter { $0.contains(sfSymbolName) }
|
||||
if !filteredMatches.isEmpty {
|
||||
|
|
|
@ -9,5 +9,5 @@ import Foundation
|
|||
import SFSafeSymbols
|
||||
|
||||
let allSymbols: [String] = SFSymbol.allSymbols.map { symbol in
|
||||
symbol.rawValue
|
||||
symbol.rawValue
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ struct TimelineTab: View {
|
|||
}
|
||||
.onAppear {
|
||||
routerPath.client = client
|
||||
if !didAppear && canFilterTimeline {
|
||||
if !didAppear, canFilterTimeline {
|
||||
didAppear = true
|
||||
if client.isAuth {
|
||||
timeline = lastTimelineFilter
|
||||
|
@ -97,7 +97,7 @@ struct TimelineTab: View {
|
|||
private var timelineFilterButton: some View {
|
||||
if timeline.supportNewestPagination {
|
||||
Button {
|
||||
self.timeline = .latest
|
||||
timeline = .latest
|
||||
} label: {
|
||||
Label(TimelineFilter.latest.localizedTitle(), systemImage: TimelineFilter.latest.iconName() ?? "")
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ struct TimelineTab: View {
|
|||
}
|
||||
statusEditorToolbarItem(routerPath: routerPath,
|
||||
visibility: preferences.postVisibility)
|
||||
if UIDevice.current.userInterfaceIdiom == .pad && !preferences.showiPadSecondaryColumn {
|
||||
if UIDevice.current.userInterfaceIdiom == .pad, !preferences.showiPadSecondaryColumn {
|
||||
SecondaryColumnToolbarItem()
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -70,7 +70,7 @@ class NotificationService: UNNotificationServiceExtension {
|
|||
preferences.setNotification(count: currentCount, token: token)
|
||||
}
|
||||
|
||||
let tokens = AppAccountsManager.shared.pushAccounts.map { $0.token }
|
||||
let tokens = AppAccountsManager.shared.pushAccounts.map(\.token)
|
||||
bestAttemptContent.badge = .init(integerLiteral: preferences.getNotificationsTotalCount(for: tokens))
|
||||
|
||||
if let urlString = notification.icon,
|
||||
|
|
|
@ -29,7 +29,7 @@ let package = Package(
|
|||
.product(name: "Status", package: "Status"),
|
||||
],
|
||||
swiftSettings: [
|
||||
.enableExperimentalFeature("StrictConcurrency")
|
||||
.enableExperimentalFeature("StrictConcurrency"),
|
||||
]
|
||||
),
|
||||
.testTarget(
|
||||
|
|
|
@ -89,7 +89,7 @@ public struct AccountDetailView: View {
|
|||
viewModel.client = client
|
||||
|
||||
// Avoid capturing non-Sendable `self` just to access the view model.
|
||||
let viewModel = self.viewModel
|
||||
let viewModel = viewModel
|
||||
Task {
|
||||
await withTaskGroup(of: Void.self) { group in
|
||||
group.addTask { await viewModel.fetchAccount() }
|
||||
|
|
|
@ -27,25 +27,25 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
|
|||
|
||||
var iconName: String {
|
||||
switch self {
|
||||
case .statuses: return "bubble.right"
|
||||
case .favorites: return "star"
|
||||
case .bookmarks: return "bookmark"
|
||||
case .followedTags: return "tag"
|
||||
case .postsAndReplies: return "bubble.left.and.bubble.right"
|
||||
case .media: return "photo.on.rectangle.angled"
|
||||
case .lists: return "list.bullet"
|
||||
case .statuses: "bubble.right"
|
||||
case .favorites: "star"
|
||||
case .bookmarks: "bookmark"
|
||||
case .followedTags: "tag"
|
||||
case .postsAndReplies: "bubble.left.and.bubble.right"
|
||||
case .media: "photo.on.rectangle.angled"
|
||||
case .lists: "list.bullet"
|
||||
}
|
||||
}
|
||||
|
||||
var accessibilityLabel: LocalizedStringKey {
|
||||
switch self {
|
||||
case .statuses: return "accessibility.tabs.profile.picker.statuses"
|
||||
case .favorites: return "accessibility.tabs.profile.picker.favorites"
|
||||
case .bookmarks: return "accessibility.tabs.profile.picker.bookmarks"
|
||||
case .followedTags: return "accessibility.tabs.profile.picker.followed-tags"
|
||||
case .postsAndReplies: return "accessibility.tabs.profile.picker.posts-and-replies"
|
||||
case .media: return "accessibility.tabs.profile.picker.media"
|
||||
case .lists: return "accessibility.tabs.profile.picker.lists"
|
||||
case .statuses: "accessibility.tabs.profile.picker.statuses"
|
||||
case .favorites: "accessibility.tabs.profile.picker.favorites"
|
||||
case .bookmarks: "accessibility.tabs.profile.picker.bookmarks"
|
||||
case .followedTags: "accessibility.tabs.profile.picker.followed-tags"
|
||||
case .postsAndReplies: "accessibility.tabs.profile.picker.posts-and-replies"
|
||||
case .media: "accessibility.tabs.profile.picker.media"
|
||||
case .lists: "accessibility.tabs.profile.picker.lists"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
|
|||
private func fetchAccountData(accountId: String, client: Client) async throws -> AccountData {
|
||||
async let account: Account = client.get(endpoint: Accounts.accounts(id: accountId))
|
||||
async let featuredTags: [FeaturedTag] = client.get(endpoint: Accounts.featuredTags(id: accountId))
|
||||
if client.isAuth && !isCurrentUser {
|
||||
if client.isAuth, !isCurrentUser {
|
||||
async let relationships: [Relationship] = client.get(endpoint: Accounts.relationships(ids: [accountId]))
|
||||
do {
|
||||
return try await .init(account: account,
|
||||
|
|
|
@ -10,15 +10,15 @@ public enum AccountsListMode {
|
|||
var title: LocalizedStringKey {
|
||||
switch self {
|
||||
case .following:
|
||||
return "account.following"
|
||||
"account.following"
|
||||
case .followers:
|
||||
return "account.followers"
|
||||
"account.followers"
|
||||
case .favoritedBy:
|
||||
return "account.favorited-by"
|
||||
"account.favorited-by"
|
||||
case .rebloggedBy:
|
||||
return "account.boosted-by"
|
||||
"account.boosted-by"
|
||||
case .accountsList:
|
||||
return ""
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ class AccountsListViewModel: ObservableObject {
|
|||
}
|
||||
nextPageId = link?.maxId
|
||||
relationships = try await client.get(endpoint:
|
||||
Accounts.relationships(ids: accounts.map { $0.id }))
|
||||
Accounts.relationships(ids: accounts.map(\.id)))
|
||||
state = .display(accounts: accounts,
|
||||
relationships: relationships,
|
||||
nextPageState: link?.maxId != nil ? .hasNextPage : .none)
|
||||
|
@ -108,7 +108,7 @@ class AccountsListViewModel: ObservableObject {
|
|||
}
|
||||
accounts.append(contentsOf: newAccounts)
|
||||
let newRelationships: [Relationship] =
|
||||
try await client.get(endpoint: Accounts.relationships(ids: newAccounts.map { $0.id }))
|
||||
try await client.get(endpoint: Accounts.relationships(ids: newAccounts.map(\.id)))
|
||||
|
||||
relationships.append(contentsOf: newRelationships)
|
||||
self.nextPageId = link?.maxId
|
||||
|
|
|
@ -28,15 +28,13 @@ struct EditFilterView: View {
|
|||
@FocusState private var focusedField: Fields?
|
||||
|
||||
private var data: ServerFilterData {
|
||||
var expiresIn: String?
|
||||
// we add 50 seconds, otherwise we immediately show 6d for a 7d filter (6d, 23h, 59s)
|
||||
switch expirySelection {
|
||||
let expiresIn: String? = switch expirySelection {
|
||||
case .infinite:
|
||||
expiresIn = "" // need to send an empty value in order for the server to clear this field in the filter
|
||||
"" // need to send an empty value in order for the server to clear this field in the filter
|
||||
case .custom:
|
||||
expiresIn = String(Int(expiresAt?.timeIntervalSince(Date()) ?? 0) + 50)
|
||||
String(Int(expiresAt?.timeIntervalSince(Date()) ?? 0) + 50)
|
||||
default:
|
||||
expiresIn = String(expirySelection.rawValue + 50)
|
||||
String(expirySelection.rawValue + 50)
|
||||
}
|
||||
|
||||
return ServerFilterData(title: title,
|
||||
|
@ -100,7 +98,7 @@ struct EditFilterView: View {
|
|||
}
|
||||
if expirySelection != .infinite {
|
||||
DatePicker("filter.edit.expiry.date-time",
|
||||
selection: Binding<Date>(get: { self.expiresAt ?? Date() }, set: { self.expiresAt = $0 }),
|
||||
selection: Binding<Date>(get: { expiresAt ?? Date() }, set: { expiresAt = $0 }),
|
||||
displayedComponents: [.date, .hourAndMinute])
|
||||
.disabled(expirySelection != .custom)
|
||||
}
|
||||
|
|
|
@ -19,11 +19,11 @@ public struct FiltersListView: View {
|
|||
public var body: some View {
|
||||
NavigationStack {
|
||||
Form {
|
||||
if !isLoading && filters.isEmpty {
|
||||
if !isLoading, filters.isEmpty {
|
||||
EmptyView()
|
||||
} else {
|
||||
Section {
|
||||
if isLoading && filters.isEmpty {
|
||||
if isLoading, filters.isEmpty {
|
||||
ProgressView()
|
||||
} else {
|
||||
ForEach(filters) { filter in
|
||||
|
@ -31,7 +31,7 @@ public struct FiltersListView: View {
|
|||
VStack(alignment: .leading) {
|
||||
Text(filter.title)
|
||||
.font(.scaledSubheadline)
|
||||
Text("\(filter.context.map { $0.name }.joined(separator: ", "))")
|
||||
Text("\(filter.context.map(\.name).joined(separator: ", "))")
|
||||
.font(.scaledBody)
|
||||
.foregroundColor(.gray)
|
||||
if filter.hasExpiry() {
|
||||
|
|
|
@ -31,7 +31,7 @@ let package = Package(
|
|||
.product(name: "DesignSystem", package: "DesignSystem"),
|
||||
],
|
||||
swiftSettings: [
|
||||
.enableExperimentalFeature("StrictConcurrency")
|
||||
.enableExperimentalFeature("StrictConcurrency"),
|
||||
]
|
||||
),
|
||||
]
|
||||
|
|
|
@ -25,9 +25,9 @@ public class AppAccountViewModel: ObservableObject {
|
|||
|
||||
var acct: String {
|
||||
if let acct = appAccount.accountName {
|
||||
return acct
|
||||
acct
|
||||
} else {
|
||||
return "@\(account?.acct ?? "...")@\(appAccount.server)"
|
||||
"@\(account?.acct ?? "...")@\(appAccount.server)"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ public class AppAccountsManager: ObservableObject {
|
|||
|
||||
public static var shared = AppAccountsManager()
|
||||
|
||||
internal init() {
|
||||
init() {
|
||||
var defaultAccount = AppAccount(server: AppInfo.defaultServer, accountName: nil, oauthToken: nil)
|
||||
let keychainAccounts = AppAccount.retrieveAll()
|
||||
availableAccounts = keychainAccounts
|
||||
|
|
|
@ -19,7 +19,7 @@ public struct AppAccountsSelectorView: View {
|
|||
private var showNotificationBadge: Bool {
|
||||
accountsViewModel
|
||||
.filter { $0.account?.id != currentAccount.account?.id }
|
||||
.compactMap { $0.appAccount.oauthToken }
|
||||
.compactMap(\.appAccount.oauthToken)
|
||||
.map { preferences.getNotificationsCount(for: $0) }
|
||||
.reduce(0, +) > 0
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ public struct AppAccountsSelectorView: View {
|
|||
.redacted(reason: .placeholder)
|
||||
}
|
||||
}.overlay(alignment: .topTrailing) {
|
||||
if (!currentAccount.followRequests.isEmpty || showNotificationBadge) && accountCreationEnabled {
|
||||
if !currentAccount.followRequests.isEmpty || showNotificationBadge, accountCreationEnabled {
|
||||
Circle()
|
||||
.fill(Color.red)
|
||||
.frame(width: 9, height: 9)
|
||||
|
|
|
@ -31,7 +31,7 @@ let package = Package(
|
|||
.product(name: "DesignSystem", package: "DesignSystem"),
|
||||
],
|
||||
swiftSettings: [
|
||||
.enableExperimentalFeature("StrictConcurrency")
|
||||
.enableExperimentalFeature("StrictConcurrency"),
|
||||
]
|
||||
),
|
||||
]
|
||||
|
|
|
@ -27,8 +27,8 @@ struct ConversationsListRow: View {
|
|||
.accessibilityHidden(true)
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
HStack {
|
||||
EmojiTextApp(.init(stringValue: conversation.accounts.map { $0.safeDisplayName }.joined(separator: ", ")),
|
||||
emojis: conversation.accounts.flatMap { $0.emojis })
|
||||
EmojiTextApp(.init(stringValue: conversation.accounts.map(\.safeDisplayName).joined(separator: ", ")),
|
||||
emojis: conversation.accounts.flatMap(\.emojis))
|
||||
.font(.scaledSubheadline)
|
||||
.foregroundColor(theme.labelColor)
|
||||
.emojiSize(Font.scaledSubheadlineFont.emojiSize)
|
||||
|
|
|
@ -18,9 +18,9 @@ public struct ConversationsListView: View {
|
|||
|
||||
private var conversations: Binding<[Conversation]> {
|
||||
if viewModel.isLoadingFirstPage {
|
||||
return Binding.constant(Conversation.placeholders())
|
||||
Binding.constant(Conversation.placeholders())
|
||||
} else {
|
||||
return $viewModel.conversations
|
||||
$viewModel.conversations
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ public struct ConversationsListView: View {
|
|||
}
|
||||
Divider()
|
||||
}
|
||||
} else if conversations.isEmpty && !viewModel.isLoadingFirstPage && !viewModel.isError {
|
||||
} else if conversations.isEmpty, !viewModel.isLoadingFirstPage, !viewModel.isError {
|
||||
EmptyView(iconName: "tray",
|
||||
title: "conversations.empty.title",
|
||||
message: "conversations.empty.message")
|
||||
|
@ -79,7 +79,7 @@ public struct ConversationsListView: View {
|
|||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
StatusEditorToolbarItem(visibility: .direct)
|
||||
if UIDevice.current.userInterfaceIdiom == .pad && !preferences.showiPadSecondaryColumn {
|
||||
if UIDevice.current.userInterfaceIdiom == .pad, !preferences.showiPadSecondaryColumn {
|
||||
SecondaryColumnToolbarItem()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,11 +60,10 @@ class ConversationsListViewModel: ObservableObject {
|
|||
|
||||
func favorite(conversation: Conversation) async {
|
||||
guard let client, let message = conversation.lastStatus else { return }
|
||||
let endpoint: Endpoint
|
||||
if message.favourited ?? false {
|
||||
endpoint = Statuses.unfavorite(id: message.id)
|
||||
let endpoint: Endpoint = if message.favourited ?? false {
|
||||
Statuses.unfavorite(id: message.id)
|
||||
} else {
|
||||
endpoint = Statuses.favorite(id: message.id)
|
||||
Statuses.favorite(id: message.id)
|
||||
}
|
||||
do {
|
||||
let status: Status = try await client.post(endpoint: endpoint)
|
||||
|
@ -74,11 +73,10 @@ class ConversationsListViewModel: ObservableObject {
|
|||
|
||||
func bookmark(conversation: Conversation) async {
|
||||
guard let client, let message = conversation.lastStatus else { return }
|
||||
let endpoint: Endpoint
|
||||
if message.bookmarked ?? false {
|
||||
endpoint = Statuses.unbookmark(id: message.id)
|
||||
let endpoint: Endpoint = if message.bookmarked ?? false {
|
||||
Statuses.unbookmark(id: message.id)
|
||||
} else {
|
||||
endpoint = Statuses.bookmark(id: message.id)
|
||||
Statuses.bookmark(id: message.id)
|
||||
}
|
||||
do {
|
||||
let status: Status = try await client.post(endpoint: endpoint)
|
||||
|
|
|
@ -34,7 +34,7 @@ let package = Package(
|
|||
.product(name: "EmojiText", package: "EmojiText"),
|
||||
],
|
||||
swiftSettings: [
|
||||
.enableExperimentalFeature("StrictConcurrency")
|
||||
.enableExperimentalFeature("StrictConcurrency"),
|
||||
]
|
||||
),
|
||||
]
|
||||
|
|
|
@ -160,19 +160,18 @@ public struct ConstellationDark: ColorSet {
|
|||
public var scheme: ColorScheme = .dark
|
||||
public var tintColor: Color = .init(hex: 0xFFD966)
|
||||
public var primaryBackgroundColor: Color = .init(hex: 0x09192C)
|
||||
public var secondaryBackgroundColor: Color = .init(hex: 0x304c7a)
|
||||
public var secondaryBackgroundColor: Color = .init(hex: 0x304C7A)
|
||||
public var labelColor: Color = .init(hex: 0xE2E4E2)
|
||||
|
||||
public init() {}
|
||||
}
|
||||
|
||||
|
||||
public struct ConstellationLight: ColorSet {
|
||||
public var name: ColorSetName = .constellationLight
|
||||
public var scheme: ColorScheme = .light
|
||||
public var tintColor: Color = .init(hex: 0xc82238)
|
||||
public var primaryBackgroundColor: Color = .init(hex: 0xf4f5f7)
|
||||
public var secondaryBackgroundColor: Color = .init(hex: 0xacc7e5)
|
||||
public var tintColor: Color = .init(hex: 0xC82238)
|
||||
public var primaryBackgroundColor: Color = .init(hex: 0xF4F5F7)
|
||||
public var secondaryBackgroundColor: Color = .init(hex: 0xACC7E5)
|
||||
public var labelColor: Color = .black
|
||||
|
||||
public init() {}
|
||||
|
|
|
@ -27,7 +27,7 @@ extension Color: RawRepresentable {
|
|||
}
|
||||
|
||||
public var rawValue: Int {
|
||||
guard let coreImageColor = coreImageColor else {
|
||||
guard let coreImageColor else {
|
||||
return 0
|
||||
}
|
||||
let red = Int(coreImageColor.red * 255 + 0.5)
|
||||
|
@ -37,7 +37,7 @@ extension Color: RawRepresentable {
|
|||
}
|
||||
|
||||
private var coreImageColor: CIColor? {
|
||||
return CIColor(color: .init(self))
|
||||
CIColor(color: .init(self))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,15 +22,15 @@ public class Theme: ObservableObject {
|
|||
public var title: LocalizedStringKey {
|
||||
switch self {
|
||||
case .system:
|
||||
return "settings.display.font.system"
|
||||
"settings.display.font.system"
|
||||
case .openDyslexic:
|
||||
return "Open Dyslexic"
|
||||
"Open Dyslexic"
|
||||
case .hyperLegible:
|
||||
return "Hyper Legible"
|
||||
"Hyper Legible"
|
||||
case .SFRounded:
|
||||
return "SF Rounded"
|
||||
"SF Rounded"
|
||||
case .custom:
|
||||
return "settings.display.font.custom"
|
||||
"settings.display.font.custom"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,9 +41,9 @@ public class Theme: ObservableObject {
|
|||
public var description: LocalizedStringKey {
|
||||
switch self {
|
||||
case .leading:
|
||||
return "enum.avatar-position.leading"
|
||||
"enum.avatar-position.leading"
|
||||
case .top:
|
||||
return "enum.avatar-position.top"
|
||||
"enum.avatar-position.top"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,9 +54,9 @@ public class Theme: ObservableObject {
|
|||
public var description: LocalizedStringKey {
|
||||
switch self {
|
||||
case .circle:
|
||||
return "enum.avatar-shape.circle"
|
||||
"enum.avatar-shape.circle"
|
||||
case .rounded:
|
||||
return "enum.avatar-shape.rounded"
|
||||
"enum.avatar-shape.rounded"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,11 +67,11 @@ public class Theme: ObservableObject {
|
|||
public var description: LocalizedStringKey {
|
||||
switch self {
|
||||
case .full:
|
||||
return "enum.status-actions-display.all"
|
||||
"enum.status-actions-display.all"
|
||||
case .discret:
|
||||
return "enum.status-actions-display.only-buttons"
|
||||
"enum.status-actions-display.only-buttons"
|
||||
case .none:
|
||||
return "enum.status-actions-display.no-buttons"
|
||||
"enum.status-actions-display.no-buttons"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,11 +82,11 @@ public class Theme: ObservableObject {
|
|||
public var description: LocalizedStringKey {
|
||||
switch self {
|
||||
case .large:
|
||||
return "enum.status-display-style.large"
|
||||
"enum.status-display-style.large"
|
||||
case .medium:
|
||||
return "enum.status-display-style.medium"
|
||||
"enum.status-display-style.medium"
|
||||
case .compact:
|
||||
return "enum.status-display-style.compact"
|
||||
"enum.status-display-style.compact"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ struct ThemeApplier: ViewModifier {
|
|||
private func allWindows() -> [UIWindow] {
|
||||
UIApplication.shared.connectedScenes
|
||||
.compactMap { $0 as? UIWindowScene }
|
||||
.flatMap { $0.windows }
|
||||
.flatMap(\.windows)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -33,9 +33,9 @@ public struct AvatarView: View {
|
|||
var cornerRadius: CGFloat {
|
||||
switch self {
|
||||
case .badge, .boost, .list:
|
||||
return size.width / 2
|
||||
size.width / 2
|
||||
default:
|
||||
return 4
|
||||
4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public struct AvatarView: View {
|
|||
.fill(.gray)
|
||||
.frame(width: size.size.width, height: size.size.height)
|
||||
} else {
|
||||
LazyImage(request: url.map{ makeImageRequest(for: $0) }) { state in
|
||||
LazyImage(request: url.map { makeImageRequest(for: $0) }) { state in
|
||||
if let image = state.image {
|
||||
image
|
||||
.resizable()
|
||||
|
@ -80,9 +80,9 @@ public struct AvatarView: View {
|
|||
private var clipShape: some Shape {
|
||||
switch theme.avatarShape {
|
||||
case .circle:
|
||||
return AnyShape(Circle())
|
||||
AnyShape(Circle())
|
||||
case .rounded:
|
||||
return AnyShape(RoundedRectangle(cornerRadius: size.cornerRadius))
|
||||
AnyShape(RoundedRectangle(cornerRadius: size.cornerRadius))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,6 @@ public struct EmojiTextApp: View {
|
|||
|
||||
private func isRTL() -> Bool {
|
||||
// Arabic, Hebrew, Persian, Urdu, Kurdish, Azeri, Dhivehi
|
||||
return ["ar", "he", "fa", "ur", "ku", "az", "dv"].contains(language)
|
||||
["ar", "he", "fa", "ur", "ku", "az", "dv"].contains(language)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ public struct SecondaryColumnToolbarItem: ToolbarContent {
|
|||
|
||||
public init() {}
|
||||
|
||||
public var body: some ToolbarContent {
|
||||
public var body: some ToolbarContent {
|
||||
ToolbarItem(placement: isSecondaryColumn ? .navigationBarLeading : .navigationBarTrailing) {
|
||||
Button {
|
||||
withAnimation {
|
||||
|
|
|
@ -29,7 +29,7 @@ let package = Package(
|
|||
.product(name: "KeychainSwift", package: "keychain-swift"),
|
||||
],
|
||||
swiftSettings: [
|
||||
.enableExperimentalFeature("StrictConcurrency")
|
||||
.enableExperimentalFeature("StrictConcurrency"),
|
||||
]
|
||||
),
|
||||
]
|
||||
|
|
|
@ -48,7 +48,7 @@ public class CurrentAccount: ObservableObject {
|
|||
}
|
||||
|
||||
public func fetchConnections() async {
|
||||
guard let client = client else { return }
|
||||
guard let client else { return }
|
||||
do {
|
||||
let connections: [String] = try await client.get(endpoint: Instances.peers)
|
||||
client.addConnections(connections)
|
||||
|
@ -56,7 +56,7 @@ public class CurrentAccount: ObservableObject {
|
|||
}
|
||||
|
||||
public func fetchCurrentAccount() async {
|
||||
guard let client = client, client.isAuth else {
|
||||
guard let client, client.isAuth else {
|
||||
account = nil
|
||||
return
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public class CurrentInstance: ObservableObject {
|
|||
}
|
||||
|
||||
public func fetchCurrentInstance() async {
|
||||
guard let client = client else { return }
|
||||
guard let client else { return }
|
||||
instance = try? await client.get(endpoint: Instances.instance)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,37 +15,37 @@ public enum Duration: Int, CaseIterable {
|
|||
public var description: LocalizedStringKey {
|
||||
switch self {
|
||||
case .infinite:
|
||||
return "enum.durations.infinite"
|
||||
"enum.durations.infinite"
|
||||
case .fiveMinutes:
|
||||
return "enum.durations.fiveMinutes"
|
||||
"enum.durations.fiveMinutes"
|
||||
case .thirtyMinutes:
|
||||
return "enum.durations.thirtyMinutes"
|
||||
"enum.durations.thirtyMinutes"
|
||||
case .oneHour:
|
||||
return "enum.durations.oneHour"
|
||||
"enum.durations.oneHour"
|
||||
case .sixHours:
|
||||
return "enum.durations.sixHours"
|
||||
"enum.durations.sixHours"
|
||||
case .twelveHours:
|
||||
return "enum.durations.twelveHours"
|
||||
"enum.durations.twelveHours"
|
||||
case .oneDay:
|
||||
return "enum.durations.oneDay"
|
||||
"enum.durations.oneDay"
|
||||
case .threeDays:
|
||||
return "enum.durations.threeDays"
|
||||
"enum.durations.threeDays"
|
||||
case .sevenDays:
|
||||
return "enum.durations.sevenDays"
|
||||
"enum.durations.sevenDays"
|
||||
case .custom:
|
||||
return "enum.durations.custom"
|
||||
"enum.durations.custom"
|
||||
}
|
||||
}
|
||||
|
||||
public static func mutingDurations() -> [Duration] {
|
||||
return Self.allCases.filter { $0 != .custom }
|
||||
allCases.filter { $0 != .custom }
|
||||
}
|
||||
|
||||
public static func filterDurations() -> [Duration] {
|
||||
return [.infinite, .thirtyMinutes, .oneHour, .sixHours, .twelveHours, .oneDay, .sevenDays, .custom]
|
||||
[.infinite, .thirtyMinutes, .oneHour, .sixHours, .twelveHours, .oneDay, .sevenDays, .custom]
|
||||
}
|
||||
|
||||
public static func pollDurations() -> [Duration] {
|
||||
return [.fiveMinutes, .thirtyMinutes, .oneHour, .sixHours, .twelveHours, .oneDay, .threeDays, .sevenDays]
|
||||
[.fiveMinutes, .thirtyMinutes, .oneHour, .sixHours, .twelveHours, .oneDay, .threeDays, .sevenDays]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,15 +7,15 @@ public enum PollVotingFrequency: String, CaseIterable {
|
|||
|
||||
public var canVoteMultipleTimes: Bool {
|
||||
switch self {
|
||||
case .multipleVotes: return true
|
||||
case .oneVote: return false
|
||||
case .multipleVotes: true
|
||||
case .oneVote: false
|
||||
}
|
||||
}
|
||||
|
||||
public var displayString: LocalizedStringKey {
|
||||
switch self {
|
||||
case .oneVote: return "env.poll-vote-frequency.one"
|
||||
case .multipleVotes: return "env.poll-vote-frequency.multiple"
|
||||
case .oneVote: "env.poll-vote-frequency.one"
|
||||
case .multipleVotes: "env.poll-vote-frequency.multiple"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ public enum PreferredShareButtonBehavior: Int, CaseIterable, Codable {
|
|||
|
||||
public var title: LocalizedStringKey {
|
||||
switch self {
|
||||
case .linkOnly: return "settings.content.sharing.share-behavior.link-only"
|
||||
case .linkAndText: return "settings.content.sharing.share-behavior.link-and-text"
|
||||
case .linkOnly: "settings.content.sharing.share-behavior.link-only"
|
||||
case .linkAndText: "settings.content.sharing.share-behavior.link-and-text"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ import Network
|
|||
import SwiftUI
|
||||
import UserNotifications
|
||||
|
||||
extension UNNotificationResponse: @unchecked Sendable { }
|
||||
extension UNUserNotificationCenter: @unchecked Sendable { }
|
||||
extension UNNotificationResponse: @unchecked Sendable {}
|
||||
extension UNUserNotificationCenter: @unchecked Sendable {}
|
||||
|
||||
public struct PushAccount: Equatable {
|
||||
public let server: String
|
||||
|
@ -157,7 +157,7 @@ extension PushNotificationsService: UNUserNotificationCenterDelegate {
|
|||
|
||||
extension Data {
|
||||
var hexString: String {
|
||||
return map { String(format: "%02.2hhx", arguments: [$0]) }.joined()
|
||||
map { String(format: "%02.2hhx", arguments: [$0]) }.joined()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ public class PushNotificationSubscriptionSettings: ObservableObject {
|
|||
}
|
||||
|
||||
public func updateSubscription() async {
|
||||
guard let pushToken = pushToken else { return }
|
||||
guard let pushToken else { return }
|
||||
let client = Client(server: account.server, oauthToken: account.token)
|
||||
do {
|
||||
var listenerURL = PushNotificationsService.Constants.endpoint
|
||||
|
|
|
@ -45,25 +45,25 @@ public enum SheetDestination: Identifiable {
|
|||
switch self {
|
||||
case .editStatusEditor, .newStatusEditor, .replyToStatusEditor, .quoteStatusEditor,
|
||||
.mentionStatusEditor, .settings, .accountPushNotficationsSettings:
|
||||
return "statusEditor"
|
||||
"statusEditor"
|
||||
case .listEdit:
|
||||
return "listEdit"
|
||||
"listEdit"
|
||||
case .listAddAccount:
|
||||
return "listAddAccount"
|
||||
"listAddAccount"
|
||||
case .addAccount:
|
||||
return "addAccount"
|
||||
"addAccount"
|
||||
case .addTagGroup:
|
||||
return "addTagGroup"
|
||||
"addTagGroup"
|
||||
case .addRemoteLocalTimeline:
|
||||
return "addRemoteLocalTimeline"
|
||||
"addRemoteLocalTimeline"
|
||||
case .statusEditHistory:
|
||||
return "statusEditHistory"
|
||||
"statusEditHistory"
|
||||
case .report:
|
||||
return "report"
|
||||
"report"
|
||||
case .shareImage:
|
||||
return "shareImage"
|
||||
"shareImage"
|
||||
case .editTagGroup:
|
||||
return "editTagGroup"
|
||||
"editTagGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,9 +83,9 @@ public class RouterPath: ObservableObject {
|
|||
}
|
||||
|
||||
public func handleStatus(status: AnyStatus, url: URL) -> OpenURLAction.Result {
|
||||
if url.pathComponents.count == 3 && url.pathComponents[1] == "tags" &&
|
||||
url.host() == status.account.url?.host(),
|
||||
let tag = url.pathComponents.last
|
||||
if url.pathComponents.count == 3, url.pathComponents[1] == "tags",
|
||||
url.host() == status.account.url?.host(),
|
||||
let tag = url.pathComponents.last
|
||||
{
|
||||
// OK this test looks weird but it's
|
||||
// A 3 component path i.e. ["/", "tags", "tagname"]
|
||||
|
@ -97,7 +97,7 @@ public class RouterPath: ObservableObject {
|
|||
} else if let mention = status.mentions.first(where: { $0.url == url }) {
|
||||
navigate(to: .accountDetail(id: mention.id))
|
||||
return .handled
|
||||
} else if let client = client,
|
||||
} else if let client,
|
||||
client.isAuth,
|
||||
client.hasConnection(with: url),
|
||||
let id = Int(url.lastPathComponent)
|
||||
|
@ -126,7 +126,7 @@ public class RouterPath: ObservableObject {
|
|||
await navigateToAccountFrom(acct: acct, url: url)
|
||||
}
|
||||
return .handled
|
||||
} else if let client = client,
|
||||
} else if let client,
|
||||
client.isAuth,
|
||||
client.hasConnection(with: url),
|
||||
let id = Int(url.lastPathComponent)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import AudioToolbox
|
||||
import AVKit
|
||||
import CoreHaptics
|
||||
import UIKit
|
||||
import AudioToolbox
|
||||
|
||||
@MainActor
|
||||
public class SoundEffectManager {
|
||||
|
|
|
@ -73,7 +73,7 @@ public class StreamWatcher: ObservableObject {
|
|||
|
||||
private func receiveMessage() {
|
||||
task?.receive(completionHandler: { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
guard let self else { return }
|
||||
switch result {
|
||||
case let .success(message):
|
||||
switch message {
|
||||
|
@ -83,8 +83,8 @@ public class StreamWatcher: ObservableObject {
|
|||
print("Error decoding streaming event string")
|
||||
return
|
||||
}
|
||||
let rawEvent = try self.decoder.decode(RawStreamEvent.self, from: data)
|
||||
if let event = self.rawEventToEvent(rawEvent: rawEvent) {
|
||||
let rawEvent = try decoder.decode(RawStreamEvent.self, from: data)
|
||||
if let event = rawEventToEvent(rawEvent: rawEvent) {
|
||||
Task { @MainActor in
|
||||
self.events.append(event)
|
||||
self.latestEvent = event
|
||||
|
@ -101,10 +101,10 @@ public class StreamWatcher: ObservableObject {
|
|||
break
|
||||
}
|
||||
|
||||
self.receiveMessage()
|
||||
receiveMessage()
|
||||
|
||||
case .failure:
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(self.retryDelay)) {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(retryDelay)) {
|
||||
self.retryDelay += 30
|
||||
self.stopWatching()
|
||||
self.connect()
|
||||
|
|
|
@ -65,9 +65,9 @@ public class UserPreferences: ObservableObject {
|
|||
public var description: LocalizedStringKey {
|
||||
switch self {
|
||||
case .iconWithText:
|
||||
return "enum.swipeactions.icon-with-text"
|
||||
"enum.swipeactions.icon-with-text"
|
||||
case .iconOnly:
|
||||
return "enum.swipeactions.icon-only"
|
||||
"enum.swipeactions.icon-only"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,9 +84,9 @@ public class UserPreferences: ObservableObject {
|
|||
|
||||
public var postVisibility: Models.Visibility {
|
||||
if useInstanceContentSettings {
|
||||
return serverPreferences?.postVisibility ?? .pub
|
||||
serverPreferences?.postVisibility ?? .pub
|
||||
} else {
|
||||
return appDefaultPostVisibility
|
||||
appDefaultPostVisibility
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,25 +111,25 @@ public class UserPreferences: ObservableObject {
|
|||
|
||||
public var postIsSensitive: Bool {
|
||||
if useInstanceContentSettings {
|
||||
return serverPreferences?.postIsSensitive ?? false
|
||||
serverPreferences?.postIsSensitive ?? false
|
||||
} else {
|
||||
return appDefaultPostsSensitive
|
||||
appDefaultPostsSensitive
|
||||
}
|
||||
}
|
||||
|
||||
public var autoExpandSpoilers: Bool {
|
||||
if useInstanceContentSettings {
|
||||
return serverPreferences?.autoExpandSpoilers ?? true
|
||||
serverPreferences?.autoExpandSpoilers ?? true
|
||||
} else {
|
||||
return appAutoExpandSpoilers
|
||||
appAutoExpandSpoilers
|
||||
}
|
||||
}
|
||||
|
||||
public var autoExpandMedia: ServerPreferences.AutoExpandMedia {
|
||||
if useInstanceContentSettings {
|
||||
return serverPreferences?.autoExpandMedia ?? .hideSensitive
|
||||
serverPreferences?.autoExpandMedia ?? .hideSensitive
|
||||
} else {
|
||||
return appAutoExpandMedia
|
||||
appAutoExpandMedia
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,14 +177,14 @@ public class UserPreferences: ObservableObject {
|
|||
|
||||
public static func getIntOfVisibility(_ vis: Models.Visibility) -> Int {
|
||||
switch vis {
|
||||
case .direct:
|
||||
return 0
|
||||
case .priv:
|
||||
return 1
|
||||
case .unlisted:
|
||||
return 2
|
||||
case .pub:
|
||||
return 3
|
||||
case .direct:
|
||||
0
|
||||
case .priv:
|
||||
1
|
||||
case .unlisted:
|
||||
2
|
||||
case .pub:
|
||||
3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ let package = Package(
|
|||
.product(name: "DesignSystem", package: "DesignSystem"),
|
||||
],
|
||||
swiftSettings: [
|
||||
.enableExperimentalFeature("StrictConcurrency")
|
||||
.enableExperimentalFeature("StrictConcurrency"),
|
||||
]
|
||||
),
|
||||
]
|
||||
|
|
|
@ -126,7 +126,7 @@ public struct ExploreView: View {
|
|||
|
||||
@ViewBuilder
|
||||
private func makeSearchResultsView(results: SearchResults) -> some View {
|
||||
if !results.accounts.isEmpty && (viewModel.searchScope == .all || viewModel.searchScope == .people) {
|
||||
if !results.accounts.isEmpty, viewModel.searchScope == .all || viewModel.searchScope == .people {
|
||||
Section("explore.section.users") {
|
||||
ForEach(results.accounts) { account in
|
||||
if let relationship = results.relationships.first(where: { $0.id == account.id }) {
|
||||
|
@ -136,7 +136,7 @@ public struct ExploreView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
if !results.hashtags.isEmpty && (viewModel.searchScope == .all || viewModel.searchScope == .hashtags) {
|
||||
if !results.hashtags.isEmpty, viewModel.searchScope == .all || viewModel.searchScope == .hashtags {
|
||||
Section("explore.section.tags") {
|
||||
ForEach(results.hashtags) { tag in
|
||||
TagRowView(tag: tag)
|
||||
|
@ -145,7 +145,7 @@ public struct ExploreView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
if !results.statuses.isEmpty && (viewModel.searchScope == .all || viewModel.searchScope == .posts) {
|
||||
if !results.statuses.isEmpty, viewModel.searchScope == .all || viewModel.searchScope == .posts {
|
||||
Section("explore.section.posts") {
|
||||
ForEach(results.statuses) { status in
|
||||
StatusRowView(viewModel: { .init(status: status, client: client, routerPath: routerPath) })
|
||||
|
|
|
@ -11,13 +11,13 @@ class ExploreViewModel: ObservableObject {
|
|||
var localizedString: LocalizedStringKey {
|
||||
switch self {
|
||||
case .all:
|
||||
return .init("explore.scope.all")
|
||||
.init("explore.scope.all")
|
||||
case .people:
|
||||
return .init("explore.scope.people")
|
||||
.init("explore.scope.people")
|
||||
case .hashtags:
|
||||
return .init("explore.scope.hashtags")
|
||||
.init("explore.scope.hashtags")
|
||||
case .posts:
|
||||
return .init("explore.scope.posts")
|
||||
.init("explore.scope.posts")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ class ExploreViewModel: ObservableObject {
|
|||
trendingStatuses = data.trendingStatuses
|
||||
trendingLinks = data.trendingLinks
|
||||
|
||||
suggestedAccountsRelationShips = try await client.get(endpoint: Accounts.relationships(ids: suggestedAccounts.map { $0.id }))
|
||||
suggestedAccountsRelationShips = try await client.get(endpoint: Accounts.relationships(ids: suggestedAccounts.map(\.id)))
|
||||
withAnimation {
|
||||
isLoaded = true
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ class ExploreViewModel: ObservableObject {
|
|||
following: nil),
|
||||
forceVersion: .v2)
|
||||
let relationships: [Relationship] =
|
||||
try await client.get(endpoint: Accounts.relationships(ids: results.accounts.map { $0.id }))
|
||||
try await client.get(endpoint: Accounts.relationships(ids: results.accounts.map(\.id)))
|
||||
results.relationships = relationships
|
||||
withAnimation {
|
||||
self.results[searchQuery] = results
|
||||
|
|
|
@ -31,7 +31,7 @@ let package = Package(
|
|||
.product(name: "DesignSystem", package: "DesignSystem"),
|
||||
],
|
||||
swiftSettings: [
|
||||
.enableExperimentalFeature("StrictConcurrency")
|
||||
.enableExperimentalFeature("StrictConcurrency"),
|
||||
]
|
||||
),
|
||||
]
|
||||
|
|
|
@ -25,7 +25,7 @@ let package = Package(
|
|||
"SwiftSoup",
|
||||
],
|
||||
swiftSettings: [
|
||||
.enableExperimentalFeature("StrictConcurrency")
|
||||
.enableExperimentalFeature("StrictConcurrency"),
|
||||
]
|
||||
),
|
||||
.testTarget(
|
||||
|
|
|
@ -60,11 +60,11 @@ public final class Account: Codable, Identifiable, Hashable, Sendable, Equatable
|
|||
public let discoverable: Bool?
|
||||
|
||||
public var haveAvatar: Bool {
|
||||
return avatar.lastPathComponent != "missing.png"
|
||||
avatar.lastPathComponent != "missing.png"
|
||||
}
|
||||
|
||||
public var haveHeader: Bool {
|
||||
return header.lastPathComponent != "missing.png"
|
||||
header.lastPathComponent != "missing.png"
|
||||
}
|
||||
|
||||
public init(id: String, username: String, displayName: String?, avatar: URL, header: URL, acct: String, note: HTMLString, createdAt: ServerDate, followersCount: Int, followingCount: Int, statusesCount: Int, lastStatusAt: String? = nil, fields: [Account.Field], locked: Bool, emojis: [Emoji], url: URL? = nil, source: Account.Source? = nil, bot: Bool, discoverable: Bool? = nil) {
|
||||
|
|
|
@ -11,7 +11,7 @@ public struct HTMLString: Codable, Equatable, Hashable, @unchecked Sendable {
|
|||
public var asMarkdown: String = ""
|
||||
public var asRawText: String = ""
|
||||
public var statusesURLs = [URL]()
|
||||
private(set) public var links = [Link]()
|
||||
public private(set) var links = [Link]()
|
||||
|
||||
public var asSafeMarkdownAttributedString: AttributedString = .init()
|
||||
private var main_regex: NSRegularExpression?
|
||||
|
@ -162,9 +162,9 @@ public struct HTMLString: Codable, Equatable, Hashable, @unchecked Sendable {
|
|||
if url == nil {
|
||||
url = URL(string: href, encodePath: true)
|
||||
}
|
||||
if let linkUrl = url {
|
||||
if let linkUrl = url {
|
||||
linkRef = linkUrl.absoluteString
|
||||
let displayString = asMarkdown[start..<finish]
|
||||
let displayString = asMarkdown[start ..< finish]
|
||||
links.append(Link(linkUrl, displayString: String(displayString)))
|
||||
}
|
||||
|
||||
|
@ -203,19 +203,19 @@ public struct HTMLString: Codable, Equatable, Hashable, @unchecked Sendable {
|
|||
self.displayString = displayString
|
||||
|
||||
switch displayString.first {
|
||||
case "@":
|
||||
self.type = .mention
|
||||
self.title = displayString
|
||||
case "#":
|
||||
self.type = .hashtag
|
||||
self.title = String(displayString.dropFirst())
|
||||
default:
|
||||
self.type = .url
|
||||
var hostNameUrl = url.host ?? url.absoluteString
|
||||
if hostNameUrl.hasPrefix("www.") {
|
||||
hostNameUrl = String(hostNameUrl.dropFirst(4))
|
||||
}
|
||||
self.title = hostNameUrl
|
||||
case "@":
|
||||
type = .mention
|
||||
title = displayString
|
||||
case "#":
|
||||
type = .hashtag
|
||||
title = String(displayString.dropFirst())
|
||||
default:
|
||||
type = .url
|
||||
var hostNameUrl = url.host ?? url.absoluteString
|
||||
if hostNameUrl.hasPrefix("www.") {
|
||||
hostNameUrl = String(hostNameUrl.dropFirst(4))
|
||||
}
|
||||
title = hostNameUrl
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,15 +227,14 @@ public struct HTMLString: Codable, Equatable, Hashable, @unchecked Sendable {
|
|||
}
|
||||
}
|
||||
|
||||
extension URL {
|
||||
|
||||
public extension URL {
|
||||
// It's common to use non-ASCII characters in URLs even though they're technically
|
||||
// invalid characters. Every modern browser handles this by silently encoding
|
||||
// the invalid characters on the user's behalf. However, trying to create a URL
|
||||
// object with un-encoded characters will result in nil so we need to encode the
|
||||
// invalid characters before creating the URL object. The unencoded version
|
||||
// should still be shown in the displayed status.
|
||||
public init?(string: String, encodePath: Bool) {
|
||||
init?(string: String, encodePath: Bool) {
|
||||
var encodedUrlString = ""
|
||||
if encodePath,
|
||||
string.starts(with: "http://") || string.starts(with: "https://"),
|
||||
|
@ -248,14 +247,14 @@ extension URL {
|
|||
encodedUrlString = String(string[...startIndex])
|
||||
while let endIndex = string[string.index(after: startIndex)...].firstIndex(of: "/") {
|
||||
let componentStartIndex = string.index(after: startIndex)
|
||||
encodedUrlString = encodedUrlString + (string[componentStartIndex...endIndex].addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "")
|
||||
encodedUrlString = encodedUrlString + (string[componentStartIndex ... endIndex].addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "")
|
||||
startIndex = endIndex
|
||||
}
|
||||
|
||||
// The last part of the path may have a query string appended to it
|
||||
let componentStartIndex = string.index(after: startIndex)
|
||||
if let queryStartIndex = string[componentStartIndex...].firstIndex(of: "?") {
|
||||
encodedUrlString = encodedUrlString + (string[componentStartIndex..<queryStartIndex].addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "")
|
||||
encodedUrlString = encodedUrlString + (string[componentStartIndex ..< queryStartIndex].addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "")
|
||||
encodedUrlString = encodedUrlString + (string[queryStartIndex...].addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")
|
||||
} else {
|
||||
encodedUrlString = encodedUrlString + (string[componentStartIndex...].addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "")
|
||||
|
|
|
@ -8,9 +8,9 @@ public struct AppAccount: Codable, Identifiable, Hashable {
|
|||
|
||||
public var key: String {
|
||||
if let oauthToken {
|
||||
return "\(server):\(oauthToken.createdAt)"
|
||||
"\(server):\(oauthToken.createdAt)"
|
||||
} else {
|
||||
return "\(server):anonymous"
|
||||
"\(server):anonymous"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import Foundation
|
|||
|
||||
@MainActor
|
||||
public struct Language: Identifiable, Equatable, Hashable {
|
||||
nonisolated public var id: String { isoCode }
|
||||
public nonisolated var id: String { isoCode }
|
||||
|
||||
public let isoCode: String
|
||||
public let nativeName: String?
|
||||
|
|
|
@ -32,7 +32,7 @@ public struct Poll: Codable, Equatable, Hashable {
|
|||
// 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 {
|
||||
return votersCount ?? votesCount
|
||||
votersCount ?? votesCount
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,14 +24,14 @@ public struct ServerFilter: Codable, Identifiable, Hashable, Sendable {
|
|||
public let expiresAt: ServerDate?
|
||||
|
||||
public func hasExpiry() -> Bool {
|
||||
return expiresAt != nil
|
||||
expiresAt != nil
|
||||
}
|
||||
|
||||
public func isExpired() -> Bool {
|
||||
if let expiresAtDate = expiresAt?.asDate {
|
||||
return expiresAtDate < Date()
|
||||
expiresAtDate < Date()
|
||||
} else {
|
||||
return false
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,30 +40,30 @@ public extension ServerFilter.Context {
|
|||
var iconName: String {
|
||||
switch self {
|
||||
case .home:
|
||||
return "rectangle.stack"
|
||||
"rectangle.stack"
|
||||
case .notifications:
|
||||
return "bell"
|
||||
"bell"
|
||||
case .public:
|
||||
return "globe.americas"
|
||||
"globe.americas"
|
||||
case .thread:
|
||||
return "bubble.left.and.bubble.right"
|
||||
"bubble.left.and.bubble.right"
|
||||
case .account:
|
||||
return "person.crop.circle"
|
||||
"person.crop.circle"
|
||||
}
|
||||
}
|
||||
|
||||
var name: String {
|
||||
switch self {
|
||||
case .home:
|
||||
return NSLocalizedString("filter.contexts.home", comment: "")
|
||||
NSLocalizedString("filter.contexts.home", comment: "")
|
||||
case .notifications:
|
||||
return NSLocalizedString("filter.contexts.notifications", comment: "")
|
||||
NSLocalizedString("filter.contexts.notifications", comment: "")
|
||||
case .public:
|
||||
return NSLocalizedString("filter.contexts.public", comment: "")
|
||||
NSLocalizedString("filter.contexts.public", comment: "")
|
||||
case .thread:
|
||||
return NSLocalizedString("filter.contexts.conversations", comment: "")
|
||||
NSLocalizedString("filter.contexts.conversations", comment: "")
|
||||
case .account:
|
||||
return NSLocalizedString("filter.contexts.profiles", comment: "")
|
||||
NSLocalizedString("filter.contexts.profiles", comment: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -72,9 +72,9 @@ public extension ServerFilter.Action {
|
|||
var label: String {
|
||||
switch self {
|
||||
case .warn:
|
||||
return NSLocalizedString("filter.action.warning", comment: "")
|
||||
NSLocalizedString("filter.action.warning", comment: "")
|
||||
case .hide:
|
||||
return NSLocalizedString("filter.action.hide", comment: "")
|
||||
NSLocalizedString("filter.action.hide", comment: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,11 @@ public struct ServerPreferences: Decodable {
|
|||
public var description: LocalizedStringKey {
|
||||
switch self {
|
||||
case .showAll:
|
||||
return "enum.expand-media.show"
|
||||
"enum.expand-media.show"
|
||||
case .hideAll:
|
||||
return "enum.expand-media.hide"
|
||||
"enum.expand-media.hide"
|
||||
case .hideSensitive:
|
||||
return "enum.expand-media.hide-sensitive"
|
||||
"enum.expand-media.hide-sensitive"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ let package = Package(
|
|||
.product(name: "Models", package: "Models"),
|
||||
],
|
||||
swiftSettings: [
|
||||
.enableExperimentalFeature("StrictConcurrency")
|
||||
.enableExperimentalFeature("StrictConcurrency"),
|
||||
]
|
||||
),
|
||||
.testTarget(
|
||||
|
|
|
@ -33,49 +33,49 @@ public enum Accounts: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case let .accounts(id):
|
||||
return "accounts/\(id)"
|
||||
"accounts/\(id)"
|
||||
case .favorites:
|
||||
return "favourites"
|
||||
"favourites"
|
||||
case .bookmarks:
|
||||
return "bookmarks"
|
||||
"bookmarks"
|
||||
case .followedTags:
|
||||
return "followed_tags"
|
||||
"followed_tags"
|
||||
case let .featuredTags(id):
|
||||
return "accounts/\(id)/featured_tags"
|
||||
"accounts/\(id)/featured_tags"
|
||||
case .verifyCredentials:
|
||||
return "accounts/verify_credentials"
|
||||
"accounts/verify_credentials"
|
||||
case .updateCredentials:
|
||||
return "accounts/update_credentials"
|
||||
"accounts/update_credentials"
|
||||
case let .statuses(id, _, _, _, _, _):
|
||||
return "accounts/\(id)/statuses"
|
||||
"accounts/\(id)/statuses"
|
||||
case .relationships:
|
||||
return "accounts/relationships"
|
||||
"accounts/relationships"
|
||||
case let .follow(id, _, _):
|
||||
return "accounts/\(id)/follow"
|
||||
"accounts/\(id)/follow"
|
||||
case let .unfollow(id):
|
||||
return "accounts/\(id)/unfollow"
|
||||
"accounts/\(id)/unfollow"
|
||||
case .familiarFollowers:
|
||||
return "accounts/familiar_followers"
|
||||
"accounts/familiar_followers"
|
||||
case .suggestions:
|
||||
return "suggestions"
|
||||
"suggestions"
|
||||
case let .following(id, _):
|
||||
return "accounts/\(id)/following"
|
||||
"accounts/\(id)/following"
|
||||
case let .followers(id, _):
|
||||
return "accounts/\(id)/followers"
|
||||
"accounts/\(id)/followers"
|
||||
case let .lists(id):
|
||||
return "accounts/\(id)/lists"
|
||||
"accounts/\(id)/lists"
|
||||
case .preferences:
|
||||
return "preferences"
|
||||
"preferences"
|
||||
case let .block(id):
|
||||
return "accounts/\(id)/block"
|
||||
"accounts/\(id)/block"
|
||||
case let .unblock(id):
|
||||
return "accounts/\(id)/unblock"
|
||||
"accounts/\(id)/unblock"
|
||||
case let .mute(id, _):
|
||||
return "accounts/\(id)/mute"
|
||||
"accounts/\(id)/mute"
|
||||
case let .unmute(id):
|
||||
return "accounts/\(id)/unmute"
|
||||
"accounts/\(id)/unmute"
|
||||
case let .relationshipNote(id, _):
|
||||
return "accounts/\(id)/note"
|
||||
"accounts/\(id)/note"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,13 +128,13 @@ public enum Accounts: Endpoint {
|
|||
public var jsonValue: Encodable? {
|
||||
switch self {
|
||||
case let .mute(_, json):
|
||||
return json
|
||||
json
|
||||
case let .relationshipNote(_, json):
|
||||
return json
|
||||
json
|
||||
case let .updateCredentials(json):
|
||||
return json
|
||||
json
|
||||
default:
|
||||
return nil
|
||||
nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ public enum Apps: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .registerApp:
|
||||
return "apps"
|
||||
"apps"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,20 +8,20 @@ public enum Conversations: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .conversations:
|
||||
return "conversations"
|
||||
"conversations"
|
||||
case let .delete(id):
|
||||
return "conversations/\(id)"
|
||||
"conversations/\(id)"
|
||||
case let .read(id):
|
||||
return "conversations/\(id)/read"
|
||||
"conversations/\(id)/read"
|
||||
}
|
||||
}
|
||||
|
||||
public func queryItems() -> [URLQueryItem]? {
|
||||
switch self {
|
||||
case let .conversations(maxId):
|
||||
return makePaginationParam(sinceId: nil, maxId: maxId, mindId: nil)
|
||||
makePaginationParam(sinceId: nil, maxId: maxId, mindId: nil)
|
||||
default:
|
||||
return nil
|
||||
nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ public enum CustomEmojis: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .customEmojis:
|
||||
return "custom_emojis"
|
||||
"custom_emojis"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,11 +8,11 @@ public enum FollowRequests: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .list:
|
||||
return "follow_requests"
|
||||
"follow_requests"
|
||||
case let .accept(id):
|
||||
return "follow_requests/\(id)/authorize"
|
||||
"follow_requests/\(id)/authorize"
|
||||
case let .reject(id):
|
||||
return "follow_requests/\(id)/reject"
|
||||
"follow_requests/\(id)/reject"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ public enum Instances: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .instance:
|
||||
return "instance"
|
||||
"instance"
|
||||
case .peers:
|
||||
return "instance/peers"
|
||||
"instance/peers"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,13 +10,13 @@ public enum Lists: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .lists, .createList:
|
||||
return "lists"
|
||||
"lists"
|
||||
case let .list(id):
|
||||
return "lists/\(id)"
|
||||
"lists/\(id)"
|
||||
case let .accounts(listId):
|
||||
return "lists/\(listId)/accounts"
|
||||
"lists/\(listId)/accounts"
|
||||
case let .updateAccounts(listId, _):
|
||||
return "lists/\(listId)/accounts"
|
||||
"lists/\(listId)/accounts"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,22 +7,22 @@ public enum Media: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .medias:
|
||||
return "media"
|
||||
"media"
|
||||
case let .media(id, _):
|
||||
return "media/\(id)"
|
||||
"media/\(id)"
|
||||
}
|
||||
}
|
||||
|
||||
public func queryItems() -> [URLQueryItem]? {
|
||||
return nil
|
||||
nil
|
||||
}
|
||||
|
||||
public var jsonValue: Encodable? {
|
||||
switch self {
|
||||
case let .media(_, json):
|
||||
return json
|
||||
json
|
||||
default:
|
||||
return nil
|
||||
nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@ public enum Notifications: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .notifications:
|
||||
return "notifications"
|
||||
"notifications"
|
||||
case let .notification(id):
|
||||
return "notifications/\(id)"
|
||||
"notifications/\(id)"
|
||||
case .clear:
|
||||
return "notifications/clear"
|
||||
"notifications/clear"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,18 +8,18 @@ public enum Oauth: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .authorize:
|
||||
return "oauth/authorize"
|
||||
"oauth/authorize"
|
||||
case .token:
|
||||
return "oauth/token"
|
||||
"oauth/token"
|
||||
}
|
||||
}
|
||||
|
||||
public var jsonValue: Encodable? {
|
||||
switch self {
|
||||
case let .token(code, clientId, clientSecret):
|
||||
return TokenData(clientId: clientId, clientSecret: clientSecret, code: code)
|
||||
TokenData(clientId: clientId, clientSecret: clientSecret, code: code)
|
||||
default:
|
||||
return nil
|
||||
nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ public enum Polls: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case let .poll(id):
|
||||
return "polls/\(id)"
|
||||
"polls/\(id)"
|
||||
case let .vote(id, _):
|
||||
return "polls/\(id)/votes"
|
||||
"polls/\(id)/votes"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ public enum Push: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .subscription, .createSub:
|
||||
return "push/subscription"
|
||||
"push/subscription"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ public enum Search: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .search:
|
||||
return "search"
|
||||
"search"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,17 +12,17 @@ public enum ServerFilters: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .filters:
|
||||
return "filters"
|
||||
"filters"
|
||||
case .createFilter:
|
||||
return "filters"
|
||||
"filters"
|
||||
case let .filter(id):
|
||||
return "filters/\(id)"
|
||||
"filters/\(id)"
|
||||
case let .editFilter(id, _):
|
||||
return "filters/\(id)"
|
||||
"filters/\(id)"
|
||||
case let .addKeyword(id, _, _):
|
||||
return "filters/\(id)/keywords"
|
||||
"filters/\(id)/keywords"
|
||||
case let .removeKeyword(id):
|
||||
return "filters/keywords/\(id)"
|
||||
"filters/keywords/\(id)"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,11 +39,11 @@ public enum ServerFilters: Endpoint {
|
|||
public var jsonValue: Encodable? {
|
||||
switch self {
|
||||
case let .createFilter(json):
|
||||
return json
|
||||
json
|
||||
case let .editFilter(_, json):
|
||||
return json
|
||||
json
|
||||
default:
|
||||
return nil
|
||||
nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,39 +23,39 @@ public enum Statuses: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .postStatus:
|
||||
return "statuses"
|
||||
"statuses"
|
||||
case let .status(id):
|
||||
return "statuses/\(id)"
|
||||
"statuses/\(id)"
|
||||
case let .editStatus(id, _):
|
||||
return "statuses/\(id)"
|
||||
"statuses/\(id)"
|
||||
case let .context(id):
|
||||
return "statuses/\(id)/context"
|
||||
"statuses/\(id)/context"
|
||||
case let .favorite(id):
|
||||
return "statuses/\(id)/favourite"
|
||||
"statuses/\(id)/favourite"
|
||||
case let .unfavorite(id):
|
||||
return "statuses/\(id)/unfavourite"
|
||||
"statuses/\(id)/unfavourite"
|
||||
case let .reblog(id):
|
||||
return "statuses/\(id)/reblog"
|
||||
"statuses/\(id)/reblog"
|
||||
case let .unreblog(id):
|
||||
return "statuses/\(id)/unreblog"
|
||||
"statuses/\(id)/unreblog"
|
||||
case let .rebloggedBy(id, _):
|
||||
return "statuses/\(id)/reblogged_by"
|
||||
"statuses/\(id)/reblogged_by"
|
||||
case let .favoritedBy(id, _):
|
||||
return "statuses/\(id)/favourited_by"
|
||||
"statuses/\(id)/favourited_by"
|
||||
case let .pin(id):
|
||||
return "statuses/\(id)/pin"
|
||||
"statuses/\(id)/pin"
|
||||
case let .unpin(id):
|
||||
return "statuses/\(id)/unpin"
|
||||
"statuses/\(id)/unpin"
|
||||
case let .bookmark(id):
|
||||
return "statuses/\(id)/bookmark"
|
||||
"statuses/\(id)/bookmark"
|
||||
case let .unbookmark(id):
|
||||
return "statuses/\(id)/unbookmark"
|
||||
"statuses/\(id)/unbookmark"
|
||||
case let .history(id):
|
||||
return "statuses/\(id)/history"
|
||||
"statuses/\(id)/history"
|
||||
case let .translate(id, _):
|
||||
return "statuses/\(id)/translate"
|
||||
"statuses/\(id)/translate"
|
||||
case .report:
|
||||
return "reports"
|
||||
"reports"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,11 +82,11 @@ public enum Statuses: Endpoint {
|
|||
public var jsonValue: Encodable? {
|
||||
switch self {
|
||||
case let .postStatus(json):
|
||||
return json
|
||||
json
|
||||
case let .editStatus(_, json):
|
||||
return json
|
||||
json
|
||||
default:
|
||||
return nil
|
||||
nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,14 +6,14 @@ public enum Streaming: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .streaming:
|
||||
return "streaming"
|
||||
"streaming"
|
||||
}
|
||||
}
|
||||
|
||||
public func queryItems() -> [URLQueryItem]? {
|
||||
switch self {
|
||||
default:
|
||||
return nil
|
||||
nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,18 +8,18 @@ public enum Tags: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case let .tag(id):
|
||||
return "tags/\(id)/"
|
||||
"tags/\(id)/"
|
||||
case let .follow(id):
|
||||
return "tags/\(id)/follow"
|
||||
"tags/\(id)/follow"
|
||||
case let .unfollow(id):
|
||||
return "tags/\(id)/unfollow"
|
||||
"tags/\(id)/unfollow"
|
||||
}
|
||||
}
|
||||
|
||||
public func queryItems() -> [URLQueryItem]? {
|
||||
switch self {
|
||||
default:
|
||||
return nil
|
||||
nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,13 +9,13 @@ public enum Timelines: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .pub:
|
||||
return "timelines/public"
|
||||
"timelines/public"
|
||||
case .home:
|
||||
return "timelines/home"
|
||||
"timelines/home"
|
||||
case let .list(listId, _, _, _):
|
||||
return "timelines/list/\(listId)"
|
||||
"timelines/list/\(listId)"
|
||||
case let .hashtag(tag, _, _):
|
||||
return "timelines/tag/\(tag)"
|
||||
"timelines/tag/\(tag)"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,11 +8,11 @@ public enum Trends: Endpoint {
|
|||
public func path() -> String {
|
||||
switch self {
|
||||
case .tags:
|
||||
return "trends/tags"
|
||||
"trends/tags"
|
||||
case .statuses:
|
||||
return "trends/statuses"
|
||||
"trends/statuses"
|
||||
case .links:
|
||||
return "trends/links"
|
||||
"trends/links"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,15 +62,15 @@ public struct OpenAIClient {
|
|||
var request: OpenAIRequest {
|
||||
switch self {
|
||||
case let .correct(input):
|
||||
return ChatRequest(content: "Fix the spelling and grammar mistakes in the following text: \(input)", temperature: 0.2)
|
||||
ChatRequest(content: "Fix the spelling and grammar mistakes in the following text: \(input)", temperature: 0.2)
|
||||
case let .addTags(input):
|
||||
return ChatRequest(content: "Replace relevant words with camel-cased hashtags in the following text. Don't try to search for context or add hashtags if there is not enough context: \(input)", temperature: 0.1)
|
||||
ChatRequest(content: "Replace relevant words with camel-cased hashtags in the following text. Don't try to search for context or add hashtags if there is not enough context: \(input)", temperature: 0.1)
|
||||
case let .insertTags(input):
|
||||
return ChatRequest(content: "Return the input with added camel-cased hashtags at the end of the input. Don't try to search for context or add hashtags if there is not enough context: \(input)", temperature: 0.2)
|
||||
ChatRequest(content: "Return the input with added camel-cased hashtags at the end of the input. Don't try to search for context or add hashtags if there is not enough context: \(input)", temperature: 0.2)
|
||||
case let .shorten(input):
|
||||
return ChatRequest(content: "Make a shorter version of this text: \(input)", temperature: 0.5)
|
||||
ChatRequest(content: "Make a shorter version of this text: \(input)", temperature: 0.5)
|
||||
case let .emphasize(input):
|
||||
return ChatRequest(content: "Make this text catchy, more fun: \(input)", temperature: 1)
|
||||
ChatRequest(content: "Make this text catchy, more fun: \(input)", temperature: 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import Foundation
|
|||
|
||||
public extension String {
|
||||
func escape() -> String {
|
||||
return replacingOccurrences(of: "&", with: "&")
|
||||
replacingOccurrences(of: "&", with: "&")
|
||||
.replacingOccurrences(of: "<", with: "<")
|
||||
.replacingOccurrences(of: ">", with: ">")
|
||||
.replacingOccurrences(of: """, with: "\"")
|
||||
|
|
|
@ -2,7 +2,7 @@ import Foundation
|
|||
|
||||
extension Data {
|
||||
func base64UrlEncodedString() -> String {
|
||||
return base64EncodedString()
|
||||
base64EncodedString()
|
||||
.replacingOccurrences(of: "+", with: "-")
|
||||
.replacingOccurrences(of: "/", with: "_")
|
||||
.replacingOccurrences(of: "=", with: "")
|
||||
|
|
|
@ -33,7 +33,7 @@ let package = Package(
|
|||
.product(name: "DesignSystem", package: "DesignSystem"),
|
||||
],
|
||||
swiftSettings: [
|
||||
.enableExperimentalFeature("StrictConcurrency")
|
||||
.enableExperimentalFeature("StrictConcurrency"),
|
||||
]
|
||||
),
|
||||
]
|
||||
|
|
|
@ -11,7 +11,7 @@ extension ConsolidatedNotification {
|
|||
var notificationIds: [String] { notifications.map(\.id) }
|
||||
}
|
||||
|
||||
extension Array where Element == ConsolidatedNotification {
|
||||
extension [ConsolidatedNotification] {
|
||||
var notificationCount: Int {
|
||||
reduce(0) { $0 + ($1.accounts.isEmpty ? 1 : $1.accounts.count) }
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import Foundation
|
||||
import Models
|
||||
|
||||
extension Array where Element == Models.Notification {
|
||||
extension [Models.Notification] {
|
||||
func consolidated(selectedType: Models.Notification.NotificationType?) async -> [ConsolidatedNotification] {
|
||||
await withCheckedContinuation { result in
|
||||
DispatchQueue.global().async {
|
||||
|
|
|
@ -6,42 +6,42 @@ extension Models.Notification.NotificationType {
|
|||
public func label(count: Int) -> LocalizedStringKey {
|
||||
switch self {
|
||||
case .status:
|
||||
return "notifications.label.status"
|
||||
"notifications.label.status"
|
||||
case .mention:
|
||||
return ""
|
||||
""
|
||||
case .reblog:
|
||||
return "notifications.label.reblog \(count)"
|
||||
"notifications.label.reblog \(count)"
|
||||
case .follow:
|
||||
return "notifications.label.follow \(count)"
|
||||
"notifications.label.follow \(count)"
|
||||
case .follow_request:
|
||||
return "notifications.label.follow-request"
|
||||
"notifications.label.follow-request"
|
||||
case .favourite:
|
||||
return "notifications.label.favorite \(count)"
|
||||
"notifications.label.favorite \(count)"
|
||||
case .poll:
|
||||
return "notifications.label.poll"
|
||||
"notifications.label.poll"
|
||||
case .update:
|
||||
return "notifications.label.update"
|
||||
"notifications.label.update"
|
||||
}
|
||||
}
|
||||
|
||||
public func notificationKey() -> String {
|
||||
switch self {
|
||||
case .status:
|
||||
return "notifications.label.status.push"
|
||||
"notifications.label.status.push"
|
||||
case .mention:
|
||||
return ""
|
||||
""
|
||||
case .reblog:
|
||||
return "notifications.label.reblog.push"
|
||||
"notifications.label.reblog.push"
|
||||
case .follow:
|
||||
return "notifications.label.follow.push"
|
||||
"notifications.label.follow.push"
|
||||
case .follow_request:
|
||||
return "notifications.label.follow-request.push"
|
||||
"notifications.label.follow-request.push"
|
||||
case .favourite:
|
||||
return "notifications.label.favorite.push"
|
||||
"notifications.label.favorite.push"
|
||||
case .poll:
|
||||
return "notifications.label.poll.push"
|
||||
"notifications.label.poll.push"
|
||||
case .update:
|
||||
return "notifications.label.update.push"
|
||||
"notifications.label.update.push"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,21 +86,21 @@ extension Models.Notification.NotificationType {
|
|||
func menuTitle() -> LocalizedStringKey {
|
||||
switch self {
|
||||
case .status:
|
||||
return "notifications.menu-title.status"
|
||||
"notifications.menu-title.status"
|
||||
case .mention:
|
||||
return "notifications.menu-title.mention"
|
||||
"notifications.menu-title.mention"
|
||||
case .reblog:
|
||||
return "notifications.menu-title.reblog"
|
||||
"notifications.menu-title.reblog"
|
||||
case .follow:
|
||||
return "notifications.menu-title.follow"
|
||||
"notifications.menu-title.follow"
|
||||
case .follow_request:
|
||||
return "notifications.menu-title.follow-request"
|
||||
"notifications.menu-title.follow-request"
|
||||
case .favourite:
|
||||
return "notifications.menu-title.favorite"
|
||||
"notifications.menu-title.favorite"
|
||||
case .poll:
|
||||
return "notifications.menu-title.poll"
|
||||
"notifications.menu-title.poll"
|
||||
case .update:
|
||||
return "notifications.menu-title.update"
|
||||
"notifications.menu-title.update"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ class NotificationsViewModel: ObservableObject {
|
|||
if let selectedType {
|
||||
var excludedTypes = Models.Notification.NotificationType.allCases
|
||||
excludedTypes.removeAll(where: { $0 == selectedType })
|
||||
return excludedTypes.map { $0.rawValue }
|
||||
return excludedTypes.map(\.rawValue)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ let package = Package(
|
|||
.product(name: "DesignSystem", package: "DesignSystem"),
|
||||
],
|
||||
swiftSettings: [
|
||||
.enableExperimentalFeature("StrictConcurrency")
|
||||
.enableExperimentalFeature("StrictConcurrency"),
|
||||
]
|
||||
),
|
||||
]
|
||||
|
|
|
@ -161,7 +161,7 @@ public struct StatusDetailView: View {
|
|||
.id(status.id)
|
||||
// VoiceOver / Switch Control focus workaround
|
||||
.onAppear {
|
||||
self.initialFocusBugWorkaround = true
|
||||
initialFocusBugWorkaround = true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,15 +24,15 @@ enum StatusEditorAIPrompt: CaseIterable {
|
|||
func toRequestPrompt(text: String) -> OpenAIClient.Prompt {
|
||||
switch self {
|
||||
case .correct:
|
||||
return .correct(input: text)
|
||||
.correct(input: text)
|
||||
case .addTags:
|
||||
return .addTags(input: text)
|
||||
.addTags(input: text)
|
||||
case .insertTags:
|
||||
return .insertTags(input: text)
|
||||
.insertTags(input: text)
|
||||
case .fit:
|
||||
return .shorten(input: text)
|
||||
.shorten(input: text)
|
||||
case .emphasize:
|
||||
return .emphasize(input: text)
|
||||
.emphasize(input: text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ struct StatusEditorAccessoryView: View {
|
|||
|
||||
@ViewBuilder
|
||||
private func languageTextView(isoCode: String, nativeName: String?, name: String?) -> some View {
|
||||
if let nativeName = nativeName, let name = name {
|
||||
if let nativeName, let name {
|
||||
Text("\(nativeName) (\(name))")
|
||||
} else {
|
||||
Text(isoCode.uppercased())
|
||||
|
|
|
@ -8,7 +8,7 @@ actor StatusEditorCompressor {
|
|||
}
|
||||
|
||||
func compressImageFrom(url: URL) async -> Data? {
|
||||
return await withCheckedContinuation { continuation in
|
||||
await withCheckedContinuation { continuation in
|
||||
let sourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary
|
||||
guard let source = CGImageSourceCreateWithURL(url as CFURL, sourceOptions) else {
|
||||
continuation.resume(returning: nil)
|
||||
|
|
|
@ -66,7 +66,7 @@ struct StatusEditorMediaEditView: View {
|
|||
Button {
|
||||
if !imageDescription.isEmpty {
|
||||
isUpdating = true
|
||||
if currentInstance.isEditAltTextSupported && viewModel.mode.isEditing {
|
||||
if currentInstance.isEditAltTextSupported, viewModel.mode.isEditing {
|
||||
Task {
|
||||
await viewModel.editDescription(container: container, description: imageDescription)
|
||||
dismiss()
|
||||
|
|
|
@ -43,18 +43,18 @@ enum StatusEditorUTTypeSupported: String, CaseIterable {
|
|||
var isVideo: Bool {
|
||||
switch self {
|
||||
case .video, .movie, .mp4, .quickTimeMovie:
|
||||
return true
|
||||
true
|
||||
default:
|
||||
return false
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
var isGif: Bool {
|
||||
switch self {
|
||||
case .gif, .gif2:
|
||||
return true
|
||||
true
|
||||
default:
|
||||
return false
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ enum StatusEditorUTTypeSupported: String, CaseIterable {
|
|||
}
|
||||
|
||||
private func getVideoTransferable(item: NSItemProvider) async -> MovieFileTranseferable? {
|
||||
return await withCheckedContinuation { continuation in
|
||||
await withCheckedContinuation { continuation in
|
||||
_ = item.loadTransferable(type: MovieFileTranseferable.self) { result in
|
||||
switch result {
|
||||
case let .success(success):
|
||||
|
@ -113,7 +113,7 @@ enum StatusEditorUTTypeSupported: String, CaseIterable {
|
|||
}
|
||||
|
||||
private func getGifTransferable(item: NSItemProvider) async -> GifFileTranseferable? {
|
||||
return await withCheckedContinuation { continuation in
|
||||
await withCheckedContinuation { continuation in
|
||||
_ = item.loadTransferable(type: GifFileTranseferable.self) { result in
|
||||
switch result {
|
||||
case let .success(success):
|
||||
|
@ -126,7 +126,7 @@ enum StatusEditorUTTypeSupported: String, CaseIterable {
|
|||
}
|
||||
|
||||
private func getImageTansferable(item: NSItemProvider) async -> ImageFileTranseferable? {
|
||||
return await withCheckedContinuation { continuation in
|
||||
await withCheckedContinuation { continuation in
|
||||
_ = item.loadTransferable(type: ImageFileTranseferable.self) { result in
|
||||
switch result {
|
||||
case let .success(success):
|
||||
|
|
|
@ -157,7 +157,7 @@ public class StatusEditorViewModel: NSObject, ObservableObject {
|
|||
|
||||
func evaluateLanguages() {
|
||||
if let detectedLang = detectLanguage(text: statusText.string),
|
||||
let selectedLanguage = selectedLanguage,
|
||||
let selectedLanguage,
|
||||
selectedLanguage != "",
|
||||
selectedLanguage != detectedLang
|
||||
{
|
||||
|
@ -311,14 +311,14 @@ public class StatusEditorViewModel: NSObject, ObservableObject {
|
|||
let range = NSMakeRange(0, statusText.string.utf16.count)
|
||||
var ranges = hashtagRegex.matches(in: statusText.string,
|
||||
options: [],
|
||||
range: range).map { $0.range }
|
||||
range: range).map(\.range)
|
||||
ranges.append(contentsOf: mentionRegex.matches(in: statusText.string,
|
||||
options: [],
|
||||
range: range).map { $0.range })
|
||||
range: range).map(\.range))
|
||||
|
||||
let urlRanges = urlRegex.matches(in: statusText.string,
|
||||
options: [],
|
||||
range: range).map { $0.range }
|
||||
range: range).map(\.range)
|
||||
|
||||
var foundSuggestionRange = false
|
||||
for nsRange in ranges {
|
||||
|
|
|
@ -14,40 +14,40 @@ public extension StatusEditorViewModel {
|
|||
var isInShareExtension: Bool {
|
||||
switch self {
|
||||
case .shareExtension:
|
||||
return true
|
||||
true
|
||||
default:
|
||||
return false
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
var isEditing: Bool {
|
||||
switch self {
|
||||
case .edit:
|
||||
return true
|
||||
true
|
||||
default:
|
||||
return false
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
var replyToStatus: Status? {
|
||||
switch self {
|
||||
case let .replyTo(status):
|
||||
return status
|
||||
status
|
||||
default:
|
||||
return nil
|
||||
nil
|
||||
}
|
||||
}
|
||||
|
||||
var title: LocalizedStringKey {
|
||||
switch self {
|
||||
case .new, .mention, .shareExtension:
|
||||
return "status.editor.mode.new"
|
||||
"status.editor.mode.new"
|
||||
case .edit:
|
||||
return "status.editor.mode.edit"
|
||||
"status.editor.mode.edit"
|
||||
case let .replyTo(status):
|
||||
return "status.editor.mode.reply-\(status.reblog?.account.displayNameWithoutEmojis ?? status.account.displayNameWithoutEmojis)"
|
||||
"status.editor.mode.reply-\(status.reblog?.account.displayNameWithoutEmojis ?? status.account.displayNameWithoutEmojis)"
|
||||
case let .quote(status):
|
||||
return "status.editor.mode.quote-\(status.reblog?.account.displayNameWithoutEmojis ?? status.account.displayNameWithoutEmojis)"
|
||||
"status.editor.mode.quote-\(status.reblog?.account.displayNameWithoutEmojis ?? status.account.displayNameWithoutEmojis)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue