mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-09-27 14:10:08 +00:00
Add support for GIPHY + rework loading of the media in the editor
This commit is contained in:
parent
4985e69200
commit
1fa54afc3a
7 changed files with 174 additions and 54 deletions
|
@ -88,9 +88,10 @@
|
||||||
9FBFE64E292A72BD00C250E9 /* Network in Frameworks */ = {isa = PBXBuildFile; productRef = 9FBFE64D292A72BD00C250E9 /* Network */; };
|
9FBFE64E292A72BD00C250E9 /* Network in Frameworks */ = {isa = PBXBuildFile; productRef = 9FBFE64D292A72BD00C250E9 /* Network */; };
|
||||||
9FD34823293D06E800DB0EE9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9FD34822293D06E800DB0EE9 /* Assets.xcassets */; };
|
9FD34823293D06E800DB0EE9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9FD34822293D06E800DB0EE9 /* Assets.xcassets */; };
|
||||||
9FD542E72962D2FF0045321A /* Lists in Frameworks */ = {isa = PBXBuildFile; productRef = 9FD542E62962D2FF0045321A /* Lists */; };
|
9FD542E72962D2FF0045321A /* Lists in Frameworks */ = {isa = PBXBuildFile; productRef = 9FD542E62962D2FF0045321A /* Lists */; };
|
||||||
9FE0346C2ADD5C2100529EA8 /* MediaUI in Frameworks */ = {isa = PBXBuildFile; productRef = 9FE0346B2ADD5C2100529EA8 /* MediaUI */; };
|
|
||||||
9FE151A6293C90F900E9683D /* IconSelectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FE151A5293C90F900E9683D /* IconSelectorView.swift */; };
|
9FE151A6293C90F900E9683D /* IconSelectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FE151A5293C90F900E9683D /* IconSelectorView.swift */; };
|
||||||
9FE3DB57296FEFCA00628CB0 /* AppAccount in Frameworks */ = {isa = PBXBuildFile; productRef = 9FE3DB56296FEFCA00628CB0 /* AppAccount */; };
|
9FE3DB57296FEFCA00628CB0 /* AppAccount in Frameworks */ = {isa = PBXBuildFile; productRef = 9FE3DB56296FEFCA00628CB0 /* AppAccount */; };
|
||||||
|
9FF614472B2EDCE500F7B0E6 /* GiphyUISDK in Frameworks */ = {isa = PBXBuildFile; productRef = 9FF614462B2EDCE500F7B0E6 /* GiphyUISDK */; };
|
||||||
|
9FF614492B2EDCEC00F7B0E6 /* GiphyUISDK in Frameworks */ = {isa = PBXBuildFile; productRef = 9FF614482B2EDCEC00F7B0E6 /* GiphyUISDK */; };
|
||||||
9FFF677C299B7B2C00FE700A /* Notifications in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF677B299B7B2C00FE700A /* Notifications */; };
|
9FFF677C299B7B2C00FE700A /* Notifications in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF677B299B7B2C00FE700A /* Notifications */; };
|
||||||
9FFF677E299B7D2800FE700A /* Status in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF677D299B7D2800FE700A /* Status */; };
|
9FFF677E299B7D2800FE700A /* Status in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF677D299B7D2800FE700A /* Status */; };
|
||||||
9FFF6780299B7D2B00FE700A /* DesignSystem in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF677F299B7D2B00FE700A /* DesignSystem */; };
|
9FFF6780299B7D2B00FE700A /* DesignSystem in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF677F299B7D2B00FE700A /* DesignSystem */; };
|
||||||
|
@ -228,7 +229,6 @@
|
||||||
9FCBB3D429859615009B77EE /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = ca.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
9FCBB3D429859615009B77EE /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = ca.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
9FD34822293D06E800DB0EE9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
9FD34822293D06E800DB0EE9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
9FD542E52962D2CE0045321A /* Lists */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Lists; path = Packages/Lists; sourceTree = "<group>"; };
|
9FD542E52962D2CE0045321A /* Lists */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Lists; path = Packages/Lists; sourceTree = "<group>"; };
|
||||||
9FE034692ADD597100529EA8 /* MediaUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = MediaUI; path = Packages/MediaUI; sourceTree = "<group>"; };
|
|
||||||
9FE0346A2ADD59AC00529EA8 /* MediaUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = MediaUI; path = Packages/MediaUI; sourceTree = "<group>"; };
|
9FE0346A2ADD59AC00529EA8 /* MediaUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = MediaUI; path = Packages/MediaUI; sourceTree = "<group>"; };
|
||||||
9FE151A5293C90F900E9683D /* IconSelectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconSelectorView.swift; sourceTree = "<group>"; };
|
9FE151A5293C90F900E9683D /* IconSelectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconSelectorView.swift; sourceTree = "<group>"; };
|
||||||
9FE3DB55296FEF5800628CB0 /* AppAccount */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = AppAccount; path = Packages/AppAccount; sourceTree = "<group>"; };
|
9FE3DB55296FEF5800628CB0 /* AppAccount */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = AppAccount; path = Packages/AppAccount; sourceTree = "<group>"; };
|
||||||
|
@ -275,6 +275,7 @@
|
||||||
9FAD85A2297456A400496AB1 /* Env in Frameworks */,
|
9FAD85A2297456A400496AB1 /* Env in Frameworks */,
|
||||||
9FAD85A0297456A100496AB1 /* Models in Frameworks */,
|
9FAD85A0297456A100496AB1 /* Models in Frameworks */,
|
||||||
9FAD85A4297456A800496AB1 /* DesignSystem in Frameworks */,
|
9FAD85A4297456A800496AB1 /* DesignSystem in Frameworks */,
|
||||||
|
9FF614492B2EDCEC00F7B0E6 /* GiphyUISDK in Frameworks */,
|
||||||
9FAD859E2974569B00496AB1 /* Account in Frameworks */,
|
9FAD859E2974569B00496AB1 /* Account in Frameworks */,
|
||||||
9FAD859C2974422700496AB1 /* AppAccount in Frameworks */,
|
9FAD859C2974422700496AB1 /* AppAccount in Frameworks */,
|
||||||
9FAD859A297440CB00496AB1 /* KeychainSwift in Frameworks */,
|
9FAD859A297440CB00496AB1 /* KeychainSwift in Frameworks */,
|
||||||
|
@ -296,13 +297,13 @@
|
||||||
9FAE4ACE29379A5A00772766 /* KeychainSwift in Frameworks */,
|
9FAE4ACE29379A5A00772766 /* KeychainSwift in Frameworks */,
|
||||||
9F7335EA2966B3F800AFF0BA /* Conversations in Frameworks */,
|
9F7335EA2966B3F800AFF0BA /* Conversations in Frameworks */,
|
||||||
9FE3DB57296FEFCA00628CB0 /* AppAccount in Frameworks */,
|
9FE3DB57296FEFCA00628CB0 /* AppAccount in Frameworks */,
|
||||||
9FE0346C2ADD5C2100529EA8 /* MediaUI in Frameworks */,
|
|
||||||
9F398AA92935FFDB00A889F2 /* Account in Frameworks */,
|
9F398AA92935FFDB00A889F2 /* Account in Frameworks */,
|
||||||
9FBFE64E292A72BD00C250E9 /* Network in Frameworks */,
|
9FBFE64E292A72BD00C250E9 /* Network in Frameworks */,
|
||||||
9FD542E72962D2FF0045321A /* Lists in Frameworks */,
|
9FD542E72962D2FF0045321A /* Lists in Frameworks */,
|
||||||
9F398AAB2935FFDB00A889F2 /* Models in Frameworks */,
|
9F398AAB2935FFDB00A889F2 /* Models in Frameworks */,
|
||||||
9F5E581929545BE700A53960 /* Env in Frameworks */,
|
9F5E581929545BE700A53960 /* Env in Frameworks */,
|
||||||
9F2A540A29699705009B2D7C /* ReceiptParser in Frameworks */,
|
9F2A540A29699705009B2D7C /* ReceiptParser in Frameworks */,
|
||||||
|
9FF614472B2EDCE500F7B0E6 /* GiphyUISDK in Frameworks */,
|
||||||
9F35DB44294F9A7D00B3281A /* Status in Frameworks */,
|
9F35DB44294F9A7D00B3281A /* Status in Frameworks */,
|
||||||
DA0B24FB2A6876D50045BDD7 /* SFSafeSymbols in Frameworks */,
|
DA0B24FB2A6876D50045BDD7 /* SFSafeSymbols in Frameworks */,
|
||||||
9F295540292B6C3400E0E81B /* Timeline in Frameworks */,
|
9F295540292B6C3400E0E81B /* Timeline in Frameworks */,
|
||||||
|
@ -493,7 +494,6 @@
|
||||||
9FBFE64C292A72BD00C250E9 /* Frameworks */ = {
|
9FBFE64C292A72BD00C250E9 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
9FE034692ADD597100529EA8 /* MediaUI */,
|
|
||||||
9F2A540D2969A0B0009B2D7C /* StoreKit.framework */,
|
9F2A540D2969A0B0009B2D7C /* StoreKit.framework */,
|
||||||
9F2A5404296995FB009B2D7C /* QuickLookUI.framework */,
|
9F2A5404296995FB009B2D7C /* QuickLookUI.framework */,
|
||||||
9F7335EE29674F7100AFF0BA /* QuickLook.framework */,
|
9F7335EE29674F7100AFF0BA /* QuickLook.framework */,
|
||||||
|
@ -597,6 +597,7 @@
|
||||||
9FAD85A1297456A400496AB1 /* Env */,
|
9FAD85A1297456A400496AB1 /* Env */,
|
||||||
9FAD85A3297456A800496AB1 /* DesignSystem */,
|
9FAD85A3297456A800496AB1 /* DesignSystem */,
|
||||||
065FA209298675BA00012EA0 /* LRUCache */,
|
065FA209298675BA00012EA0 /* LRUCache */,
|
||||||
|
9FF614482B2EDCEC00F7B0E6 /* GiphyUISDK */,
|
||||||
);
|
);
|
||||||
productName = IceCubesShareExtension;
|
productName = IceCubesShareExtension;
|
||||||
productReference = 9FAD858829743F7400496AB1 /* IceCubesShareExtension.appex */;
|
productReference = 9FAD858829743F7400496AB1 /* IceCubesShareExtension.appex */;
|
||||||
|
@ -636,7 +637,7 @@
|
||||||
9FE3DB56296FEFCA00628CB0 /* AppAccount */,
|
9FE3DB56296FEFCA00628CB0 /* AppAccount */,
|
||||||
065FA1FD29866CD600012EA0 /* LRUCache */,
|
065FA1FD29866CD600012EA0 /* LRUCache */,
|
||||||
DA0B24FA2A6876D50045BDD7 /* SFSafeSymbols */,
|
DA0B24FA2A6876D50045BDD7 /* SFSafeSymbols */,
|
||||||
9FE0346B2ADD5C2100529EA8 /* MediaUI */,
|
9FF614462B2EDCE500F7B0E6 /* GiphyUISDK */,
|
||||||
);
|
);
|
||||||
productName = IceCubesApp;
|
productName = IceCubesApp;
|
||||||
productReference = 9FBFE639292A715500C250E9 /* Ice Cubes.app */;
|
productReference = 9FBFE639292A715500C250E9 /* Ice Cubes.app */;
|
||||||
|
@ -719,6 +720,7 @@
|
||||||
9F2A540829699705009B2D7C /* XCRemoteSwiftPackageReference "purchases-ios" */,
|
9F2A540829699705009B2D7C /* XCRemoteSwiftPackageReference "purchases-ios" */,
|
||||||
065FA1FC29866CD600012EA0 /* XCRemoteSwiftPackageReference "LRUCache" */,
|
065FA1FC29866CD600012EA0 /* XCRemoteSwiftPackageReference "LRUCache" */,
|
||||||
DA0B24F92A6876D40045BDD7 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */,
|
DA0B24F92A6876D40045BDD7 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */,
|
||||||
|
9FF614452B2EDCE500F7B0E6 /* XCRemoteSwiftPackageReference "giphy-ios-sdk" */,
|
||||||
);
|
);
|
||||||
productRefGroup = 9FBFE63A292A715500C250E9 /* Products */;
|
productRefGroup = 9FBFE63A292A715500C250E9 /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
|
@ -1410,6 +1412,14 @@
|
||||||
kind = branch;
|
kind = branch;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
9FF614452B2EDCE500F7B0E6 /* XCRemoteSwiftPackageReference "giphy-ios-sdk" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/Giphy/giphy-ios-sdk";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 2.2.7;
|
||||||
|
};
|
||||||
|
};
|
||||||
DA0B24F92A6876D40045BDD7 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */ = {
|
DA0B24F92A6876D40045BDD7 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/SFSafeSymbols/SFSafeSymbols";
|
repositoryURL = "https://github.com/SFSafeSymbols/SFSafeSymbols";
|
||||||
|
@ -1532,14 +1542,20 @@
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = Lists;
|
productName = Lists;
|
||||||
};
|
};
|
||||||
9FE0346B2ADD5C2100529EA8 /* MediaUI */ = {
|
|
||||||
isa = XCSwiftPackageProductDependency;
|
|
||||||
productName = MediaUI;
|
|
||||||
};
|
|
||||||
9FE3DB56296FEFCA00628CB0 /* AppAccount */ = {
|
9FE3DB56296FEFCA00628CB0 /* AppAccount */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = AppAccount;
|
productName = AppAccount;
|
||||||
};
|
};
|
||||||
|
9FF614462B2EDCE500F7B0E6 /* GiphyUISDK */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 9FF614452B2EDCE500F7B0E6 /* XCRemoteSwiftPackageReference "giphy-ios-sdk" */;
|
||||||
|
productName = GiphyUISDK;
|
||||||
|
};
|
||||||
|
9FF614482B2EDCEC00F7B0E6 /* GiphyUISDK */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 9FF614452B2EDCE500F7B0E6 /* XCRemoteSwiftPackageReference "giphy-ios-sdk" */;
|
||||||
|
productName = GiphyUISDK;
|
||||||
|
};
|
||||||
9FFF677B299B7B2C00FE700A /* Notifications */ = {
|
9FFF677B299B7B2C00FE700A /* Notifications */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = Notifications;
|
productName = Notifications;
|
||||||
|
|
|
@ -18,6 +18,15 @@
|
||||||
"version" : "3.2.0"
|
"version" : "3.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"identity" : "giphy-ios-sdk",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/Giphy/giphy-ios-sdk",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "95c32b862185e76107841b49bfff8ff7230f3b68",
|
||||||
|
"version" : "2.2.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"identity" : "keychain-swift",
|
"identity" : "keychain-swift",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
|
@ -27,6 +36,15 @@
|
||||||
"revision" : "f38cb0ada97847ac5068b915b8d2793b35435668"
|
"revision" : "f38cb0ada97847ac5068b915b8d2793b35435668"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"identity" : "libwebp-xcode",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/SDWebImage/libwebp-Xcode",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "b2b1d20a90b14d11f6ef4241da6b81c1d3f171e4",
|
||||||
|
"version" : "1.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"identity" : "lrucache",
|
"identity" : "lrucache",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
|
|
|
@ -2,7 +2,7 @@ import Foundation
|
||||||
|
|
||||||
public enum Media: Endpoint {
|
public enum Media: Endpoint {
|
||||||
case medias
|
case medias
|
||||||
case media(id: String, json: MediaDescriptionData)
|
case media(id: String, json: MediaDescriptionData?)
|
||||||
|
|
||||||
public func path() -> String {
|
public func path() -> String {
|
||||||
switch self {
|
switch self {
|
||||||
|
@ -20,9 +20,12 @@ public enum Media: Endpoint {
|
||||||
public var jsonValue: Encodable? {
|
public var jsonValue: Encodable? {
|
||||||
switch self {
|
switch self {
|
||||||
case let .media(_, json):
|
case let .media(_, json):
|
||||||
json
|
if let json {
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
return nil
|
||||||
default:
|
default:
|
||||||
nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
import SwiftUI
|
||||||
|
import GiphyUISDK
|
||||||
|
import UIKit
|
||||||
|
import DesignSystem
|
||||||
|
|
||||||
|
struct GifPickerView: UIViewControllerRepresentable {
|
||||||
|
@Environment(Theme.self) private var theme
|
||||||
|
|
||||||
|
var completion: ((String) -> Void)
|
||||||
|
var onShouldDismissGifPicker: () -> Void
|
||||||
|
|
||||||
|
func makeUIViewController(context: Context) -> GiphyViewController {
|
||||||
|
Giphy.configure(apiKey: "MIylJkNX57vcUNZxmSODKU9dQKBgXCkV")
|
||||||
|
|
||||||
|
let controller = GiphyViewController()
|
||||||
|
controller.swiftUIEnabled = true
|
||||||
|
controller.mediaTypeConfig = [.gifs, .stickers, .recents]
|
||||||
|
controller.delegate = context.coordinator
|
||||||
|
controller.navigationController?.isNavigationBarHidden = true
|
||||||
|
controller.navigationController?.setNavigationBarHidden(true, animated: false)
|
||||||
|
|
||||||
|
GiphyViewController.trayHeightMultiplier = 1.0
|
||||||
|
|
||||||
|
controller.theme = GPHTheme(type: theme.selectedScheme == .dark ? .darkBlur : .lightBlur)
|
||||||
|
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { }
|
||||||
|
|
||||||
|
func makeCoordinator() -> Coordinator {
|
||||||
|
GifPickerView.Coordinator(parent: self)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Coordinator: NSObject, GiphyDelegate {
|
||||||
|
var parent: GifPickerView
|
||||||
|
|
||||||
|
init(parent: GifPickerView) {
|
||||||
|
self.parent = parent
|
||||||
|
}
|
||||||
|
|
||||||
|
func didDismiss(controller: GiphyViewController?) {
|
||||||
|
self.parent.onShouldDismissGifPicker()
|
||||||
|
}
|
||||||
|
|
||||||
|
func didSelectMedia(giphyViewController: GiphyViewController, media: GPHMedia) {
|
||||||
|
let url = media.url(rendition: .fixedWidth, fileType: .gif)
|
||||||
|
parent.completion(url ?? "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import Models
|
||||||
import NukeUI
|
import NukeUI
|
||||||
import PhotosUI
|
import PhotosUI
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import GiphyUISDK
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
struct StatusEditorAccessoryView: View {
|
struct StatusEditorAccessoryView: View {
|
||||||
|
@ -24,6 +25,7 @@ struct StatusEditorAccessoryView: View {
|
||||||
@State private var isPhotosPickerPresented: Bool = false
|
@State private var isPhotosPickerPresented: Bool = false
|
||||||
@State private var isFileImporterPresented: Bool = false
|
@State private var isFileImporterPresented: Bool = false
|
||||||
@State private var isCameraPickerPresented: Bool = false
|
@State private var isCameraPickerPresented: Bool = false
|
||||||
|
@State private var isGIFPickerPresented: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@Bindable var viewModel = focusedSEVM
|
@Bindable var viewModel = focusedSEVM
|
||||||
|
@ -51,6 +53,12 @@ struct StatusEditorAccessoryView: View {
|
||||||
} label: {
|
} label: {
|
||||||
Label("status.editor.browse-file", systemImage: "folder")
|
Label("status.editor.browse-file", systemImage: "folder")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
isGIFPickerPresented = true
|
||||||
|
} label: {
|
||||||
|
Label("GIPHY", systemImage: "party.popper")
|
||||||
|
}
|
||||||
} label: {
|
} label: {
|
||||||
if viewModel.isMediasLoading {
|
if viewModel.isMediasLoading {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
|
@ -82,6 +90,18 @@ struct StatusEditorAccessoryView: View {
|
||||||
}))
|
}))
|
||||||
.background(.black)
|
.background(.black)
|
||||||
})
|
})
|
||||||
|
.sheet(isPresented: $isGIFPickerPresented, content: {
|
||||||
|
GifPickerView { url in
|
||||||
|
GPHCache.shared.downloadAssetData(url) { data, error in
|
||||||
|
guard let data else { return }
|
||||||
|
viewModel.processGIFData(data: data)
|
||||||
|
}
|
||||||
|
isGIFPickerPresented = false
|
||||||
|
} onShouldDismissGifPicker: {
|
||||||
|
isGIFPickerPresented = false
|
||||||
|
}
|
||||||
|
.presentationDetents([.medium, .large])
|
||||||
|
})
|
||||||
.accessibilityLabel("accessibility.editor.button.attach-photo")
|
.accessibilityLabel("accessibility.editor.button.attach-photo")
|
||||||
.disabled(viewModel.showPoll)
|
.disabled(viewModel.showPoll)
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import Env
|
||||||
import Models
|
import Models
|
||||||
import NukeUI
|
import NukeUI
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import MediaUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
struct StatusEditorMediaView: View {
|
struct StatusEditorMediaView: View {
|
||||||
|
@ -93,13 +94,13 @@ struct StatusEditorMediaView: View {
|
||||||
RoundedRectangle(cornerRadius: 8).fill(.clear)
|
RoundedRectangle(cornerRadius: 8).fill(.clear)
|
||||||
.overlay {
|
.overlay {
|
||||||
if let attachement = container.mediaAttachment {
|
if let attachement = container.mediaAttachment {
|
||||||
makeLazyImage(mediaAttachement: attachement)
|
makeRemoteMediaView(mediaAttachement: attachement)
|
||||||
} else if container.image != nil {
|
} else if container.image != nil {
|
||||||
makeLocalImage(container: container)
|
makeLocalImageView(container: container)
|
||||||
} else if container.movieTransferable != nil || container.gifTransferable != nil {
|
|
||||||
makeVideoAttachement(container: container)
|
|
||||||
} else if let error = container.error as? ServerError {
|
} else if let error = container.error as? ServerError {
|
||||||
makeErrorView(error: error)
|
makeErrorView(error: error)
|
||||||
|
} else {
|
||||||
|
placeholderView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,17 +117,7 @@ struct StatusEditorMediaView: View {
|
||||||
.matchedGeometryEffect(id: index, in: mediaSpace, anchor: .leading)
|
.matchedGeometryEffect(id: index, in: mediaSpace, anchor: .leading)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func makeVideoAttachement(container: StatusEditorMediaContainer) -> some View {
|
private func makeLocalImageView(container: StatusEditorMediaContainer) -> some View {
|
||||||
ZStack(alignment: .center) {
|
|
||||||
placeholderView
|
|
||||||
if container.mediaAttachment == nil {
|
|
||||||
ProgressView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.cornerRadius(8)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func makeLocalImage(container: StatusEditorMediaContainer) -> some View {
|
|
||||||
ZStack(alignment: .center) {
|
ZStack(alignment: .center) {
|
||||||
Image(uiImage: container.image!)
|
Image(uiImage: container.image!)
|
||||||
.resizable()
|
.resizable()
|
||||||
|
@ -141,30 +132,29 @@ struct StatusEditorMediaView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func makeLazyImage(mediaAttachement: MediaAttachment) -> some View {
|
private func makeRemoteMediaView(mediaAttachement: MediaAttachment) -> some View {
|
||||||
ZStack(alignment: .center) {
|
ZStack(alignment: .center) {
|
||||||
if let url = mediaAttachement.url ?? mediaAttachement.previewUrl {
|
switch mediaAttachement.supportedType {
|
||||||
LazyImage(url: url) { state in
|
case .gifv, .video, .audio:
|
||||||
if let image = state.image {
|
if let url = mediaAttachement.url {
|
||||||
image
|
MediaUIAttachmentVideoView(viewModel: .init(url: url, forceAutoPlay: true))
|
||||||
.resizable()
|
} else {
|
||||||
.scaledToFill()
|
placeholderView
|
||||||
} else {
|
}
|
||||||
placeholderView
|
case .image:
|
||||||
|
if let url = mediaAttachement.url ?? mediaAttachement.previewUrl {
|
||||||
|
LazyImage(url: url) { state in
|
||||||
|
if let image = state.image {
|
||||||
|
image
|
||||||
|
.resizable()
|
||||||
|
.scaledToFill()
|
||||||
|
} else {
|
||||||
|
placeholderView
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
case .none:
|
||||||
placeholderView
|
EmptyView()
|
||||||
}
|
|
||||||
if mediaAttachement.url == nil {
|
|
||||||
ProgressView()
|
|
||||||
}
|
|
||||||
if mediaAttachement.url != nil,
|
|
||||||
mediaAttachement.supportedType == .video || mediaAttachement.supportedType == .gifv
|
|
||||||
{
|
|
||||||
Image(systemName: "play.fill")
|
|
||||||
.font(.headline)
|
|
||||||
.tint(.white)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cornerRadius(8)
|
.cornerRadius(8)
|
||||||
|
@ -242,11 +232,18 @@ struct StatusEditorMediaView: View {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
viewModel.mediaContainers.removeAll {
|
||||||
|
$0.id == container.id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var placeholderView: some View {
|
private var placeholderView: some View {
|
||||||
Rectangle()
|
ZStack(alignment: .center) {
|
||||||
.foregroundColor(theme.secondaryBackgroundColor)
|
Rectangle()
|
||||||
.accessibilityHidden(true)
|
.foregroundColor(theme.secondaryBackgroundColor)
|
||||||
|
.accessibilityHidden(true)
|
||||||
|
ProgressView()
|
||||||
|
}
|
||||||
|
.cornerRadius(8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ import SwiftUI
|
||||||
|
|
||||||
var isMediasLoading: Bool = false
|
var isMediasLoading: Bool = false
|
||||||
|
|
||||||
private(set) var mediaContainers: [StatusEditorMediaContainer] = []
|
var mediaContainers: [StatusEditorMediaContainer] = []
|
||||||
var replyToStatus: Status?
|
var replyToStatus: Status?
|
||||||
var embeddedStatus: Status?
|
var embeddedStatus: Status?
|
||||||
|
|
||||||
|
@ -385,6 +385,19 @@ import SwiftUI
|
||||||
processItemsProvider(items: items)
|
processItemsProvider(items: items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func processGIFData(data: Data) {
|
||||||
|
isMediasLoading = true
|
||||||
|
let url = URL.temporaryDirectory.appending(path: "\(UUID().uuidString).gif")
|
||||||
|
try? data.write(to: url)
|
||||||
|
let container = StatusEditorMediaContainer(id: UUID().uuidString,
|
||||||
|
image: nil,
|
||||||
|
movieTransferable: nil,
|
||||||
|
gifTransferable: .init(url: url),
|
||||||
|
mediaAttachment: nil,
|
||||||
|
error: nil)
|
||||||
|
prepareToPost(for: container)
|
||||||
|
}
|
||||||
|
|
||||||
func processCameraPhoto(image: UIImage) {
|
func processCameraPhoto(image: UIImage) {
|
||||||
let container = StatusEditorMediaContainer(
|
let container = StatusEditorMediaContainer(
|
||||||
id: UUID().uuidString,
|
id: UUID().uuidString,
|
||||||
|
@ -725,7 +738,7 @@ import SwiftUI
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
let newAttachement: MediaAttachment = try await client.get(endpoint: Media.media(id: mediaAttachement.id,
|
let newAttachement: MediaAttachment = try await client.get(endpoint: Media.media(id: mediaAttachement.id,
|
||||||
json: .init(description: nil)))
|
json: nil))
|
||||||
if newAttachement.url != nil {
|
if newAttachement.url != nil {
|
||||||
let oldContainer = mediaContainers[index]
|
let oldContainer = mediaContainers[index]
|
||||||
mediaContainers[index] = StatusEditorMediaContainer(
|
mediaContainers[index] = StatusEditorMediaContainer(
|
||||||
|
@ -736,7 +749,9 @@ import SwiftUI
|
||||||
mediaAttachment: newAttachement,
|
mediaAttachment: newAttachement,
|
||||||
error: nil)
|
error: nil)
|
||||||
}
|
}
|
||||||
} catch {}
|
} catch {
|
||||||
|
print(error.localizedDescription)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
try? await Task.sleep(for: .seconds(5))
|
try? await Task.sleep(for: .seconds(5))
|
||||||
} while !Task.isCancelled
|
} while !Task.isCancelled
|
||||||
|
|
Loading…
Reference in a new issue