diff --git a/CHANGELOG.md b/CHANGELOG.md index 0aac41f..2a23e61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ +# [2.2.6](https://github.com/GetStream/stream-swift/releases/tag/2.2.3) - 16 Nov 2022 + +### ✅ Added +- Add `ActivityReactionsOptions` in `Client.get`. Enable ability to get activities with reaction data. + # [2.2.2](https://github.com/GetStream/stream-swift/releases/tag/2.2.2) - 24 Feb 2020 ### 🐞 Fixed diff --git a/Sources/Core/Activity/ActivityEndpoint.swift b/Sources/Core/Activity/ActivityEndpoint.swift index 3807949..5ec8741 100644 --- a/Sources/Core/Activity/ActivityEndpoint.swift +++ b/Sources/Core/Activity/ActivityEndpoint.swift @@ -16,7 +16,7 @@ import Moya public typealias Properties = [String: Encodable] enum ActivityEndpoint { - case getByIds(_ enrich: Bool, _ activitiesIds: [String]) + case getByIds(_ enrich: Bool, _ activitiesIds: [String], _ reactionsOptions: ActivityReactionsOptions) case get(_ enrich: Bool, foreignIds: [String], times: [Date]) case update(_ activities: [T]) case updateActivityById(setProperties: Properties?, unsetPropertiesNames: [String]?, activityId: String) @@ -27,7 +27,7 @@ extension ActivityEndpoint: StreamTargetType { var path: String { switch self { - case .getByIds(let enrich, _), .get(let enrich, _, _): + case .getByIds(let enrich, _, _), .get(let enrich, _, _): return "\(enrich ? "enrich/" : "")activities/" case .update: return "activities/" @@ -48,9 +48,25 @@ extension ActivityEndpoint: StreamTargetType { var task: Task { switch self { - case .getByIds(_, let ids): + case .getByIds(_, let ids, let reactionsOptions): let ids = ids.map { $0 }.joined(separator: ",") - return .requestParameters(parameters: ["ids" : ids], encoding: URLEncoding.default) + var parameters: [String: Any] = [ + ActivityEndpointParameters.ids.rawValue: ids + ] + + if reactionsOptions.contains(.own) { + parameters[ActivityEndpointParameters.withOwnReactions.rawValue] = true + } + + if reactionsOptions.contains(.latest) { + parameters[ActivityEndpointParameters.withRecentReactions.rawValue] = true + } + + if reactionsOptions.contains(.counts) { + parameters[ActivityEndpointParameters.withReactionCounts.rawValue] = true + } + + return .requestParameters(parameters: parameters, encoding: URLEncoding.default) case let .get(_, foreignIds: foreignIds, times: times): return .requestParameters(parameters: idParameters(with: foreignIds, times: times), encoding: URLEncoding.default) @@ -72,7 +88,7 @@ extension ActivityEndpoint: StreamTargetType { var sampleJSON: String { switch self { - case let .getByIds(enrich, activitiesIds): + case let .getByIds(enrich, activitiesIds, _): let actorJSON = enrich ? "{\"id\":\"eric\",\"data\":{\"name\":\"Eric\"},\"updated_at\":\"2019-04-15T17:55:53.425\",\"created_at\":\"2019-04-15T17:55:53.425\"}" : "\"eric\"" @@ -187,3 +203,34 @@ extension ActivityEndpoint { return ["foreign_ids": foreignIds, "timestamps": times] } } + +enum ActivityEndpointParameters: String { + case ids + case withRecentReactions + case withOwnReactions + case withReactionCounts +} + +// MARK: - Reactions Option + +/// A activity reaction options to include reaction for activities. +/// - Available options: +/// - `includeOwn`: include reactions added by current user to all activities. +/// - `includeRecent`: include recent reactions to activities. +/// - `includeCounts`: include reaction counts to activities. +public struct ActivityReactionsOptions: OptionSet { + public let rawValue: Int + + public init(rawValue: Int) { + self.rawValue = rawValue + } + + /// Include reactions added by current user to all activities. + public static let own = ActivityReactionsOptions(rawValue: 1 << 0) + /// Include recent reactions to activities. + public static let latest = ActivityReactionsOptions(rawValue: 1 << 1) + /// Include reaction counts to activities. + public static let counts = ActivityReactionsOptions(rawValue: 1 << 2) + /// Include all reactions options to activities. + public static let all: ActivityReactionsOptions = [.own, .latest, .counts] +} diff --git a/Sources/Core/Activity/Client+Activity.swift b/Sources/Core/Activity/Client+Activity.swift index f1a161b..16f9a36 100644 --- a/Sources/Core/Activity/Client+Activity.swift +++ b/Sources/Core/Activity/Client+Activity.swift @@ -18,14 +18,20 @@ public typealias ActivitiesCompletion = (_ result: Result(enrich: Bool = true, typeOf type: T.Type, activityIds: [String], + includeReactions reactionsOptions: ActivityReactionsOptions = [], completion: @escaping ActivitiesCompletion) -> Cancellable { - return request(endpoint: ActivityEndpoint.getByIds(enrich, activityIds)) { [weak self] result in + return request(endpoint: ActivityEndpoint.getByIds(enrich, activityIds, reactionsOptions)) { [weak self] result in if let self = self { result.parse(self.callbackQueue, completion) } diff --git a/Tests/Core/ClientTests.swift b/Tests/Core/ClientTests.swift index 88f4f3a..2b8da30 100644 --- a/Tests/Core/ClientTests.swift +++ b/Tests/Core/ClientTests.swift @@ -66,10 +66,45 @@ final class ClientTests: TestCase { } func testActivityBaseURL() { - let endpoint = ActivityEndpoint.getByIds(true, [.test1]) + let endpoint = ActivityEndpoint.getByIds(true, [.test1], []) XCTAssertEqual(endpoint.baseURL, BaseURL.placeholderURL) } + func testActivityWithReactionOption() { + var endpoint = ActivityEndpoint.getByIds(true, [.test1], [.all]) + switch endpoint.task { + case .requestParameters(let parameter, _): + XCTAssertEqual(parameter[ActivityEndpointParameters.ids.rawValue] as? String, .test1) + XCTAssertEqual(parameter[ActivityEndpointParameters.withRecentReactions.rawValue] as? Bool, true) + XCTAssertEqual(parameter[ActivityEndpointParameters.withOwnReactions.rawValue] as? Bool, true) + XCTAssertEqual(parameter[ActivityEndpointParameters.withReactionCounts.rawValue] as? Bool, true) + default: + XCTFail("Should be request parameter") + } + + endpoint = ActivityEndpoint.getByIds(true, [.test1], [.counts]) + switch endpoint.task { + case .requestParameters(let parameter, _): + XCTAssertEqual(parameter[ActivityEndpointParameters.ids.rawValue] as? String, .test1) + XCTAssertNil(parameter[ActivityEndpointParameters.withRecentReactions.rawValue]) + XCTAssertNil(parameter[ActivityEndpointParameters.withOwnReactions.rawValue] ) + XCTAssertEqual(parameter[ActivityEndpointParameters.withReactionCounts.rawValue] as? Bool, true) + default: + XCTFail("Should be request parameter") + } + + endpoint = ActivityEndpoint.getByIds(true, [.test1], [.counts, .latest]) + switch endpoint.task { + case .requestParameters(let parameter, _): + XCTAssertEqual(parameter[ActivityEndpointParameters.ids.rawValue] as? String, .test1) + XCTAssertEqual(parameter[ActivityEndpointParameters.withRecentReactions.rawValue] as? Bool, true) + XCTAssertNil(parameter[ActivityEndpointParameters.withOwnReactions.rawValue]) + XCTAssertEqual(parameter[ActivityEndpointParameters.withReactionCounts.rawValue] as? Bool, true) + default: + XCTFail("Should be request parameter") + } + } + func testClientActivityGetByIds() { expect("get an enriched activity by id") { test in Client.shared.get(enrich: true, typeOf: Activity.self, activityIds: [.test1, .test2]) { result in