From d28c11940d6a038a71a9b8becb4826b69388bff0 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Fri, 31 Oct 2025 19:02:53 +0800 Subject: [PATCH] :bug: Bug fixes --- README.md | 6 ++ ios/Podfile.lock | 2 +- ios/Runner.xcodeproj/project.pbxproj | 22 ++++++- ios/Runner/Info.plist | 2 + .../NotificationService.swift | 58 +++++++++++++------ .../Views/ChatViews.swift | 2 +- .../Views/StatusCreationView.swift | 4 +- lib/screens/settings.dart | 2 +- lib/widgets/alert.dart | 20 +++++-- lib/widgets/post/compose_submit_utils.dart | 17 ------ 10 files changed, 87 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index e38a9cbb..680484c3 100644 --- a/README.md +++ b/README.md @@ -62,3 +62,9 @@ If you want to build the release version, use the flutter build command. Learn m ```bash flutter build ``` + +### Known Issues + +Due to the issues with the flutter build tools, [see](https://github.com/flutter/flutter/issues/160622). + +Since there is a watchOS app for iOS, you're unable to use the flutter cli to run iOS app. Use xcode instead. \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e06d6bcc..e989fa23 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -571,6 +571,6 @@ SPEC CHECKSUMS: wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556 WebRTC-SDK: 40d4f5ba05cadff14e4db5614aec402a633f007e -PODFILE CHECKSUM: 9924dcd1590471adb798f3a0876bedd6a65ea145 +PODFILE CHECKSUM: 34a6810e5629b6394fac3c1a962f601a58f86cb2 COCOAPODS: 1.16.2 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 11b60d22..621a4635 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 77; objects = { /* Begin PBXBuildFile section */ @@ -182,8 +182,6 @@ /* Begin PBXFileSystemSynchronizedRootGroup section */ 7310A7D52EB10962002C0FD3 /* WatchRunner Watch App */ = { isa = PBXFileSystemSynchronizedRootGroup; - exceptions = ( - ); path = "WatchRunner Watch App"; sourceTree = ""; }; @@ -671,10 +669,14 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); + inputPaths = ( + ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; @@ -732,10 +734,14 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); + inputPaths = ( + ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; @@ -764,10 +770,14 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-WatchRunner Watch App/Pods-WatchRunner Watch App-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); + inputPaths = ( + ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-WatchRunner Watch App/Pods-WatchRunner Watch App-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-WatchRunner Watch App/Pods-WatchRunner Watch App-frameworks.sh\"\n"; @@ -1006,6 +1016,7 @@ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; + WATCHOS_DEPLOYMENT_TARGET = 11.6; }; name = Profile; }; @@ -1086,6 +1097,7 @@ INFOPLIST_KEY_CFBundleDisplayName = WatchRunner; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = dev.solsynth.solian; + IPHONEOS_DEPLOYMENT_TARGET = 16.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1135,6 +1147,7 @@ INFOPLIST_KEY_CFBundleDisplayName = WatchRunner; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = dev.solsynth.solian; + IPHONEOS_DEPLOYMENT_TARGET = 16.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1181,6 +1194,7 @@ INFOPLIST_KEY_CFBundleDisplayName = WatchRunner; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = dev.solsynth.solian; + IPHONEOS_DEPLOYMENT_TARGET = 16.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1703,6 +1717,7 @@ SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; + WATCHOS_DEPLOYMENT_TARGET = 11.6; }; name = Debug; }; @@ -1731,6 +1746,7 @@ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; + WATCHOS_DEPLOYMENT_TARGET = 11.6; }; name = Release; }; diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 33137916..e032683f 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -95,6 +95,8 @@ UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait + WKCompanionAppBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) UISupportedInterfaceOrientations~ipad UIInterfaceOrientationLandscapeLeft diff --git a/ios/SolianNotificationService/NotificationService.swift b/ios/SolianNotificationService/NotificationService.swift index e9bc6bf6..0b70c8b2 100644 --- a/ios/SolianNotificationService/NotificationService.swift +++ b/ios/SolianNotificationService/NotificationService.swift @@ -57,37 +57,57 @@ class NotificationService: UNNotificationServiceExtension { guard let meta = content.userInfo["meta"] as? [AnyHashable: Any] else { throw ParseNotificationPayloadError.missingMetadata("The notification has no meta.") } - + let pfpIdentifier = meta["pfp"] as? String - let metaCopy = meta as? [String: Any] ?? [:] let pfpUrl = pfpIdentifier != nil ? getAttachmentUrl(for: pfpIdentifier!) : nil - - let targetSize = 512 - let scaleProcessor = ResizingImageProcessor(referenceSize: CGSize(width: targetSize, height: targetSize), mode: .aspectFit) - - KingfisherManager.shared.retrieveImage(with: URL(string: pfpUrl!)!, options: [.processor(scaleProcessor)], completionHandler: { result in - var image: Data? - switch result { - case .success(let value): - image = value.image.pngData() - case .failure(let error): - print("Unable to get pfp url: \(error)") - } - - let handle = INPersonHandle(value: "\(metaCopy["user_id"] ?? "")", type: .unknown) + + let handle = INPersonHandle(value: "\(metaCopy["user_id"] ?? "")", type: .unknown) + + if let pfpUrl = pfpUrl, let url = URL(string: pfpUrl) { + let targetSize = 512 + let scaleProcessor = ResizingImageProcessor(referenceSize: CGSize(width: targetSize, height: targetSize), mode: .aspectFit) + + KingfisherManager.shared.retrieveImage(with: url, options: [.processor(scaleProcessor)], completionHandler: { result in + var image: Data? + switch result { + case .success(let value): + image = value.image.pngData() + case .failure(let error): + print("Unable to get pfp url: \(error)") + } + + let sender = INPerson( + personHandle: handle, + nameComponents: PersonNameComponents(nickname: "\(metaCopy["sender_name"] ?? "")"), + displayName: content.title, + image: image == nil ? nil : INImage(imageData: image!), + contactIdentifier: nil, + customIdentifier: nil + ) + + let intent = self.createMessageIntent(with: sender, meta: metaCopy, body: content.body) + self.donateInteraction(for: intent) + + content.categoryIdentifier = "CHAT_MESSAGE" + self.contentHandler?(content) + }) + } else { let sender = INPerson( personHandle: handle, nameComponents: PersonNameComponents(nickname: "\(metaCopy["sender_name"] ?? "")"), displayName: content.title, - image: image == nil ? nil : INImage(imageData: image!), + image: nil, contactIdentifier: nil, customIdentifier: nil ) - + + let intent = self.createMessageIntent(with: sender, meta: metaCopy, body: content.body) + self.donateInteraction(for: intent) + content.categoryIdentifier = "CHAT_MESSAGE" self.contentHandler?(content) - }) + } } private func handleDefaultNotification(content: UNMutableNotificationContent) throws { diff --git a/ios/WatchRunner Watch App/Views/ChatViews.swift b/ios/WatchRunner Watch App/Views/ChatViews.swift index 997c9dc9..a90a5417 100644 --- a/ios/WatchRunner Watch App/Views/ChatViews.swift +++ b/ios/WatchRunner Watch App/Views/ChatViews.swift @@ -370,7 +370,7 @@ struct ChatRoomView: View { } } .labelStyle(.iconOnly) - .buttonStyle(.glass) + .buttonStyle(.automatic) .disabled(messageText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || isSending) .frame(width: 40, height: 40) } diff --git a/ios/WatchRunner Watch App/Views/StatusCreationView.swift b/ios/WatchRunner Watch App/Views/StatusCreationView.swift index 38db1397..2af0b5b4 100644 --- a/ios/WatchRunner Watch App/Views/StatusCreationView.swift +++ b/ios/WatchRunner Watch App/Views/StatusCreationView.swift @@ -81,14 +81,14 @@ struct StatusCreationView: View { Button("Cancel") { dismiss() } - .buttonStyle(.glass) + .buttonStyle(.automatic) Button(isSubmitting ? "Saving..." : "Save") { Task { await submitStatus() } } - .buttonStyle(.glassProminent) + .buttonStyle(.automatic) .disabled(isSubmitting) } .padding(.horizontal) diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index d97e25d7..840dabda 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -425,7 +425,7 @@ class SettingsScreen extends HookConsumerWidget { // FAB position settings ListTile( minLeadingWidth: 48, - title: Text('fabPosition').tr(), + title: Text('fabLocation').tr(), contentPadding: const EdgeInsets.only(left: 24, right: 17), leading: const Icon(Symbols.adjust), trailing: DropdownButtonHideUnderline( diff --git a/lib/widgets/alert.dart b/lib/widgets/alert.dart index 61f55e2a..48001f32 100644 --- a/lib/widgets/alert.dart +++ b/lib/widgets/alert.dart @@ -9,12 +9,24 @@ export 'content/alert.native.dart' if (dart.library.html) 'content/alert.web.dart'; void showSnackBar(String message, {SnackBarAction? action}) { + final context = globalOverlay.currentState!.context; + final screenWidth = MediaQuery.of(context).size.width; + final padding = 40.0; + final availableWidth = screenWidth - padding; + showTopSnackBar( globalOverlay.currentState!, - ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 480), - child: Center( - child: Card(child: Text(message).padding(horizontal: 20, vertical: 16)), + Center( + child: ConstrainedBox( + constraints: BoxConstraints( + minWidth: availableWidth.clamp(0, 400), + maxWidth: availableWidth.clamp(0, 600), + ), + child: Card( + elevation: 2, + color: Theme.of(context).colorScheme.surfaceContainer, + child: Text(message).padding(horizontal: 20, vertical: 16), + ), ), ), snackBarPosition: SnackBarPosition.bottom, diff --git a/lib/widgets/post/compose_submit_utils.dart b/lib/widgets/post/compose_submit_utils.dart index 7e8ec4ed..9fab492b 100644 --- a/lib/widgets/post/compose_submit_utils.dart +++ b/lib/widgets/post/compose_submit_utils.dart @@ -22,23 +22,6 @@ class ComposeSubmitUtils { throw Exception('Already submitting'); } - // Don't submit empty posts (no content and no attachments) - final hasContent = - state.titleController.text.trim().isNotEmpty || - state.descriptionController.text.trim().isNotEmpty || - state.contentController.text.trim().isNotEmpty; - final hasAttachments = state.attachments.value.isNotEmpty; - - if (!hasContent && !hasAttachments) { - // Show error message if context is mounted - if (context.mounted) { - ScaffoldMessenger.of( - context, - ).showSnackBar(SnackBar(content: Text('postContentEmpty'))); - } - throw Exception('Post content is empty'); // Don't submit empty posts - } - try { state.submitting.value = true;