diff --git a/IceCubesApp.xcodeproj/project.pbxproj b/IceCubesApp.xcodeproj/project.pbxproj index 04b91711..0caf5940 100644 --- a/IceCubesApp.xcodeproj/project.pbxproj +++ b/IceCubesApp.xcodeproj/project.pbxproj @@ -33,7 +33,6 @@ 9F2A540E2969A0B0009B2D7C /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F2A540D2969A0B0009B2D7C /* StoreKit.framework */; }; 9F2A5411296A1429009B2D7C /* PushNotificationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2A5410296A1429009B2D7C /* PushNotificationsView.swift */; }; 9F2A5419296AB631009B2D7C /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2A5418296AB631009B2D7C /* NotificationService.swift */; }; - 9F2A541D296AB631009B2D7C /* IceCubesNotifications.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 9F2A5416296AB631009B2D7C /* IceCubesNotifications.appex */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 9F2A5424296AB67A009B2D7C /* Env in Frameworks */ = {isa = PBXBuildFile; productRef = 9F2A5423296AB67A009B2D7C /* Env */; }; 9F2A5426296AB67E009B2D7C /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 9F2A5425296AB67E009B2D7C /* KeychainSwift */; }; 9F2A5428296AB683009B2D7C /* Models in Frameworks */ = {isa = PBXBuildFile; productRef = 9F2A5427296AB683009B2D7C /* Models */; }; @@ -69,7 +68,6 @@ 9FAD85832971BF7200496AB1 /* Secret.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9FAD85822971BF7200496AB1 /* Secret.plist */; }; 9FAD858B29743F7400496AB1 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAD858A29743F7400496AB1 /* ShareViewController.swift */; }; 9FAD858E29743F7400496AB1 /* (null) in Resources */ = {isa = PBXBuildFile; }; - 9FAD859229743F7400496AB1 /* IceCubesShareExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 9FAD858829743F7400496AB1 /* IceCubesShareExtension.appex */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 9FAD85982974405D00496AB1 /* Status in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD85972974405D00496AB1 /* Status */; }; 9FAD859A297440CB00496AB1 /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD8599297440CB00496AB1 /* KeychainSwift */; }; 9FAD859C2974422700496AB1 /* AppAccount in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD859B2974422700496AB1 /* AppAccount */; }; @@ -105,51 +103,10 @@ E9DF41FC29830FEC0003AAD2 /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9DF41FB29830FEC0003AAD2 /* UniformTypeIdentifiers.framework */; }; E9DF420129830FEC0003AAD2 /* ActionRequestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9DF420029830FEC0003AAD2 /* ActionRequestHandler.swift */; }; E9DF420329830FEC0003AAD2 /* Action.js in Resources */ = {isa = PBXBuildFile; fileRef = E9DF420229830FEC0003AAD2 /* Action.js */; }; - E9DF420729830FEC0003AAD2 /* IceCubesActionExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = E9DF41FA29830FEC0003AAD2 /* IceCubesActionExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; FA31A9AB2A66BF7C00D5F662 /* EditTagGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA31A9AA2A66BF7C00D5F662 /* EditTagGroupView.swift */; }; FAD203D02A66D8A80030A7FD /* Symbols.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAD203CF2A66D8A80030A7FD /* Symbols.swift */; }; /* End PBXBuildFile section */ -/* Begin PBXContainerItemProxy section */ - 9F2A541B296AB631009B2D7C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 9FBFE631292A715500C250E9 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 9F2A5415296AB631009B2D7C; - remoteInfo = IceCubesNotifications; - }; - 9FAD859029743F7400496AB1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 9FBFE631292A715500C250E9 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 9FAD858729743F7400496AB1; - remoteInfo = IceCubesShareExtension; - }; - E9DF420529830FEC0003AAD2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 9FBFE631292A715500C250E9 /* Project object */; - proxyType = 1; - remoteGlobalIDString = E9DF41F929830FEC0003AAD2; - remoteInfo = IceCubesActionExtension; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9F2A5421296AB631009B2D7C /* Embed Foundation Extensions */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 13; - files = ( - E9DF420729830FEC0003AAD2 /* IceCubesActionExtension.appex in Embed Foundation Extensions */, - 9F2A541D296AB631009B2D7C /* IceCubesNotifications.appex in Embed Foundation Extensions */, - 9FAD859229743F7400496AB1 /* IceCubesShareExtension.appex in Embed Foundation Extensions */, - ); - name = "Embed Foundation Extensions"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - /* Begin PBXFileReference section */ 069709A3298C8545006E4CB5 /* Atkinson-Hyperlegible-Regular-102.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Atkinson-Hyperlegible-Regular-102.ttf"; sourceTree = ""; }; 069709A7298C87B5006E4CB5 /* OpenDyslexic-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "OpenDyslexic-Regular.otf"; sourceTree = ""; }; @@ -218,6 +175,7 @@ 9F62216729A68DA4007B77CA /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Localizable.strings; sourceTree = ""; }; 9F62216829A68DA4007B77CA /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/InfoPlist.strings; sourceTree = ""; }; 9F654BEE299AC45B00D27FA5 /* ReportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportView.swift; sourceTree = ""; }; + 9F6AA3CE2AB06DEB0066D27C /* EmojiText */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = EmojiText; path = ../../../../Downloads/EmojiText; sourceTree = ""; }; 9F7335E82966B3DC00AFF0BA /* Conversations */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Conversations; path = Packages/Conversations; sourceTree = ""; }; 9F7335EB2967461B00AFF0BA /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk/System/Library/Frameworks/AVKit.framework; sourceTree = DEVELOPER_DIR; }; 9F7335EE29674F7100AFF0BA /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk/System/Library/Frameworks/QuickLook.framework; sourceTree = DEVELOPER_DIR; }; @@ -459,6 +417,7 @@ 9FBFE630292A715500C250E9 = { isa = PBXGroup; children = ( + 9F6AA3CE2AB06DEB0066D27C /* EmojiText */, DD31E2E5297FB68B00A4BE29 /* IceCubesApp.xcconfig */, 9F7D939529800B0300EE6B7A /* IceCubesApp-release.xcconfig */, 9FBFE63B292A715500C250E9 /* IceCubesApp */, @@ -625,14 +584,10 @@ 9FBFE635292A715500C250E9 /* Sources */, 9FBFE636292A715500C250E9 /* Frameworks */, 9FBFE637292A715500C250E9 /* Resources */, - 9F2A5421296AB631009B2D7C /* Embed Foundation Extensions */, ); buildRules = ( ); dependencies = ( - 9F2A541C296AB631009B2D7C /* PBXTargetDependency */, - 9FAD859129743F7400496AB1 /* PBXTargetDependency */, - E9DF420629830FEC0003AAD2 /* PBXTargetDependency */, ); name = IceCubesApp; packageProductDependencies = ( @@ -868,26 +823,6 @@ }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXTargetDependency section */ - 9F2A541C296AB631009B2D7C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - platformFilter = ios; - target = 9F2A5415296AB631009B2D7C /* IceCubesNotifications */; - targetProxy = 9F2A541B296AB631009B2D7C /* PBXContainerItemProxy */; - }; - 9FAD859129743F7400496AB1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - platformFilter = ios; - target = 9FAD858729743F7400496AB1 /* IceCubesShareExtension */; - targetProxy = 9FAD859029743F7400496AB1 /* PBXContainerItemProxy */; - }; - E9DF420629830FEC0003AAD2 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = E9DF41F929830FEC0003AAD2 /* IceCubesActionExtension */; - targetProxy = E9DF420529830FEC0003AAD2 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - /* Begin PBXVariantGroup section */ 7429BCE4297C55D00069A946 /* Localizable.stringsdict */ = { isa = PBXVariantGroup; @@ -1202,7 +1137,6 @@ 9FBFE649292A715600C250E9 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = "AppIconAlternate1 AppIconAlternate2 AppIconAlternate3 AppIconAlternate4 AppIconAlternate5 AppIconAlternate6 AppIconAlternate7 AppIconAlternate8 AppIconAlternate9 AppIconAlternate10 AppIconAlternate11 AppIconAlternate12 AppIconAlternate13 AppIconAlternate14 AppIconAlternate15 AppIconAlternate16 AppIconAlternate17 AppIconAlternate19 AppIconAlternate18 AppIconAlternate20 AppIconAlternate21 AppIconAlternate22 AppIconAlternate23 AppIconAlternate24 AppIconAlternate25 AppIconAlternate26 AppIconAlternate27 AppIconAlternate28 AppIconAlternate29 AppIconAlternate30 AppIconAlternate31 AppIconAlternate32 AppIconAlternate33 AppIconAlternate34 AppIconAlternate35 AppIconAlternate36 AppIconAlternate37 AppIconAlternate38 AppIconAlternate39 AppIconAlternate40"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -1211,6 +1145,7 @@ CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=xros*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 730; DEAD_CODE_STRIPPING = YES; @@ -1242,20 +1177,20 @@ PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_STRICT_CONCURRENCY = targeted; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,7"; }; name = Debug; }; 9FBFE64A292A715600C250E9 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = "AppIconAlternate1 AppIconAlternate2 AppIconAlternate3 AppIconAlternate4 AppIconAlternate5 AppIconAlternate6 AppIconAlternate7 AppIconAlternate8 AppIconAlternate9 AppIconAlternate10 AppIconAlternate11 AppIconAlternate12 AppIconAlternate13 AppIconAlternate14 AppIconAlternate15 AppIconAlternate16 AppIconAlternate17 AppIconAlternate19 AppIconAlternate18 AppIconAlternate20 AppIconAlternate21 AppIconAlternate22 AppIconAlternate23 AppIconAlternate24 AppIconAlternate25 AppIconAlternate26 AppIconAlternate27 AppIconAlternate28 AppIconAlternate29 AppIconAlternate30 AppIconAlternate31 AppIconAlternate32 AppIconAlternate33 AppIconAlternate34 AppIconAlternate35 AppIconAlternate36 AppIconAlternate37 AppIconAlternate38 AppIconAlternate39 AppIconAlternate40"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -1264,6 +1199,7 @@ CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=xros*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 730; DEAD_CODE_STRIPPING = YES; @@ -1295,13 +1231,14 @@ PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_STRICT_CONCURRENCY = targeted; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,7"; }; name = Release; }; diff --git a/IceCubesApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/IceCubesApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 70d53bd7..2f314c41 100644 --- a/IceCubesApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/IceCubesApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -9,15 +9,6 @@ "version" : "2.1.0" } }, - { - "identity" : "emojitext", - "kind" : "remoteSourceControl", - "location" : "https://github.com/divadretlaw/EmojiText", - "state" : { - "revision" : "a4ddf5077c241170e8ac0d3a9480c511e27c1ae9", - "version" : "2.8.0" - } - }, { "identity" : "keychain-swift", "kind" : "remoteSourceControl", diff --git a/IceCubesApp/App/Report/ReportView.swift b/IceCubesApp/App/Report/ReportView.swift index c70b905a..f7640016 100644 --- a/IceCubesApp/App/Report/ReportView.swift +++ b/IceCubesApp/App/Report/ReportView.swift @@ -37,7 +37,6 @@ public struct ReportView: View { .navigationBarTitleDisplayMode(.inline) .scrollContentBackground(.hidden) .background(theme.secondaryBackgroundColor) - .scrollDismissesKeyboard(.immediately) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button { diff --git a/IceCubesApp/App/SafariRouter.swift b/IceCubesApp/App/SafariRouter.swift index 3a1ebe49..0eb5f3af 100644 --- a/IceCubesApp/App/SafariRouter.swift +++ b/IceCubesApp/App/SafariRouter.swift @@ -56,7 +56,7 @@ private struct SafariRouter: ViewModifier { } } -private class InAppSafariManager: NSObject, ObservableObject, SFSafariViewControllerDelegate { +private class InAppSafariManager: NSObject, ObservableObject { var windowScene: UIWindowScene? let viewController: UIViewController = .init() var window: UIWindow? @@ -71,9 +71,6 @@ private class InAppSafariManager: NSObject, ObservableObject, SFSafariViewContro configuration.entersReaderIfAvailable = UserPreferences.shared.inAppBrowserReaderView let safari = SFSafariViewController(url: url, configuration: configuration) - safari.preferredBarTintColor = UIColor(Theme.shared.primaryBackgroundColor) - safari.preferredControlTintColor = UIColor(Theme.shared.tintColor) - safari.delegate = self DispatchQueue.main.async { [weak self] in self?.viewController.present(safari, animated: true) diff --git a/IceCubesApp/App/Tabs/Settings/AddAccountsView.swift b/IceCubesApp/App/Tabs/Settings/AddAccountsView.swift index dace26a1..2e07eb8e 100644 --- a/IceCubesApp/App/Tabs/Settings/AddAccountsView.swift +++ b/IceCubesApp/App/Tabs/Settings/AddAccountsView.swift @@ -70,7 +70,6 @@ struct AddAccountView: View { .navigationBarTitleDisplayMode(.inline) .scrollContentBackground(.hidden) .background(theme.secondaryBackgroundColor) - .scrollDismissesKeyboard(.immediately) .toolbar { if !appAccountsManager.availableAccounts.isEmpty { ToolbarItem(placement: .navigationBarLeading) { diff --git a/IceCubesApp/App/Tabs/Tabs.swift b/IceCubesApp/App/Tabs/Tabs.swift index f65e3df3..1b235243 100644 --- a/IceCubesApp/App/Tabs/Tabs.swift +++ b/IceCubesApp/App/Tabs/Tabs.swift @@ -19,7 +19,7 @@ enum Tab: Int, Identifiable, Hashable { } static func loggedInTabs() -> [Tab] { - if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { + if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac || UIDevice.current.userInterfaceIdiom == .vision { return [.timeline, .trending, .federated, .local, .notifications, .mentions, .explore, .messages, .settings] } else { return [.timeline, .notifications, .explore, .messages, .profile] diff --git a/IceCubesApp/App/Tabs/Timeline/AddRemoteTimelineView.swift b/IceCubesApp/App/Tabs/Timeline/AddRemoteTimelineView.swift index 54014dfb..f59c11db 100644 --- a/IceCubesApp/App/Tabs/Timeline/AddRemoteTimelineView.swift +++ b/IceCubesApp/App/Tabs/Timeline/AddRemoteTimelineView.swift @@ -52,7 +52,6 @@ struct AddRemoteTimelineView: View { .navigationBarTitleDisplayMode(.inline) .scrollContentBackground(.hidden) .background(theme.secondaryBackgroundColor) - .scrollDismissesKeyboard(.immediately) .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button("action.cancel", action: { dismiss() }) diff --git a/IceCubesApp/App/Tabs/Timeline/EditTagGroupView.swift b/IceCubesApp/App/Tabs/Timeline/EditTagGroupView.swift index 4fb6e217..2e4a50b1 100644 --- a/IceCubesApp/App/Tabs/Timeline/EditTagGroupView.swift +++ b/IceCubesApp/App/Tabs/Timeline/EditTagGroupView.swift @@ -53,7 +53,6 @@ struct EditTagGroupView: View { .navigationBarTitleDisplayMode(.inline) .scrollContentBackground(.hidden) .background(theme.secondaryBackgroundColor) - .scrollDismissesKeyboard(.immediately) .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button("action.cancel", action: { dismiss() }) diff --git a/Packages/Account/.swiftpm/xcode/xcshareddata/xcschemes/Account.xcscheme b/Packages/Account/.swiftpm/xcode/xcshareddata/xcschemes/Account.xcscheme new file mode 100644 index 00000000..9ef4da31 --- /dev/null +++ b/Packages/Account/.swiftpm/xcode/xcshareddata/xcschemes/Account.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Packages/Account/Sources/Account/Edit/EditAccountView.swift b/Packages/Account/Sources/Account/Edit/EditAccountView.swift index 4c1b7ac3..8a733095 100644 --- a/Packages/Account/Sources/Account/Edit/EditAccountView.swift +++ b/Packages/Account/Sources/Account/Edit/EditAccountView.swift @@ -27,7 +27,6 @@ public struct EditAccountView: View { .environment(\.editMode, .constant(.active)) .scrollContentBackground(.hidden) .background(theme.secondaryBackgroundColor) - .scrollDismissesKeyboard(.immediately) .navigationTitle("account.edit.navigation-title") .navigationBarTitleDisplayMode(.inline) .toolbar { diff --git a/Packages/Account/Sources/Account/Filters/EditFilterView.swift b/Packages/Account/Sources/Account/Filters/EditFilterView.swift index 70f9601c..0d0e2de8 100644 --- a/Packages/Account/Sources/Account/Filters/EditFilterView.swift +++ b/Packages/Account/Sources/Account/Filters/EditFilterView.swift @@ -72,7 +72,6 @@ struct EditFilterView: View { .navigationTitle(filter?.title ?? NSLocalizedString("filter.new", comment: "")) .navigationBarTitleDisplayMode(.inline) .scrollContentBackground(.hidden) - .scrollDismissesKeyboard(.interactively) .background(theme.secondaryBackgroundColor) .onAppear { if filter == nil { diff --git a/Packages/AppAccount/.swiftpm/xcode/xcshareddata/xcschemes/AppAccount.xcscheme b/Packages/AppAccount/.swiftpm/xcode/xcshareddata/xcschemes/AppAccount.xcscheme new file mode 100644 index 00000000..1e9f13f4 --- /dev/null +++ b/Packages/AppAccount/.swiftpm/xcode/xcshareddata/xcschemes/AppAccount.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Packages/AppAccount/Sources/AppAccount/AppAccountView.swift b/Packages/AppAccount/Sources/AppAccount/AppAccountView.swift index 13b8bce1..4caa1fb2 100644 --- a/Packages/AppAccount/Sources/AppAccount/AppAccountView.swift +++ b/Packages/AppAccount/Sources/AppAccount/AppAccountView.swift @@ -53,7 +53,7 @@ public struct AppAccountView: View { transation.disablesAnimations = true withTransaction(transation) { appAccounts.currentAccount = viewModel.appAccount - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) } } } label: { diff --git a/Packages/Conversations/.swiftpm/xcode/xcshareddata/xcschemes/Conversations.xcscheme b/Packages/Conversations/.swiftpm/xcode/xcshareddata/xcschemes/Conversations.xcscheme new file mode 100644 index 00000000..8302f4df --- /dev/null +++ b/Packages/Conversations/.swiftpm/xcode/xcshareddata/xcschemes/Conversations.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Packages/Conversations/Package.swift b/Packages/Conversations/Package.swift index 07ef009f..a80c4dd0 100644 --- a/Packages/Conversations/Package.swift +++ b/Packages/Conversations/Package.swift @@ -16,6 +16,7 @@ let package = Package( ), ], dependencies: [ + .package(name: "Account", path: "../Account"), .package(name: "Models", path: "../Models"), .package(name: "Network", path: "../Network"), .package(name: "Env", path: "../Env"), @@ -25,6 +26,7 @@ let package = Package( .target( name: "Conversations", dependencies: [ + .product(name: "Account", package: "Account"), .product(name: "Models", package: "Models"), .product(name: "Network", package: "Network"), .product(name: "Env", package: "Env"), diff --git a/Packages/Conversations/Sources/Conversations/Detail/ConversationDetailView.swift b/Packages/Conversations/Sources/Conversations/Detail/ConversationDetailView.swift index cdb5b75b..2cb30ac5 100644 --- a/Packages/Conversations/Sources/Conversations/Detail/ConversationDetailView.swift +++ b/Packages/Conversations/Sources/Conversations/Detail/ConversationDetailView.swift @@ -45,7 +45,6 @@ public struct ConversationDetailView: View { } .padding(.horizontal, .layoutPadding) } - .scrollDismissesKeyboard(.interactively) .safeAreaInset(edge: .bottom) { inputTextView } diff --git a/Packages/Conversations/Sources/Conversations/List/ConversationsListRow.swift b/Packages/Conversations/Sources/Conversations/List/ConversationsListRow.swift index 1712db8e..9e49e6d4 100644 --- a/Packages/Conversations/Sources/Conversations/List/ConversationsListRow.swift +++ b/Packages/Conversations/Sources/Conversations/List/ConversationsListRow.swift @@ -1,4 +1,4 @@ -import Accounts +import Account import DesignSystem import Env import Models @@ -80,11 +80,12 @@ struct ConversationsListRow: View { } .accessibilityAction(.magicTap) { if let lastStatus = conversation.lastStatus { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) routerPath.presentedSheet = .replyToStatusEditor(status: lastStatus) } } } + .buttonStyle(.plain) } private var actionsView: some View { @@ -181,7 +182,7 @@ struct ConversationsListRow: View { var replyAction: some View { if let lastStatus = conversation.lastStatus { Button("status.action.reply") { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) routerPath.presentedSheet = .replyToStatusEditor(status: lastStatus) } } else { @@ -194,7 +195,7 @@ struct ConversationsListRow: View { if let lastStatus = conversation.lastStatus { if lastStatus.account.id != currentAccount.account?.id { Button("@\(lastStatus.account.username)") { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) routerPath.navigate(to: .accountDetail(id: lastStatus.account.id)) } } @@ -204,18 +205,18 @@ struct ConversationsListRow: View { case .url: if UIApplication.shared.canOpenURL(link.url) { Button("accessibility.tabs.timeline.content-link-\(link.title)") { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) _ = routerPath.handle(url: link.url) } } case .hashtag: Button("accessibility.tabs.timeline.content-hashtag-\(link.title)") { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) _ = routerPath.handle(url: link.url) } case .mention: Button("\(link.title)") { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) _ = routerPath.handle(url: link.url) } } diff --git a/Packages/DesignSystem/.swiftpm/xcode/xcshareddata/xcschemes/DesignSystem.xcscheme b/Packages/DesignSystem/.swiftpm/xcode/xcshareddata/xcschemes/DesignSystem.xcscheme new file mode 100644 index 00000000..8581f687 --- /dev/null +++ b/Packages/DesignSystem/.swiftpm/xcode/xcshareddata/xcschemes/DesignSystem.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Packages/DesignSystem/Sources/DesignSystem/SceneDelegate.swift b/Packages/DesignSystem/Sources/DesignSystem/SceneDelegate.swift index bd5d84c4..b0f1f071 100644 --- a/Packages/DesignSystem/Sources/DesignSystem/SceneDelegate.swift +++ b/Packages/DesignSystem/Sources/DesignSystem/SceneDelegate.swift @@ -5,7 +5,7 @@ public class SceneDelegate: NSObject, ObservableObject, UIWindowSceneDelegate { public var window: UIWindow? public var windowWidth: CGFloat { - window?.bounds.size.width ?? UIScreen.main.bounds.size.width + window?.bounds.size.width ?? 0 } public func scene(_ scene: UIScene, diff --git a/Packages/Env/.swiftpm/xcode/xcshareddata/xcschemes/Env.xcscheme b/Packages/Env/.swiftpm/xcode/xcshareddata/xcschemes/Env.xcscheme new file mode 100644 index 00000000..b3bb4b97 --- /dev/null +++ b/Packages/Env/.swiftpm/xcode/xcshareddata/xcschemes/Env.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Packages/Env/Sources/Env/HapticManager.swift b/Packages/Env/Sources/Env/HapticManager.swift index 84fb23d9..7b531fbf 100644 --- a/Packages/Env/Sources/Env/HapticManager.swift +++ b/Packages/Env/Sources/Env/HapticManager.swift @@ -7,24 +7,31 @@ public class HapticManager { public enum HapticType { case buttonPress case dataRefresh(intensity: CGFloat) + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) case notification(_ type: UINotificationFeedbackGenerator.FeedbackType) + #endif case tabSelection case timeline } + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) private let selectionGenerator = UISelectionFeedbackGenerator() private let impactGenerator = UIImpactFeedbackGenerator(style: .heavy) private let notificationGenerator = UINotificationFeedbackGenerator() + #endif private let userPreferences = UserPreferences.shared private init() { + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) selectionGenerator.prepare() impactGenerator.prepare() + #endif } @MainActor public func fireHaptic(of type: HapticType) { + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) guard supportsHaptics else { return } switch type { @@ -49,6 +56,7 @@ public class HapticManager { selectionGenerator.selectionChanged() } } + #endif } public var supportsHaptics: Bool { diff --git a/Packages/Explore/.swiftpm/xcode/xcshareddata/xcschemes/Explore.xcscheme b/Packages/Explore/.swiftpm/xcode/xcshareddata/xcschemes/Explore.xcscheme new file mode 100644 index 00000000..50acd07b --- /dev/null +++ b/Packages/Explore/.swiftpm/xcode/xcshareddata/xcschemes/Explore.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Packages/Lists/.swiftpm/xcode/xcshareddata/xcschemes/Lists.xcscheme b/Packages/Lists/.swiftpm/xcode/xcshareddata/xcschemes/Lists.xcscheme new file mode 100644 index 00000000..20191b32 --- /dev/null +++ b/Packages/Lists/.swiftpm/xcode/xcshareddata/xcschemes/Lists.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Packages/Models/.swiftpm/xcode/xcshareddata/xcschemes/Models.xcscheme b/Packages/Models/.swiftpm/xcode/xcshareddata/xcschemes/Models.xcscheme new file mode 100644 index 00000000..0b6ae599 --- /dev/null +++ b/Packages/Models/.swiftpm/xcode/xcshareddata/xcschemes/Models.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Packages/Network/.swiftpm/xcode/xcshareddata/xcschemes/Network.xcscheme b/Packages/Network/.swiftpm/xcode/xcshareddata/xcschemes/Network.xcscheme new file mode 100644 index 00000000..1e37182e --- /dev/null +++ b/Packages/Network/.swiftpm/xcode/xcshareddata/xcschemes/Network.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Packages/Notifications/.swiftpm/xcode/xcshareddata/xcschemes/Notifications.xcscheme b/Packages/Notifications/.swiftpm/xcode/xcshareddata/xcschemes/Notifications.xcscheme new file mode 100644 index 00000000..fba36560 --- /dev/null +++ b/Packages/Notifications/.swiftpm/xcode/xcshareddata/xcschemes/Notifications.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Packages/Notifications/Sources/Notifications/NotificationRowView.swift b/Packages/Notifications/Sources/Notifications/NotificationRowView.swift index 1c76a4ed..88c08097 100644 --- a/Packages/Notifications/Sources/Notifications/NotificationRowView.swift +++ b/Packages/Notifications/Sources/Notifications/NotificationRowView.swift @@ -202,7 +202,7 @@ struct NotificationRowView: View { private var accessibilityUserActions: some View { ForEach(notification.accounts) { account in Button("@\(account.username)") { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) routerPath.navigate(to: .accountDetail(id: account.id)) } } diff --git a/Packages/Status/Sources/Status/Editor/StatusEditorView.swift b/Packages/Status/Sources/Status/Editor/StatusEditorView.swift index 06dfad24..10d7bb23 100644 --- a/Packages/Status/Sources/Status/Editor/StatusEditorView.swift +++ b/Packages/Status/Sources/Status/Editor/StatusEditorView.swift @@ -1,4 +1,3 @@ -import Accounts import AppAccount import DesignSystem import EmojiText diff --git a/Packages/Status/Sources/Status/Editor/StatusEditorViewModel.swift b/Packages/Status/Sources/Status/Editor/StatusEditorViewModel.swift index b2c0c5ac..403f92e0 100644 --- a/Packages/Status/Sources/Status/Editor/StatusEditorViewModel.swift +++ b/Packages/Status/Sources/Status/Editor/StatusEditorViewModel.swift @@ -192,7 +192,7 @@ public class StatusEditorViewModel: NSObject, ObservableObject { case let .edit(status): postStatus = try await client.put(endpoint: Statuses.editStatus(id: status.id, json: data)) } - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) if hasExplicitlySelectedLanguage, let selectedLanguage { preferences?.markLanguageAsSelected(isoCode: selectedLanguage) } @@ -204,7 +204,7 @@ public class StatusEditorViewModel: NSObject, ObservableObject { showPostingErrorAlert = true } isPosting = false - HapticManager.shared.fireHaptic(of: .notification(.error)) + HapticManager.shared.fireHaptic(of: .buttonPress) return nil } } diff --git a/Packages/Status/Sources/Status/List/ReblogCache.swift b/Packages/Status/Sources/Status/List/ReblogCache.swift index 5ef3b527..9213a132 100644 --- a/Packages/Status/Sources/Status/List/ReblogCache.swift +++ b/Packages/Status/Sources/Status/List/ReblogCache.swift @@ -1,6 +1,5 @@ import Env import Foundation -import LRUCache import Models import SwiftUI @@ -12,11 +11,9 @@ public class ReblogCache { } public static let shared = ReblogCache() - var statusCache = LRUCache() private var needsWrite = false init() { - statusCache.countLimit = 300 // can tune the cache here, 100 is super conservative // read any existing cache from disk if FileManager.default.fileExists(atPath: cacheFile.path()) { @@ -24,12 +21,11 @@ public class ReblogCache { let data = try Data(contentsOf: cacheFile) let cacheData = try JSONDecoder().decode([CacheEntry].self, from: data) for entry in cacheData { - statusCache.setValue(entry, forKey: entry.reblogId) + } } catch { print("Error reading cache from disc") } - print("Starting cache has \(statusCache.count) items") } DispatchQueue.main.asyncAfter(deadline: .now() + 30.0) { [weak self] in self?.saveCache() @@ -37,16 +33,6 @@ public class ReblogCache { } private func saveCache() { - if needsWrite { - do { - let data = try JSONEncoder().encode(statusCache.allValues) - try data.write(to: cacheFile) - } catch { - print("Error writing cache to disc") - } - needsWrite = false - } - DispatchQueue.main.asyncAfter(deadline: .now() + 30.0) { [weak self] in self?.saveCache() } @@ -65,56 +51,9 @@ public class ReblogCache { } var i = statuses.count - - for status in statuses.reversed() { - // go backwards through the status list - // so that we can remove items without - // borking the array - - i -= 1 - if let reblog = status.reblog { - if let cached = statusCache.value(forKey: reblog.id) { - // this is already cached - if cached.postId != status.id, cached.seen { - // This was posted by someone other than the person we have in the cache - // and we have seen the items at some point, so we might want to suppress it - - if status.account.id != CurrentAccount.shared.account?.id { - // just a quick check to makes sure that this wasn't boosted by the current - // user. Hiding that would be confusing - // But assuming it isn't then we can suppress this boost - print("suppressing: \(reblog.id)/ \(String(describing: reblog.account.displayName)) by \(String(describing: status.account.displayName))") - statuses.remove(at: i) - // assert(statuses.count == (ct-1)) - } - } - } - cache(status, seen: false) - } - } } public func cache(_ status: Status, seen: Bool) { - var wasSeen = false - var postToCache = status.id - - if let reblog = status.reblog { - // only caching boosts at the moment. - - if let cached = statusCache.value(forKey: reblog.id) { - // every time we see it, we refresh it in the list - // so poplular things are kept in the cache - - wasSeen = cached.seen - - if wasSeen { - postToCache = cached.postId - // if we have seen a particular version of the post - // that's the one we keep - } - } - statusCache.setValue(CacheEntry(reblogId: reblog.id, postId: postToCache, seen: seen || wasSeen), forKey: reblog.id) - needsWrite = true - } + } } diff --git a/Packages/Status/Sources/Status/Row/StatusRowView.swift b/Packages/Status/Sources/Status/Row/StatusRowView.swift index c6ed8f3e..940cbc34 100644 --- a/Packages/Status/Sources/Status/Row/StatusRowView.swift +++ b/Packages/Status/Sources/Status/Row/StatusRowView.swift @@ -173,19 +173,19 @@ public struct StatusRowView: View { private var accessibilityActions: some View { // Add reply and quote, which are lost when the swipe actions are removed Button("status.action.reply") { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) viewModel.routerPath.presentedSheet = .replyToStatusEditor(status: viewModel.status) } Button("settings.swipeactions.status.action.quote") { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) viewModel.routerPath.presentedSheet = .quoteStatusEditor(status: viewModel.status) } .disabled(viewModel.status.visibility == .direct || viewModel.status.visibility == .priv) if viewModel.finalStatus.mediaAttachments.isEmpty == false { Button("accessibility.status.media-viewer-action.label") { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) Task { let attachments = viewModel.finalStatus.mediaAttachments await quickLook.prepareFor(urls: attachments.compactMap { $0.url }, selectedURL: attachments[0].url!) @@ -200,14 +200,14 @@ public struct StatusRowView: View { } Button("@\(viewModel.status.account.username)") { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) viewModel.routerPath.navigate(to: .accountDetail(id: viewModel.status.account.id)) } // Add a reference to the post creator if viewModel.status.account != viewModel.finalStatus.account { Button("@\(viewModel.finalStatus.account.username)") { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) viewModel.routerPath.navigate(to: .accountDetail(id: viewModel.finalStatus.account.id)) } } @@ -218,18 +218,18 @@ public struct StatusRowView: View { case .url: if UIApplication.shared.canOpenURL(link.url) { Button("accessibility.tabs.timeline.content-link-\(link.title)") { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) _ = viewModel.routerPath.handle(url: link.url) } } case .hashtag: Button("accessibility.tabs.timeline.content-hashtag-\(link.title)") { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) _ = viewModel.routerPath.handle(url: link.url) } case .mention: Button("\(link.title)") { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) _ = viewModel.routerPath.handle(url: link.url) } } diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift index 1c64962a..c80cd5ba 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift @@ -199,7 +199,7 @@ struct StatusRowActionsView: View { return } } - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) switch action { case .respond: SoundEffectManager.shared.playSound(of: .share) diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift index d04e3ee3..eb2565c8 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift @@ -25,11 +25,6 @@ public struct StatusRowMediaPreviewView: View { @State private var isHidingMedia: Bool = false var availableWidth: CGFloat { - if UIDevice.current.userInterfaceIdiom == .phone && - (UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight) || theme.statusDisplayStyle == .medium - { - return sceneDelegate.windowWidth * 0.80 - } return sceneDelegate.windowWidth } diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowSwipeView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowSwipeView.swift index 0590c98d..7bcda0db 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowSwipeView.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowSwipeView.swift @@ -82,7 +82,7 @@ struct StatusRowSwipeView: View { @ViewBuilder private func makeSwipeButtonForRouterPath(action: StatusAction, destination: SheetDestination) -> some View { Button { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) viewModel.routerPath.presentedSheet = destination } label: { makeSwipeLabel(action: action, style: preferences.swipeActionsIconStyle) @@ -93,7 +93,7 @@ struct StatusRowSwipeView: View { private func makeSwipeButtonForTask(action: StatusAction, privateBoost: Bool = false, task: @escaping () async -> Void) -> some View { Button { Task { - HapticManager.shared.fireHaptic(of: .notification(.success)) + HapticManager.shared.fireHaptic(of: .buttonPress) await task() } } label: { diff --git a/Packages/Timeline/.swiftpm/xcode/xcshareddata/xcschemes/Timeline.xcscheme b/Packages/Timeline/.swiftpm/xcode/xcshareddata/xcschemes/Timeline.xcscheme new file mode 100644 index 00000000..03607c66 --- /dev/null +++ b/Packages/Timeline/.swiftpm/xcode/xcshareddata/xcschemes/Timeline.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + +