From 6bbe352f7eeb97e11e05e9c0ecd278875d6750f5 Mon Sep 17 00:00:00 2001 From: Thomas Ricouard Date: Sun, 25 Dec 2022 19:15:35 +0100 Subject: [PATCH] WIP posting photos --- IceCubesApp.xcodeproj/project.pbxproj | 12 +++++--- .../Status/Editor/StatusEditorView.swift | 26 +++++++++++++---- .../Status/Editor/StatusEditorViewModel.swift | 29 +++++++++++++++++++ 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/IceCubesApp.xcodeproj/project.pbxproj b/IceCubesApp.xcodeproj/project.pbxproj index 7ecf271a..0959985c 100644 --- a/IceCubesApp.xcodeproj/project.pbxproj +++ b/IceCubesApp.xcodeproj/project.pbxproj @@ -393,7 +393,7 @@ CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 350; + CURRENT_PROJECT_VERSION = 400; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = "\"IceCubesApp/Resources\""; DEVELOPMENT_TEAM = Z6P74P6T99; @@ -401,6 +401,8 @@ ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = IceCubesApp/Info.plist; + INFOPLIST_KEY_NSCameraUsageDescription = "Upload photos & videos to Mastodon"; + INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Upload photos & videos to Mastodon"; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; @@ -415,7 +417,7 @@ LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 13.0; - MARKETING_VERSION = 0.3.5; + MARKETING_VERSION = 0.4; PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.IceCubesApp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; @@ -437,7 +439,7 @@ CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 350; + CURRENT_PROJECT_VERSION = 400; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = "\"IceCubesApp/Resources\""; DEVELOPMENT_TEAM = Z6P74P6T99; @@ -445,6 +447,8 @@ ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = IceCubesApp/Info.plist; + INFOPLIST_KEY_NSCameraUsageDescription = "Upload photos & videos to Mastodon"; + INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Upload photos & videos to Mastodon"; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; @@ -459,7 +463,7 @@ LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 13.0; - MARKETING_VERSION = 0.3.5; + MARKETING_VERSION = 0.4; PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.IceCubesApp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; diff --git a/Packages/Status/Sources/Status/Editor/StatusEditorView.swift b/Packages/Status/Sources/Status/Editor/StatusEditorView.swift index 7a2b2509..478c9fe3 100644 --- a/Packages/Status/Sources/Status/Editor/StatusEditorView.swift +++ b/Packages/Status/Sources/Status/Editor/StatusEditorView.swift @@ -5,6 +5,7 @@ import DesignSystem import TextView import Models import Network +import PhotosUI public struct StatusEditorView: View { @EnvironmentObject private var client: Client @@ -20,10 +21,11 @@ public struct StatusEditorView: View { public var body: some View { NavigationStack { ZStack(alignment: .bottom) { - VStack { + VStack(spacing: 12) { accountHeaderView TextView($viewModel.statusText) .placeholder("What's on your mind") + mediasView Spacer() } accessoryView @@ -64,7 +66,8 @@ public struct StatusEditorView: View { } } - @ViewBuilder private var accountHeaderView: some View { + @ViewBuilder + private var accountHeaderView: some View { if let account = currentAccount.account { HStack { AvatarView(url: account.avatar, size: .status) @@ -81,11 +84,24 @@ public struct StatusEditorView: View { } } + private var mediasView: some View { + ScrollView(.horizontal) { + HStack { + ForEach(viewModel.mediasImages) { container in + Image(uiImage: container.image) + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: 150, height: 150) + .clipped() + } + } + } + } + private var accessoryView: some View { HStack { - Button { - - } label: { + PhotosPicker(selection: $viewModel.selectedMedias, + matching: .images) { Image(systemName: "photo.fill.on.rectangle.fill") } Spacer() diff --git a/Packages/Status/Sources/Status/Editor/StatusEditorViewModel.swift b/Packages/Status/Sources/Status/Editor/StatusEditorViewModel.swift index 54123c67..332a99e5 100644 --- a/Packages/Status/Sources/Status/Editor/StatusEditorViewModel.swift +++ b/Packages/Status/Sources/Status/Editor/StatusEditorViewModel.swift @@ -2,6 +2,7 @@ import SwiftUI import DesignSystem import Models import Network +import PhotosUI @MainActor class StatusEditorViewModel: ObservableObject { @@ -13,6 +14,17 @@ class StatusEditorViewModel: ObservableObject { } @Published var isPosting: Bool = false + @Published var selectedMedias: [PhotosPickerItem] = [] { + didSet { + inflateSelectedMedias() + } + } + @Published var mediasImages: [ImageContainer] = [] + + struct ImageContainer: Identifiable { + let id = UUID().uuidString + let image: UIImage + } var client: Client? private var internalUpdate: Bool = false @@ -78,5 +90,22 @@ class StatusEditorViewModel: ObservableObject { } } + + func inflateSelectedMedias() { + for media in selectedMedias { + media.loadTransferable(type: Data.self) { [weak self] result in + switch result { + case .success(let data?): + if let image = UIImage(data: data) { + DispatchQueue.main.async { + self?.mediasImages.append(.init(image: image)) + } + } + default: + break + } + } + } + } }