diff --git a/IceCubesActionExtension/IceCubesActionExtension.entitlements b/IceCubesActionExtension/IceCubesActionExtension.entitlements
new file mode 100644
index 00000000..ee95ab7e
--- /dev/null
+++ b/IceCubesActionExtension/IceCubesActionExtension.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.network.client
+
+
+
diff --git a/IceCubesApp.xcodeproj/project.pbxproj b/IceCubesApp.xcodeproj/project.pbxproj
index 2220b050..6a6cf842 100644
--- a/IceCubesApp.xcodeproj/project.pbxproj
+++ b/IceCubesApp.xcodeproj/project.pbxproj
@@ -75,7 +75,6 @@
9FAD85A0297456A100496AB1 /* Models in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD859F297456A100496AB1 /* Models */; };
9FAD85A2297456A400496AB1 /* Env in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD85A1297456A400496AB1 /* Env */; };
9FAD85A4297456A800496AB1 /* DesignSystem in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD85A3297456A800496AB1 /* DesignSystem */; };
- 9FAD85A8297582F100496AB1 /* QuickLookRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAD85A7297582F100496AB1 /* QuickLookRepresentable.swift */; };
9FAD85CF2975B68900496AB1 /* SideBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAD85CE2975B68900496AB1 /* SideBarView.swift */; };
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAE4ACA293783B000772766 /* SettingsTab.swift */; };
9FAE4ACE29379A5A00772766 /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAE4ACD29379A5A00772766 /* KeychainSwift */; };
@@ -103,7 +102,7 @@
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, ); }; };
+ E9DF420729830FEC0003AAD2 /* IceCubesActionExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = E9DF41FA29830FEC0003AAD2 /* IceCubesActionExtension.appex */; platformFilter = ios; 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 */
@@ -212,13 +211,13 @@
9FAD858A29743F7400496AB1 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; };
9FAD858F29743F7400496AB1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
9FAD859629743F7E00496AB1 /* IceCubesShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = IceCubesShareExtension.entitlements; sourceTree = ""; };
- 9FAD85A7297582F100496AB1 /* QuickLookRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickLookRepresentable.swift; sourceTree = ""; };
9FAD85CE2975B68900496AB1 /* SideBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideBarView.swift; sourceTree = ""; };
9FAE4AC8293774FF00772766 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
9FAE4ACA293783B000772766 /* SettingsTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTab.swift; sourceTree = ""; };
9FBFE639292A715500C250E9 /* IceCubesApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IceCubesApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
9FBFE63C292A715500C250E9 /* IceCubesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IceCubesApp.swift; sourceTree = ""; };
9FBFE642292A715600C250E9 /* IceCubesApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = IceCubesApp.entitlements; sourceTree = ""; };
+ 9FC60CB82AE6C2F600C6EAD2 /* IceCubesActionExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = IceCubesActionExtension.entitlements; sourceTree = ""; };
9FCBB3D22984EFD5009B77EE /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; };
9FCBB3D429859615009B77EE /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = ca.lproj/InfoPlist.strings; sourceTree = ""; };
9FD34822293D06E800DB0EE9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
@@ -343,7 +342,6 @@
9FBFE63C292A715500C250E9 /* IceCubesApp.swift */,
9F398AA52935FE8A00A889F2 /* AppRegistry.swift */,
639CDF9B296AC82F00C35E58 /* SafariRouter.swift */,
- 9FAD85A7297582F100496AB1 /* QuickLookRepresentable.swift */,
9FAD85CE2975B68900496AB1 /* SideBarView.swift */,
);
path = App;
@@ -517,6 +515,7 @@
E9DF41FD29830FEC0003AAD2 /* IceCubesActionExtension */ = {
isa = PBXGroup;
children = (
+ 9FC60CB82AE6C2F600C6EAD2 /* IceCubesActionExtension.entitlements */,
E9DF420029830FEC0003AAD2 /* ActionRequestHandler.swift */,
E9DF420229830FEC0003AAD2 /* Action.js */,
E9DF420429830FEC0003AAD2 /* Info.plist */,
@@ -818,7 +817,6 @@
9F55C68D2955968700F94077 /* ExploreTab.swift in Sources */,
9F1E8B47298EBCBB00609F80 /* HapticSettingsView.swift in Sources */,
9F2A5411296A1429009B2D7C /* PushNotificationsView.swift in Sources */,
- 9FAD85A8297582F100496AB1 /* QuickLookRepresentable.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -847,6 +845,7 @@
};
E9DF420629830FEC0003AAD2 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
+ platformFilter = ios;
target = E9DF41F929830FEC0003AAD2 /* IceCubesActionExtension */;
targetProxy = E9DF420529830FEC0003AAD2 /* PBXContainerItemProxy */;
};
@@ -881,6 +880,7 @@
CODE_SIGN_ENTITLEMENTS = IceCubesNotifications/IceCubesNotifications.entitlements;
CODE_SIGN_IDENTITY = "-";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
+ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 730;
DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)";
@@ -899,6 +899,9 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = YES;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -911,6 +914,7 @@
CODE_SIGN_ENTITLEMENTS = IceCubesNotifications/IceCubesNotifications.entitlements;
CODE_SIGN_IDENTITY = "-";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
+ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 730;
DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)";
@@ -929,6 +933,9 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = YES;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -942,6 +949,7 @@
CODE_SIGN_ENTITLEMENTS = IceCubesShareExtension/IceCubesShareExtension.entitlements;
CODE_SIGN_IDENTITY = "-";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
+ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 730;
DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)";
@@ -960,6 +968,9 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = YES;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -972,6 +983,7 @@
CODE_SIGN_ENTITLEMENTS = IceCubesShareExtension/IceCubesShareExtension.entitlements;
CODE_SIGN_IDENTITY = "-";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
+ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 730;
DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)";
@@ -990,6 +1002,9 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = YES;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -1147,6 +1162,7 @@
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
INFOPLIST_KEY_NSCameraUsageDescription = "Upload photos & videos to Mastodon";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Upload photos & videos to Mastodon";
+ INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
@@ -1166,8 +1182,8 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
- SUPPORTS_MACCATALYST = NO;
- SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
+ SUPPORTS_MACCATALYST = YES;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_STRICT_CONCURRENCY = complete;
SWIFT_VERSION = 5.0;
@@ -1200,6 +1216,7 @@
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
INFOPLIST_KEY_NSCameraUsageDescription = "Upload photos & videos to Mastodon";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Upload photos & videos to Mastodon";
+ INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
@@ -1219,8 +1236,8 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
- SUPPORTS_MACCATALYST = NO;
- SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
+ SUPPORTS_MACCATALYST = YES;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_STRICT_CONCURRENCY = complete;
SWIFT_VERSION = 5.0;
@@ -1232,6 +1249,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = ActionIcon;
+ CODE_SIGN_ENTITLEMENTS = IceCubesActionExtension/IceCubesActionExtension.entitlements;
CODE_SIGN_IDENTITY = "-";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
@@ -1253,6 +1271,9 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = YES;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -1263,6 +1284,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = ActionIcon;
+ CODE_SIGN_ENTITLEMENTS = IceCubesActionExtension/IceCubesActionExtension.entitlements;
CODE_SIGN_IDENTITY = "-";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
@@ -1284,6 +1306,9 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = YES;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
diff --git a/IceCubesApp/App/AppRegistry.swift b/IceCubesApp/App/AppRegistry.swift
index f0111ee7..c8928ce1 100644
--- a/IceCubesApp/App/AppRegistry.swift
+++ b/IceCubesApp/App/AppRegistry.swift
@@ -180,3 +180,9 @@ struct ActivityView: UIViewControllerRepresentable {
func updateUIViewController(_: UIActivityViewController, context _: UIViewControllerRepresentableContext) {}
}
+
+extension URL: Identifiable {
+ public var id: String {
+ absoluteString
+ }
+}
diff --git a/IceCubesApp/App/IceCubesApp.swift b/IceCubesApp/App/IceCubesApp.swift
index a0fd9a39..31f1fe14 100644
--- a/IceCubesApp/App/IceCubesApp.swift
+++ b/IceCubesApp/App/IceCubesApp.swift
@@ -37,6 +37,11 @@ struct IceCubesApp: App {
}
var body: some Scene {
+ appScene
+ otherScenes
+ }
+
+ private var appScene: some Scene {
WindowGroup {
appView
.applyTheme(theme)
@@ -60,14 +65,8 @@ struct IceCubesApp: App {
attachments: quickLook.mediaAttachments)
.presentationBackground(.ultraThinMaterial)
.presentationCornerRadius(16)
- .environment(userPreferences)
- .environment(theme)
+ .withEnvironments()
}
- .fullScreenCover(item: $quickLook.url, content: { url in
- QuickLookPreview(selectedURL: url, urls: quickLook.urls)
- .edgesIgnoringSafeArea(.bottom)
- .background(TransparentBackground())
- })
.onChange(of: pushNotificationsService.handledNotification) { _, newValue in
if newValue != nil {
pushNotificationsService.handledNotification = nil
@@ -99,6 +98,7 @@ struct IceCubesApp: App {
watcher.watch(streams: [.user, .direct])
}
}
+
}
@ViewBuilder
@@ -207,6 +207,27 @@ struct IceCubesApp: App {
}
.id(appAccountsManager.currentClient.id)
}
+
+ private var otherScenes: some Scene {
+ WindowGroup(for: WindowDestination.self) { destination in
+ Group {
+ switch destination.wrappedValue {
+ case let .newStatusEditor(visibility):
+ StatusEditorView(mode: .new(visibility: visibility))
+ case let .mediaViewer(attachments, selectedAttachment):
+ MediaUIView(selectedAttachment: selectedAttachment,
+ attachments: attachments)
+ case .none:
+ EmptyView()
+ }
+ }
+ .withEnvironments()
+ .withModelContainer()
+ .applyTheme(theme)
+ }
+ .defaultSize(width: 600, height: 800)
+ .windowResizability(.automatic)
+ }
private func setNewClientsInEnv(client: Client) {
currentAccount.setClient(client: client)
diff --git a/IceCubesApp/App/QuickLookRepresentable.swift b/IceCubesApp/App/QuickLookRepresentable.swift
deleted file mode 100644
index c647c00b..00000000
--- a/IceCubesApp/App/QuickLookRepresentable.swift
+++ /dev/null
@@ -1,101 +0,0 @@
-import QuickLook
-import SwiftUI
-import UIKit
-
-extension URL: Identifiable {
- public var id: String {
- absoluteString
- }
-}
-
-struct QuickLookPreview: UIViewControllerRepresentable {
- let selectedURL: URL
- let urls: [URL]
-
- func makeUIViewController(context _: Context) -> UIViewController {
- AppQLPreviewController(selectedURL: selectedURL, urls: urls)
- }
-
- func updateUIViewController(
- _: UIViewController, context _: Context
- ) {}
-}
-
-@MainActor
-class AppQLPreviewController: UIViewController {
- let selectedURL: URL
- let urls: [URL]
-
- var qlController: QLPreviewController?
-
- init(selectedURL: URL, urls: [URL]) {
- self.selectedURL = selectedURL
- self.urls = urls
- super.init(nibName: nil, bundle: nil)
- }
-
- @available(*, unavailable)
- required init?(coder _: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
-
- override func viewWillAppear(_ animated: Bool) {
- super.viewWillAppear(animated)
- if qlController == nil {
- qlController = QLPreviewController()
- qlController?.dataSource = self
- qlController?.delegate = self
- qlController?.currentPreviewItemIndex = urls.firstIndex(of: selectedURL) ?? 0
- present(qlController!, animated: true)
- }
- }
-}
-
-extension AppQLPreviewController: QLPreviewControllerDataSource {
- nonisolated func numberOfPreviewItems(in _: QLPreviewController) -> Int {
- urls.count
- }
-
- nonisolated func previewController(_: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
- urls[index] as QLPreviewItem
- }
-}
-
-extension AppQLPreviewController: QLPreviewControllerDelegate {
- nonisolated func previewController(_: QLPreviewController, editingModeFor _: QLPreviewItem) -> QLPreviewItemEditingMode {
- .createCopy
- }
-
- nonisolated func previewControllerWillDismiss(_: QLPreviewController) {
- Task { @MainActor in
- dismiss(animated: true)
- }
- }
-
- nonisolated func previewControllerDidDismiss(_: QLPreviewController) {
- Task { @MainActor in
- dismiss(animated: true)
- }
- }
-}
-
-struct TransparentBackground: UIViewControllerRepresentable {
- public func makeUIViewController(context _: Context) -> UIViewController {
- TransparentController()
- }
-
- public func updateUIViewController(_: UIViewController, context _: Context) {}
-
- class TransparentController: UIViewController {
- override func viewDidLoad() {
- super.viewDidLoad()
- view.backgroundColor = .clear
- }
-
- override func willMove(toParent parent: UIViewController?) {
- super.willMove(toParent: parent)
- parent?.view?.backgroundColor = .clear
- parent?.modalPresentationStyle = .overCurrentContext
- }
- }
-}
diff --git a/IceCubesApp/App/SafariRouter.swift b/IceCubesApp/App/SafariRouter.swift
index 128647c6..2ba875b2 100644
--- a/IceCubesApp/App/SafariRouter.swift
+++ b/IceCubesApp/App/SafariRouter.swift
@@ -42,7 +42,7 @@ private struct SafariRouter: ViewModifier {
return .handled
}
}
- guard preferences.preferredBrowser == .inAppSafari, !ProcessInfo.processInfo.isiOSAppOnMac else { return .systemAction }
+ guard preferences.preferredBrowser == .inAppSafari, !ProcessInfo.processInfo.isMacCatalystApp else { return .systemAction }
// SFSafariViewController only supports initial URLs with http:// or https:// schemes.
guard let scheme = url.scheme, ["https", "http"].contains(scheme.lowercased()) else {
return .systemAction
diff --git a/IceCubesApp/App/SideBarView.swift b/IceCubesApp/App/SideBarView.swift
index 01beb719..d966f6df 100644
--- a/IceCubesApp/App/SideBarView.swift
+++ b/IceCubesApp/App/SideBarView.swift
@@ -7,6 +7,8 @@ import SwiftUI
@MainActor
struct SideBarView: View {
+ @Environment(\.openWindow) private var openWindow
+
@Environment(AppAccountsManager.self) private var appAccounts
@Environment(CurrentAccount.self) private var currentAccount
@Environment(Theme.self) private var theme
@@ -55,7 +57,11 @@ struct SideBarView: View {
private var postButton: some View {
Button {
- routerPath.presentedSheet = .newStatusEditor(visibility: userPreferences.postVisibility)
+ if ProcessInfo.processInfo.isMacCatalystApp {
+ openWindow(value: WindowDestination.newStatusEditor(visibility: userPreferences.postVisibility))
+ } else {
+ routerPath.presentedSheet = .newStatusEditor(visibility: userPreferences.postVisibility)
+ }
} label: {
Image(systemName: "square.and.pencil")
.resizable()
diff --git a/IceCubesApp/App/Tabs/Settings/SettingsTab.swift b/IceCubesApp/App/Tabs/Settings/SettingsTab.swift
index 9b804f12..88af1e56 100644
--- a/IceCubesApp/App/Tabs/Settings/SettingsTab.swift
+++ b/IceCubesApp/App/Tabs/Settings/SettingsTab.swift
@@ -169,7 +169,7 @@ struct SettingsTabs: View {
private var otherSections: some View {
@Bindable var preferences = preferences
Section("settings.section.other") {
- if !ProcessInfo.processInfo.isiOSAppOnMac {
+ if !ProcessInfo.processInfo.isMacCatalystApp{
Picker(selection: $preferences.preferredBrowser) {
ForEach(PreferredBrowser.allCases, id: \.rawValue) { browser in
switch browser {
@@ -202,7 +202,7 @@ struct SettingsTabs: View {
private var appSection: some View {
Section {
- if !ProcessInfo.processInfo.isiOSAppOnMac {
+ if !ProcessInfo.processInfo.isMacCatalystApp {
NavigationLink(destination: IconSelectorView()) {
Label {
Text("settings.app.icon")
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/128.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/128.png
deleted file mode 100755
index 8ff599a7..00000000
Binary files a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/128.png and /dev/null differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/16.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/16.png
deleted file mode 100755
index c9f41c69..00000000
Binary files a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/16.png and /dev/null differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/256.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/256.png
deleted file mode 100755
index c5fdb987..00000000
Binary files a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/256.png and /dev/null differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/32.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/32.png
deleted file mode 100755
index 7d20ede1..00000000
Binary files a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/32.png and /dev/null differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/512.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/512.png
deleted file mode 100755
index ca8a6bd7..00000000
Binary files a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/512.png and /dev/null differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/60.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/60.png
old mode 100755
new mode 100644
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/64.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/64.png
deleted file mode 100755
index ec0d2cea..00000000
Binary files a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/64.png and /dev/null differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Contents.json
index 5e8372b6..41745e62 100755
--- a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -1,284 +1,218 @@
{
- "images": [
- {
- "size": "60x60",
- "expected-size": "180",
- "filename": "180.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "iphone",
- "scale": "3x"
- },
- {
- "size": "40x40",
- "expected-size": "80",
- "filename": "80.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "iphone",
- "scale": "2x"
- },
- {
- "size": "40x40",
- "expected-size": "120",
- "filename": "120.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "iphone",
- "scale": "3x"
- },
- {
- "size": "60x60",
- "expected-size": "120",
- "filename": "120.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "iphone",
- "scale": "2x"
- },
- {
- "size": "57x57",
- "expected-size": "57",
- "filename": "57.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "iphone",
- "scale": "1x"
- },
- {
- "size": "29x29",
- "expected-size": "58",
- "filename": "58.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "iphone",
- "scale": "2x"
- },
- {
- "size": "29x29",
- "expected-size": "29",
- "filename": "29.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "iphone",
- "scale": "1x"
- },
- {
- "size": "29x29",
- "expected-size": "87",
- "filename": "87.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "iphone",
- "scale": "3x"
- },
- {
- "size": "57x57",
- "expected-size": "114",
- "filename": "114.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "iphone",
- "scale": "2x"
- },
- {
- "size": "20x20",
- "expected-size": "40",
- "filename": "40.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "iphone",
- "scale": "2x"
- },
- {
- "size": "20x20",
- "expected-size": "60",
- "filename": "60.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "iphone",
- "scale": "3x"
- },
- {
- "size": "1024x1024",
- "filename": "1024.png",
- "expected-size": "1024",
- "idiom": "ios-marketing",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "scale": "1x"
- },
- {
- "size": "40x40",
- "expected-size": "80",
- "filename": "80.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "ipad",
- "scale": "2x"
- },
- {
- "size": "72x72",
- "expected-size": "72",
- "filename": "72.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "ipad",
- "scale": "1x"
- },
- {
- "size": "76x76",
- "expected-size": "152",
- "filename": "152.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "ipad",
- "scale": "2x"
- },
- {
- "size": "50x50",
- "expected-size": "100",
- "filename": "100.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "ipad",
- "scale": "2x"
- },
- {
- "size": "29x29",
- "expected-size": "58",
- "filename": "58.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "ipad",
- "scale": "2x"
- },
- {
- "size": "76x76",
- "expected-size": "76",
- "filename": "76.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "ipad",
- "scale": "1x"
- },
- {
- "size": "29x29",
- "expected-size": "29",
- "filename": "29.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "ipad",
- "scale": "1x"
- },
- {
- "size": "50x50",
- "expected-size": "50",
- "filename": "50.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "ipad",
- "scale": "1x"
- },
- {
- "size": "72x72",
- "expected-size": "144",
- "filename": "144.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "ipad",
- "scale": "2x"
- },
- {
- "size": "40x40",
- "expected-size": "40",
- "filename": "40.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "ipad",
- "scale": "1x"
- },
- {
- "size": "83.5x83.5",
- "expected-size": "167",
- "filename": "167.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "ipad",
- "scale": "2x"
- },
- {
- "size": "20x20",
- "expected-size": "20",
- "filename": "20.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "ipad",
- "scale": "1x"
- },
- {
- "size": "20x20",
- "expected-size": "40",
- "filename": "40.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "ipad",
- "scale": "2x"
- },
- {
- "size": "128x128",
- "expected-size": "128",
- "filename": "128.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "mac",
- "scale": "1x"
- },
- {
- "size": "256x256",
- "expected-size": "256",
- "filename": "256.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "mac",
- "scale": "1x"
- },
- {
- "size": "128x128",
- "expected-size": "256",
- "filename": "256.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "mac",
- "scale": "2x"
- },
- {
- "size": "256x256",
- "expected-size": "512",
- "filename": "512.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "mac",
- "scale": "2x"
- },
- {
- "size": "32x32",
- "expected-size": "32",
- "filename": "32.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "mac",
- "scale": "1x"
- },
- {
- "size": "512x512",
- "expected-size": "512",
- "filename": "512.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "mac",
- "scale": "1x"
- },
- {
- "size": "16x16",
- "expected-size": "16",
- "filename": "16.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "mac",
- "scale": "1x"
- },
- {
- "size": "16x16",
- "expected-size": "32",
- "filename": "32.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "mac",
- "scale": "2x"
- },
- {
- "size": "32x32",
- "expected-size": "64",
- "filename": "64.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "mac",
- "scale": "2x"
- },
- {
- "size": "512x512",
- "expected-size": "1024",
- "filename": "1024.png",
- "folder": "Assets.xcassets/AppIcon.appiconset/",
- "idiom": "mac",
- "scale": "2x"
- }
- ]
-}
\ No newline at end of file
+ "images" : [
+ {
+ "filename" : "40.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "20x20"
+ },
+ {
+ "filename" : "60.png",
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "20x20"
+ },
+ {
+ "filename" : "29.png",
+ "idiom" : "iphone",
+ "scale" : "1x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "58.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "87.png",
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "80.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "40x40"
+ },
+ {
+ "filename" : "120.png",
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "40x40"
+ },
+ {
+ "filename" : "57.png",
+ "idiom" : "iphone",
+ "scale" : "1x",
+ "size" : "57x57"
+ },
+ {
+ "filename" : "114.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "57x57"
+ },
+ {
+ "filename" : "120.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "60x60"
+ },
+ {
+ "filename" : "180.png",
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "60x60"
+ },
+ {
+ "filename" : "20.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "20x20"
+ },
+ {
+ "filename" : "40.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "20x20"
+ },
+ {
+ "filename" : "29.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "58.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "40.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "40x40"
+ },
+ {
+ "filename" : "80.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "40x40"
+ },
+ {
+ "filename" : "50.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "50x50"
+ },
+ {
+ "filename" : "100.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "50x50"
+ },
+ {
+ "filename" : "72.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "72x72"
+ },
+ {
+ "filename" : "144.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "72x72"
+ },
+ {
+ "filename" : "76.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "76x76"
+ },
+ {
+ "filename" : "152.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "76x76"
+ },
+ {
+ "filename" : "167.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "83.5x83.5"
+ },
+ {
+ "filename" : "1024.png",
+ "idiom" : "ios-marketing",
+ "scale" : "1x",
+ "size" : "1024x1024"
+ },
+ {
+ "filename" : "Icon-16.png",
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "16x16"
+ },
+ {
+ "filename" : "Icon-32.png",
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "16x16"
+ },
+ {
+ "filename" : "Icon-32 1.png",
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "32x32"
+ },
+ {
+ "filename" : "Icon-64.png",
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "32x32"
+ },
+ {
+ "filename" : "Icon-128.png",
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "128x128"
+ },
+ {
+ "filename" : "Icon-256 1.png",
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "128x128"
+ },
+ {
+ "filename" : "Icon-256.png",
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "256x256"
+ },
+ {
+ "filename" : "Icon-512 1.png",
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "256x256"
+ },
+ {
+ "filename" : "Icon-512.png",
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "512x512"
+ },
+ {
+ "filename" : "Icon-1024.png",
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "512x512"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-1024.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-1024.png
new file mode 100644
index 00000000..17b11d09
Binary files /dev/null and b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-1024.png differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-128.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-128.png
new file mode 100644
index 00000000..32beb5d8
Binary files /dev/null and b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-128.png differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-16.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-16.png
new file mode 100644
index 00000000..5ed79738
Binary files /dev/null and b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-16.png differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-256 1.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-256 1.png
new file mode 100644
index 00000000..89bc2489
Binary files /dev/null and b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-256 1.png differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-256.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-256.png
new file mode 100644
index 00000000..89bc2489
Binary files /dev/null and b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-256.png differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-32 1.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-32 1.png
new file mode 100644
index 00000000..05d80642
Binary files /dev/null and b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-32 1.png differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-32.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-32.png
new file mode 100644
index 00000000..05d80642
Binary files /dev/null and b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-32.png differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-512 1.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-512 1.png
new file mode 100644
index 00000000..be14fb1b
Binary files /dev/null and b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-512 1.png differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-512.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-512.png
new file mode 100644
index 00000000..be14fb1b
Binary files /dev/null and b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-512.png differ
diff --git a/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-64.png b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-64.png
new file mode 100644
index 00000000..988e7579
Binary files /dev/null and b/IceCubesApp/Assets.xcassets/AppIcon.appiconset/Icon-64.png differ
diff --git a/IceCubesApp/IceCubesApp.entitlements b/IceCubesApp/IceCubesApp.entitlements
index cb44e4cc..b9a62da1 100644
--- a/IceCubesApp/IceCubesApp.entitlements
+++ b/IceCubesApp/IceCubesApp.entitlements
@@ -18,6 +18,8 @@
com.apple.security.files.user-selected.read-only
+ com.apple.security.network.client
+
keychain-access-groups
$(AppIdentifierPrefix)$(BUNDLE_ID_PREFIX).IceCubesApp
diff --git a/IceCubesNotifications/IceCubesNotifications.entitlements b/IceCubesNotifications/IceCubesNotifications.entitlements
index 187bce3e..a60eec3f 100644
--- a/IceCubesNotifications/IceCubesNotifications.entitlements
+++ b/IceCubesNotifications/IceCubesNotifications.entitlements
@@ -2,10 +2,14 @@
+ com.apple.security.app-sandbox
+
com.apple.security.application-groups
group.$(BUNDLE_ID_PREFIX).IceCubesApp
+ com.apple.security.network.client
+
keychain-access-groups
$(AppIdentifierPrefix)$(BUNDLE_ID_PREFIX).IceCubesApp
diff --git a/IceCubesShareExtension/IceCubesShareExtension.entitlements b/IceCubesShareExtension/IceCubesShareExtension.entitlements
index 187bce3e..a60eec3f 100644
--- a/IceCubesShareExtension/IceCubesShareExtension.entitlements
+++ b/IceCubesShareExtension/IceCubesShareExtension.entitlements
@@ -2,10 +2,14 @@
+ com.apple.security.app-sandbox
+
com.apple.security.application-groups
group.$(BUNDLE_ID_PREFIX).IceCubesApp
+ com.apple.security.network.client
+
keychain-access-groups
$(AppIdentifierPrefix)$(BUNDLE_ID_PREFIX).IceCubesApp
diff --git a/Packages/DesignSystem/Sources/DesignSystem/DesignSystem.swift b/Packages/DesignSystem/Sources/DesignSystem/DesignSystem.swift
index c5df1581..803edaa5 100644
--- a/Packages/DesignSystem/Sources/DesignSystem/DesignSystem.swift
+++ b/Packages/DesignSystem/Sources/DesignSystem/DesignSystem.swift
@@ -7,6 +7,6 @@ public extension CGFloat {
static let scrollToViewHeight: CGFloat = 1
static let statusColumnsSpacing: CGFloat = 8
static let secondaryColumnWidth: CGFloat = 400
- static let sidebarWidth: CGFloat = 80
+ static let sidebarWidth: CGFloat = 90
static let pollBarHeight: CGFloat = 30
}
diff --git a/Packages/DesignSystem/Sources/DesignSystem/Font.swift b/Packages/DesignSystem/Sources/DesignSystem/Font.swift
index 31342216..011fbec9 100644
--- a/Packages/DesignSystem/Sources/DesignSystem/Font.swift
+++ b/Packages/DesignSystem/Sources/DesignSystem/Font.swift
@@ -12,7 +12,7 @@ public extension Font {
private static let subheadline = onMac ? 16.0 : 15.0
private static let footnote = onMac ? 15.0 : 13.0
private static let caption = onMac ? 14.0 : 12.0
- private static let onMac = ProcessInfo.processInfo.isiOSAppOnMac
+ private static let onMac = ProcessInfo.processInfo.isMacCatalystApp
private static func customFont(size: CGFloat, relativeTo textStyle: TextStyle) -> Font {
if let chosenFont = Theme.shared.chosenFont {
diff --git a/Packages/DesignSystem/Sources/DesignSystem/SceneDelegate.swift b/Packages/DesignSystem/Sources/DesignSystem/SceneDelegate.swift
index ff71431a..ee32cf7f 100644
--- a/Packages/DesignSystem/Sources/DesignSystem/SceneDelegate.swift
+++ b/Packages/DesignSystem/Sources/DesignSystem/SceneDelegate.swift
@@ -14,5 +14,12 @@ import UIKit
{
guard let windowScene = scene as? UIWindowScene else { return }
window = windowScene.keyWindow
+
+ #if targetEnvironment(macCatalyst)
+ if let titlebar = windowScene.titlebar {
+ titlebar.titleVisibility = .hidden
+ titlebar.toolbar = nil
+ }
+ #endif
}
}
diff --git a/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift b/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift
index 74abfbf9..6bde7001 100644
--- a/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift
+++ b/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift
@@ -16,7 +16,7 @@ public struct AvatarView: View {
case .account:
return .init(width: 80, height: 80)
case .status:
- if ProcessInfo.processInfo.isiOSAppOnMac {
+ if ProcessInfo.processInfo.isMacCatalystApp {
return .init(width: 48, height: 48)
}
return .init(width: 40, height: 40)
diff --git a/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift b/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift
index 52da42a8..c77d3c53 100644
--- a/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift
+++ b/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift
@@ -4,26 +4,15 @@ import SwiftUI
@MainActor
public extension View {
- func statusEditorToolbarItem(routerPath: RouterPath, visibility: Models.Visibility) -> some ToolbarContent {
- ToolbarItem(placement: .navigationBarTrailing) {
- Button {
- routerPath.presentedSheet = .newStatusEditor(visibility: visibility)
- HapticManager.shared.fireHaptic(of: .buttonPress)
- } label: {
- Image(systemName: "square.and.pencil")
- .accessibilityLabel("accessibility.tabs.timeline.new-post.label")
- .accessibilityInputLabels([
- LocalizedStringKey("accessibility.tabs.timeline.new-post.label"),
- LocalizedStringKey("accessibility.tabs.timeline.new-post.inputLabel1"),
- LocalizedStringKey("accessibility.tabs.timeline.new-post.inputLabel2"),
- ])
- }
- }
+ func statusEditorToolbarItem(routerPath: RouterPath,
+ visibility: Models.Visibility) -> some ToolbarContent {
+ StatusEditorToolbarItem(visibility: visibility)
}
}
@MainActor
public struct StatusEditorToolbarItem: ToolbarContent {
+ @Environment(\.openWindow) private var openWindow
@Environment(RouterPath.self) private var routerPath
let visibility: Models.Visibility
@@ -36,8 +25,12 @@ public struct StatusEditorToolbarItem: ToolbarContent {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
Task { @MainActor in
- routerPath.presentedSheet = .newStatusEditor(visibility: visibility)
- HapticManager.shared.fireHaptic(of: .buttonPress)
+ if ProcessInfo.processInfo.isMacCatalystApp {
+ openWindow(value: WindowDestination.newStatusEditor(visibility: visibility))
+ } else {
+ routerPath.presentedSheet = .newStatusEditor(visibility: visibility)
+ HapticManager.shared.fireHaptic(of: .buttonPress)
+ }
}
} label: {
Image(systemName: "square.and.pencil")
diff --git a/Packages/Env/Sources/Env/QuickLook.swift b/Packages/Env/Sources/Env/QuickLook.swift
index 6c7132eb..fb5a991f 100644
--- a/Packages/Env/Sources/Env/QuickLook.swift
+++ b/Packages/Env/Sources/Env/QuickLook.swift
@@ -1,5 +1,4 @@
import Combine
-@preconcurrency import SwiftUI
import Models
import QuickLook
@@ -8,88 +7,10 @@ import QuickLook
public var selectedMediaAttachment: MediaAttachment?
public var mediaAttachments: [MediaAttachment] = []
- public var url: URL? {
- didSet {
- if url == nil {
- cleanup(urls: urls)
- }
- }
- }
- public private(set) var urls: [URL] = []
-
-
public init() {}
public func prepareFor(selectedMediaAttachment: MediaAttachment, mediaAttachments: [MediaAttachment]) {
- if ProcessInfo.processInfo.isiOSAppOnMac, let selectedURL = selectedMediaAttachment.url {
- let urls = mediaAttachments.compactMap{ $0.url }
- Task {
- await prepareFor(urls: urls, selectedURL: selectedURL)
- }
- } else {
- self.selectedMediaAttachment = selectedMediaAttachment
- self.mediaAttachments = mediaAttachments
- }
- }
-
- private func prepareFor(urls: [URL], selectedURL: URL) async {
- var transaction = Transaction(animation: .default)
- transaction.disablesAnimations = true
- do {
- var order = 0
- let pathOrderMap = urls.reduce(into: [String: Int]()) { result, url in
- result[url.lastPathComponent] = order
- order += 1
- }
- let paths: [URL] = try await withThrowingTaskGroup(of: URL.self, body: { group in
- var paths: [URL] = []
- for url in urls {
- group.addTask {
- try await self.localPathFor(url: url)
- }
- }
- for try await path in group {
- paths.append(path)
- }
- return paths.sorted { url1, url2 in
- pathOrderMap[url1.lastPathComponent] ?? 0 < pathOrderMap[url2.lastPathComponent] ?? 0
- }
- })
- withTransaction(transaction) {
- self.urls = paths
- url = paths.first(where: { $0.lastPathComponent == selectedURL.lastPathComponent })
- }
- } catch {
- withTransaction(transaction) {
- self.urls = []
- url = nil
- }
- }
- }
-
- private var quickLookDir: URL {
- try! FileManager.default.url(for: .cachesDirectory,
- in: .userDomainMask,
- appropriateFor: nil,
- create: false)
- .appending(component: "quicklook")
- }
-
- private func localPathFor(url: URL) async throws -> URL {
- try? FileManager.default.createDirectory(at: quickLookDir, withIntermediateDirectories: true)
- let path = quickLookDir.appendingPathComponent(url.lastPathComponent)
-
- // Warning: Non-sendable type '(any URLSessionTaskDelegate)?' exiting main actor-isolated
- // context in call to non-isolated instance method 'data(for:delegate:)' cannot cross actor
- // boundary.
- // This is on the defaulted-to-nil second parameter of `.data(from:delegate:)`.
- // There is a Radar tracking this & others like it.
- let data = try await URLSession.shared.data(from: url).0
- try data.write(to: path)
- return path
- }
-
- private func cleanup(urls _: [URL]) {
- try? FileManager.default.removeItem(at: quickLookDir)
+ self.selectedMediaAttachment = selectedMediaAttachment
+ self.mediaAttachments = mediaAttachments
}
}
diff --git a/Packages/Env/Sources/Env/Router.swift b/Packages/Env/Sources/Env/Router.swift
index 71930353..fce330b3 100644
--- a/Packages/Env/Sources/Env/Router.swift
+++ b/Packages/Env/Sources/Env/Router.swift
@@ -25,6 +25,20 @@ public enum RouterDestination: Hashable {
case tagsList(tags: [Tag])
}
+public enum WindowDestination: Hashable, Codable {
+ case newStatusEditor(visibility: Models.Visibility)
+ case mediaViewer(attachments: [MediaAttachment], selectedAttachment: MediaAttachment)
+
+ var initialSize: CGSize {
+ switch self {
+ case .newStatusEditor:
+ return .init(width: 500, height: 700)
+ case .mediaViewer:
+ return .init(width: 800, height: 600)
+ }
+ }
+}
+
public enum SheetDestination: Identifiable {
case newStatusEditor(visibility: Models.Visibility)
case editStatusEditor(status: Status)
diff --git a/Packages/MediaUI/Sources/MediaUI/MediaUIView.swift b/Packages/MediaUI/Sources/MediaUI/MediaUIView.swift
index cb2ef98d..e46ef11b 100644
--- a/Packages/MediaUI/Sources/MediaUI/MediaUIView.swift
+++ b/Packages/MediaUI/Sources/MediaUI/MediaUIView.swift
@@ -71,6 +71,7 @@ public struct MediaUIView: View, @unchecked Sendable {
@ToolbarContentBuilder
private var toolbarView: some ToolbarContent {
+ #if !targetEnvironment(macCatalyst)
ToolbarItem(placement: .topBarLeading) {
Button {
dismiss()
@@ -78,6 +79,7 @@ public struct MediaUIView: View, @unchecked Sendable {
Image(systemName: "xmark.circle")
}
}
+ #endif
ToolbarItem(placement: .topBarTrailing) {
if let url = attachments.first(where: { $0.id == scrollToId})?.url {
Button {
diff --git a/Packages/Status/Sources/Status/Editor/Components/StatusEditorAccessoryView.swift b/Packages/Status/Sources/Status/Editor/Components/StatusEditorAccessoryView.swift
index d8b03853..9afeba8a 100644
--- a/Packages/Status/Sources/Status/Editor/Components/StatusEditorAccessoryView.swift
+++ b/Packages/Status/Sources/Status/Editor/Components/StatusEditorAccessoryView.swift
@@ -37,7 +37,7 @@ struct StatusEditorAccessoryView: View {
} label: {
Label("status.editor.photo-library", systemImage: "photo")
}
- if !ProcessInfo.processInfo.isiOSAppOnMac {
+ if !ProcessInfo.processInfo.isMacCatalystApp {
Button {
isCameraPickerPresented = true
} label: {
diff --git a/Packages/Status/Sources/Status/Editor/StatusEditorView.swift b/Packages/Status/Sources/Status/Editor/StatusEditorView.swift
index 3e1db09e..89ee291a 100644
--- a/Packages/Status/Sources/Status/Editor/StatusEditorView.swift
+++ b/Packages/Status/Sources/Status/Editor/StatusEditorView.swift
@@ -215,7 +215,7 @@ public struct StatusEditorView: View {
SoundEffectManager.shared.playSound(of: .tootSent)
NotificationCenter.default.post(name: NotificationsName.shareSheetClose,
object: nil)
- if !viewModel.mode.isInShareExtension, !preferences.requestedReview, !ProcessInfo.processInfo.isiOSAppOnMac {
+ if !viewModel.mode.isInShareExtension, !preferences.requestedReview, !ProcessInfo.processInfo.isMacCatalystApp {
if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
SKStoreReviewController.requestReview(in: scene)
}
diff --git a/Packages/Status/Sources/Status/Editor/UITextView/Coordinator.swift b/Packages/Status/Sources/Status/Editor/UITextView/Coordinator.swift
index 658b5c9b..7957584c 100644
--- a/Packages/Status/Sources/Status/Editor/UITextView/Coordinator.swift
+++ b/Packages/Status/Sources/Status/Editor/UITextView/Coordinator.swift
@@ -45,7 +45,7 @@ extension TextView.Representable {
textView.allowsEditingTextAttributes = false
textView.returnKeyType = .default
textView.allowsEditingTextAttributes = true
- if ProcessInfo.processInfo.isiOSAppOnMac {
+ if ProcessInfo.processInfo.isMacCatalystApp {
textView.inlinePredictionType = .no
}
diff --git a/Packages/Status/Sources/Status/Row/StatusRowView.swift b/Packages/Status/Sources/Status/Row/StatusRowView.swift
index 5f5e1a5c..98e75224 100644
--- a/Packages/Status/Sources/Status/Row/StatusRowView.swift
+++ b/Packages/Status/Sources/Status/Row/StatusRowView.swift
@@ -9,6 +9,7 @@ import SwiftUI
@MainActor
public struct StatusRowView: View {
+ @Environment(\.openWindow) private var openWindow
@Environment(\.isInCaptureMode) private var isInCaptureMode: Bool
@Environment(\.redactionReasons) private var reasons
@Environment(\.isCompact) private var isCompact: Bool
@@ -208,7 +209,12 @@ public struct StatusRowView: View {
Button("accessibility.status.media-viewer-action.label") {
HapticManager.shared.fireHaptic(of: .notification(.success))
let attachments = viewModel.finalStatus.mediaAttachments
- quickLook.prepareFor(selectedMediaAttachment: attachments[0], mediaAttachments: attachments)
+ if ProcessInfo.processInfo.isMacCatalystApp {
+ openWindow(value: WindowDestination.mediaViewer(attachments: attachments,
+ selectedAttachment: attachments[0]))
+ } else {
+ quickLook.prepareFor(selectedMediaAttachment: attachments[0], mediaAttachments: attachments)
+ }
}
}
diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift
index 7d398727..d7a9577f 100644
--- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift
+++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift
@@ -8,6 +8,7 @@ import MediaUI
@MainActor
public struct StatusRowMediaPreviewView: View {
+ @Environment(\.openWindow) private var openWindow
@Environment(\.isSecondaryColumn) private var isSecondaryColumn: Bool
@Environment(\.extraLeadingInset) private var extraLeadingInset: CGFloat
@Environment(\.isInCaptureMode) private var isInCaptureMode: Bool
@@ -88,7 +89,12 @@ public struct StatusRowMediaPreviewView: View {
if attachments.count == 1, let attachment = attachments.first {
makeFeaturedImagePreview(attachment: attachment)
.onTapGesture {
- quickLook.prepareFor(selectedMediaAttachment: attachment, mediaAttachments: attachments)
+ if ProcessInfo.processInfo.isMacCatalystApp {
+ openWindow(value: WindowDestination.mediaViewer(attachments: attachments,
+ selectedAttachment: attachment))
+ } else {
+ quickLook.prepareFor(selectedMediaAttachment: attachment, mediaAttachments: attachments)
+ }
}
.accessibilityElement(children: .ignore)
.accessibilityLabel(Self.accessibilityLabel(for: attachment))
@@ -272,7 +278,12 @@ public struct StatusRowMediaPreviewView: View {
// #965: do not create overlapping tappable areas, when multiple images are shown
.contentShape(Rectangle())
.onTapGesture {
- quickLook.prepareFor(selectedMediaAttachment: attachment, mediaAttachments: attachments)
+ if ProcessInfo.processInfo.isMacCatalystApp {
+ openWindow(value: WindowDestination.mediaViewer(attachments: attachments,
+ selectedAttachment: attachment))
+ } else {
+ quickLook.prepareFor(selectedMediaAttachment: attachment, mediaAttachments: attachments)
+ }
}
.accessibilityElement(children: .ignore)
.accessibilityLabel(Self.accessibilityLabel(for: attachment))