Skip to content

Commit 9a9e8a1

Browse files
authored
Add FileCDN class enable generating signedURL's in File Attachments (#620)
1 parent e5b0be1 commit 9a9e8a1

File tree

4 files changed

+64
-6
lines changed

4 files changed

+64
-6
lines changed

Sources/StreamChatSwiftUI/ChatChannel/MessageList/FileAttachmentPreview.swift

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,15 @@ public struct FileAttachmentPreview: View {
1010

1111
@Injected(\.fonts) private var fonts
1212
@Injected(\.images) private var images
13+
@Injected(\.utils) private var utils
14+
15+
private var fileCDN: FileCDN {
16+
utils.fileCDN
17+
}
1318

1419
var url: URL
1520

21+
@State var adjustedUrl: URL?
1622
@State private var isLoading = false
1723
@State private var title: String?
1824
@State private var error: Error?
@@ -25,18 +31,31 @@ public struct FileAttachmentPreview: View {
2531
.font(fonts.body)
2632
.padding()
2733
} else {
28-
WebView(
29-
url: url,
30-
isLoading: $isLoading,
31-
title: $title,
32-
error: $error
33-
)
34+
35+
if let adjustedUrl = adjustedUrl {
36+
WebView(
37+
url: adjustedUrl,
38+
isLoading: $isLoading,
39+
title: $title,
40+
error: $error
41+
)
42+
}
3443

3544
if isLoading {
3645
ProgressView()
3746
}
3847
}
3948
}
49+
.onAppear {
50+
fileCDN.adjustedURL(for: url) { result in
51+
switch result {
52+
case let .success(url):
53+
self.adjustedUrl = url
54+
case let .failure(error):
55+
self.error = error
56+
}
57+
}
58+
}
4059
.navigationBarTitleDisplayMode(.inline)
4160
.toolbar {
4261
ToolbarItem(placement: .principal) {

Sources/StreamChatSwiftUI/Utils.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public class Utils {
1414
public var imageCDN: ImageCDN
1515
public var imageProcessor: ImageProcessor
1616
public var imageMerger: ImageMerging
17+
public var fileCDN: FileCDN
1718
public var channelNamer: ChatChannelNamer
1819
public var chatUserNamer: ChatUserNamer
1920
public var channelAvatarsMerger: ChannelAvatarsMerging
@@ -69,6 +70,7 @@ public class Utils {
6970
imageCDN: ImageCDN = StreamImageCDN(),
7071
imageProcessor: ImageProcessor = NukeImageProcessor(),
7172
imageMerger: ImageMerging = DefaultImageMerger(),
73+
fileCDN: FileCDN = DefaultFileCDN(),
7274
channelAvatarsMerger: ChannelAvatarsMerging = ChannelAvatarsMerger(),
7375
messageTypeResolver: MessageTypeResolving = MessageTypeResolver(),
7476
messageActionResolver: MessageActionsResolving = MessageActionsResolver(),
@@ -92,6 +94,7 @@ public class Utils {
9294
self.imageCDN = imageCDN
9395
self.imageProcessor = imageProcessor
9496
self.imageMerger = imageMerger
97+
self.fileCDN = fileCDN
9598
self.channelNamer = channelNamer
9699
self.chatUserNamer = chatUserNamer
97100
self.channelAvatarsMerger = channelAvatarsMerger
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// Copyright © 2024 Stream.io Inc. All rights reserved.
3+
//
4+
5+
import Foundation
6+
import StreamChat
7+
8+
/// A protocol the video preview uploader implementation must conform to.
9+
public protocol FileCDN: AnyObject {
10+
/// Prepare and return an adjusted or signed `URL` for the given file `URL`
11+
/// This function can be used to intercept an unsigned URL and return a valid signed URL
12+
/// - Parameters:
13+
/// - url: A file URL.
14+
/// - completion: A completion that is called when an adjusted URL is ready to be provided.
15+
func adjustedURL(
16+
for url: URL,
17+
completion: @escaping ((Result<URL, Error>) -> Void)
18+
)
19+
}
20+
21+
/// The `DefaultFileCDN` implemenation used by default.
22+
public final class DefaultFileCDN: FileCDN {
23+
24+
// Initializer required for subclasses
25+
public init() {
26+
// Public init.
27+
}
28+
29+
public func adjustedURL(for url: URL, completion: @escaping ((Result<URL, any Error>) -> Void)) {
30+
completion(.success(url))
31+
}
32+
}

StreamChatSwiftUI.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@
490490
91B79FD9284E7E9C005B6E4F /* ChatUserNamer_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91B79FD8284E7E9C005B6E4F /* ChatUserNamer_Tests.swift */; };
491491
91CC203A283C3E7F0049A146 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91CC2039283C3E7F0049A146 /* URLExtensions.swift */; };
492492
91CC203C283C4C250049A146 /* URLUtils_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91CC203B283C4C250049A146 /* URLUtils_Tests.swift */; };
493+
9D9A54512CB89EAA00A76D9E /* FileCDN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9A54502CB89EAA00A76D9E /* FileCDN.swift */; };
493494
A35D803B283E89F50084FE25 /* StreamChatSwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8465FBB52746873A00AF091E /* StreamChatSwiftUI.framework */; };
494495
A35D803C283E89F50084FE25 /* StreamChatSwiftUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8465FBB52746873A00AF091E /* StreamChatSwiftUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
495496
A3600B2A283E9E1900E1C930 /* UserRobot.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3600B24283E9E1900E1C930 /* UserRobot.swift */; };
@@ -1060,6 +1061,7 @@
10601061
91B79FD8284E7E9C005B6E4F /* ChatUserNamer_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatUserNamer_Tests.swift; sourceTree = "<group>"; };
10611062
91CC2039283C3E7F0049A146 /* URLExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLExtensions.swift; sourceTree = "<group>"; };
10621063
91CC203B283C4C250049A146 /* URLUtils_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLUtils_Tests.swift; sourceTree = "<group>"; };
1064+
9D9A54502CB89EAA00A76D9E /* FileCDN.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileCDN.swift; sourceTree = "<group>"; };
10631065
A3600B24283E9E1900E1C930 /* UserRobot.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserRobot.swift; sourceTree = "<group>"; };
10641066
A3600B29283E9E1900E1C930 /* UserRobot+Asserts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UserRobot+Asserts.swift"; sourceTree = "<group>"; };
10651067
A3600B31283E9E4700E1C930 /* MessageList_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageList_Tests.swift; sourceTree = "<group>"; };
@@ -1838,6 +1840,7 @@
18381840
91B79FD6284E21E0005B6E4F /* ChatUserNamer.swift */,
18391841
8465FD3A2746A95600AF091E /* DateFormatter+Extensions.swift */,
18401842
8465FD402746A95600AF091E /* DateUtils.swift */,
1843+
9D9A54502CB89EAA00A76D9E /* FileCDN.swift */,
18411844
8465FD3D2746A95600AF091E /* ImageCDN.swift */,
18421845
8465FD482746A95600AF091E /* ImageMerger.swift */,
18431846
8465FD422746A95600AF091E /* InputTextView.swift */,
@@ -2708,6 +2711,7 @@
27082711
8482094E2ACFFCD900EF3261 /* Throttler.swift in Sources */,
27092712
84EADEBD2B28C2EC0046B50C /* RecordingState.swift in Sources */,
27102713
4F7DD9A02BFC7C6100599AA6 /* ChatClient+Extensions.swift in Sources */,
2714+
9D9A54512CB89EAA00A76D9E /* FileCDN.swift in Sources */,
27112715
82D64C1B2AD7E5B700C5C79E /* ImageCaching.swift in Sources */,
27122716
82D64C062AD7E5B700C5C79E /* Graphics.swift in Sources */,
27132717
8465FDCB2746A95700AF091E /* ChatChannelListView.swift in Sources */,

0 commit comments

Comments
 (0)