Skip to content

Commit

Permalink
Update lexicon models, methods to latest changes
Browse files Browse the repository at this point in the history
  • Loading branch information
MasterJ93 committed Jun 12, 2024
1 parent 89bdb77 commit 4da1ab5
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,12 @@ extension AppBskyLexicon.Actor {
/// A URI which indicates the user is being followed by the requesting account.
public let followedByURI: String?

/// An array of mutual followers. Optional.
///
/// - Note: According to the AT Protocol specifications: "The subject's followers whom you
/// also follow."
public let knownFollowers: KnownFollowers

enum CodingKeys: String, CodingKey {
case isMuted = "muted"
case mutedByArray = "mutedByList"
Expand All @@ -387,6 +393,33 @@ extension AppBskyLexicon.Actor {
case blockingByArray = "blockingByList"
case followingURI = "following"
case followedByURI = "followedBy"
case knownFollowers
}
}

/// A definition model for mutual followers.
///
/// - Note: According to the AT Protocol specifications: "The subject's followers whom you
/// also follow."
///
/// - SeeAlso: This is based on the [`app.bsky.actor.defs`][github] lexicon.
///
/// [github]: https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/actor/defs.json
public struct KnownFollowers: Codable {

/// The number of mutual followers related to the parent structure's specifications.
public let count: Int

/// An array of user accounts that follow the viewer.
public let followers: [ProfileViewBasicDefinition]

public func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)

try container.encode(self.count, forKey: .count)

// Truncate `displayName` to 5 items before encoding
try truncatedEncode(self.followers, withContainer: &container, forKey: .followers, upToLength: 5)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// AppBskyGraphGetKnownFollowers.swift
//
//
// Created by Christopher Jr Riley on 2024-06-12.
//

import Foundation

extension AppBskyLexicon.Graph {

/// An output model for identifying mutual followers.
///
/// - Note: According to the AT Protocol specifications: "Enumerates accounts which follow a
/// specified account (actor) and are followed by the viewer."
///
/// - SeeAlso: This is based on the [`app.bsky.graph.getKnownFollowers`][github] lexicon.
///
/// [github]: https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/graph/getKnownFollowers.json
public struct GetKnownFollowersOutput: Codable {

/// The user account that mutually follows ``followers``.
public let subject: AppBskyLexicon.Actor.ProfileViewDefinition

/// The number of the last successful message decoded. Optional.
public let cursor: String?

/// An array of mutual followers.
public let followers: [AppBskyLexicon.Actor.ProfileViewDefinition]
}
}
77 changes: 77 additions & 0 deletions Sources/ATProtoKit/Networking/PlatformAPI/GetKnownFollowers.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// GetKnownFollowers.swift
//
//
// Created by Christopher Jr Riley on 2024-06-12.
//

import Foundation

extension ATProtoKit {

/// Identifies mutual followers.
///
/// - Note: According to the AT Protocol specifications: "Enumerates accounts which follow a
/// specified account (actor) and are followed by the viewer."
///
/// - SeeAlso: This is based on the [`app.bsky.graph.getKnownFollowers`][github] lexicon.
///
/// [github]: https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/graph/getKnownFollowers.json
///
/// - Parameters:
/// - actor: The user account to check for mutual followers.
/// - limit: The number of items the list will hold. Optional. Defaults to `50`.
/// - cursor: The mark used to indicate the starting point for the next set of
/// result. Optional.
/// - Returns: A `Result`, containing either a
/// ``AppBskyLexicon/Graph/GetKnownFollowersOutput``
/// if successful, or an `Error` if not.
public func getKnownFollowers(
from actor: String,
limit: Int? = 50,
cursor: String? = nil
) async throws -> Result<AppBskyLexicon.Graph.GetKnownFollowersOutput, Error> {
guard session != nil,
let accessToken = session?.accessToken else {
return .failure(ATRequestPrepareError.missingActiveSession)
}

guard let sessionURL = session?.pdsURL,
let requestURL = URL(string: "\(sessionURL)/xrpc/app.bsky.graph.getKnownFollowers") else {
return .failure(ATRequestPrepareError.invalidRequestURL)
}

var queryItems = [(String, String)]()

if let limit {
let finalLimit = max(1, min(limit, 100))
queryItems.append(("limit", "\(finalLimit)"))
}

if let cursor {
queryItems.append(("cursor", cursor))
}

let queryURL: URL

do {
queryURL = try APIClientService.setQueryItems(
for: requestURL,
with: queryItems
)

let request = APIClientService.createRequest(forRequest: queryURL,
andMethod: .get,
acceptValue: "application/json",
contentTypeValue: nil,
authorizationValue: "Bearer \(accessToken)")
let response = try await APIClientService.sendRequest(request,
decodeTo: AppBskyLexicon.Graph.GetKnownFollowersOutput.self)

return .success(response)

} catch {
return .failure(error)
}
}
}

0 comments on commit 4da1ab5

Please sign in to comment.