added Sendable and other corrections

This commit is contained in:
Wilhelm Oks 2024-12-22 17:24:48 +01:00
parent d782a2fcf5
commit 3824735fe1
26 changed files with 119 additions and 49 deletions

View File

@ -1,6 +1,6 @@
/// Represents an error coming directly from the devrant API.
public struct DevRantApiError: Swift.Error {
let message: String
public let message: String
}
public extension DevRantApiError {

View File

@ -1,5 +1,5 @@
/// An image that the user has uploaded for his rant or comment.
public struct AttachedImage: Hashable {
public struct AttachedImage: Hashable, Sendable {
public let url: String
public let width: Int
public let height: Int

View File

@ -1,6 +1,6 @@
import Foundation
public struct AuthToken: Hashable {
public struct AuthToken: Hashable, Sendable {
public let id: Int
public let key: String
public let expireTime: Date
@ -18,21 +18,21 @@ public struct AuthToken: Hashable {
}
}
extension AuthToken {
struct CodingData: Codable {
struct Container: Codable {
public extension AuthToken {
public struct CodingData: Codable {
public struct Container: Codable {
let auth_token: AuthToken.CodingData
}
let id: Int
let key: String
let expire_time: Int
let user_id: Int
public let id: Int
public let key: String
public let expire_time: Int
public let user_id: Int
}
}
extension AuthToken.CodingData {
var decoded: AuthToken {
public extension AuthToken.CodingData {
public var decoded: AuthToken {
.init(
id: id,
key: key,
@ -41,3 +41,14 @@ extension AuthToken.CodingData {
)
}
}
public extension AuthToken {
public var encoded: AuthToken.CodingData {
.init(
id: id,
key: key,
expire_time: Int(expireTime.timeIntervalSince1970),
user_id: userId
)
}
}

View File

@ -1,5 +1,5 @@
public struct Collaboration: Hashable {
public enum Kind: Int {
public struct Collaboration: Hashable, Sendable {
public enum Kind: Int, Sendable {
case openSourceIdea = 1
case existingOpenSourceProject = 2
case projectIdea = 3

View File

@ -1,7 +1,7 @@
import Foundation
/// A comment posted by a user inside of a rant.
public struct Comment: Identifiable, Hashable {
public struct Comment: Identifiable, Hashable, Sendable {
/// The id of this comment.
public let id: Int

View File

@ -1,5 +1,5 @@
/// Represents the reason for downvoting.
public enum DownvoteReason: Int, Hashable {
public enum DownvoteReason: Int, Hashable, Sendable {
case notForMe = 0
case repost = 1
case offensiveOrSpam = 2

View File

@ -1,8 +1,8 @@
/// A URL or a user mention link in a rant or comment.
public struct Link: Hashable {
public enum Kind {
case url
case userMention
public struct Link: Hashable, Sendable {
public enum Kind: String, Sendable {
case url = "url"
case userMention = "mention"
}
public let kind: Kind
@ -47,7 +47,7 @@ extension Link {
extension Link.CodingData {
var decoded: Link {
.init(
kind: type == "mention" ? .userMention : .url,
kind: .init(rawValue: type) ?? .url,
url: url,
shortURL: short_url,
title: title,

View File

@ -1,8 +1,8 @@
import Foundation
/// A notification about activities in a rant or a comment.
public struct Notification: Hashable, Identifiable {
public enum Kind: String {
public struct Notification: Hashable, Identifiable, Sendable {
public enum Kind: String, Sendable {
/// An upvote for a rant.
case rantUpvote = "content_vote"

View File

@ -0,0 +1,57 @@
import Foundation
public extension NotificationFeed {
public struct MappedNotificationItem: Hashable, Sendable {
public let rantId: Rant.ID
public let commentId: Comment.ID?
public let userId: Int
public let userAvatar: User.Avatar
public let userName: String
public let notificationKind: Notification.Kind
public let created: Date
public let isRead: Bool
public init(rantId: Rant.ID, commentId: Comment.ID?, userId: Int, userAvatar: User.Avatar, userName: String, notificationKind: Notification.Kind, created: Date, isRead: Bool) {
self.rantId = rantId
self.commentId = commentId
self.userId = userId
self.userAvatar = userAvatar
self.userName = userName
self.notificationKind = notificationKind
self.created = created
self.isRead = isRead
}
}
public var mappedItems: [MappedNotificationItem] {
notifications.map { notification in
let rantId = notification.rantId
let commentId = notification.commentId
let userId = notification.userId
let userInfo = userInfos.first { $0.userId == String(userId) }
let userAvatar = userInfo?.avatar ?? .init(colorHex: "cccccc", imageUrlPath: nil)
let userName = userInfo?.username ?? ""
return MappedNotificationItem(
rantId: rantId,
commentId: commentId,
userId: userId,
userAvatar: userAvatar,
userName: userName,
notificationKind: notification.kind,
created: notification.created,
isRead: notification.read
)
}
}
public var unreadByCategory: [NotificationFeed.Category: Int] {
[
.all: unreadNumbers.all,
.upvotes: unreadNumbers.upvotes,
.mentions: unreadNumbers.mentions,
.comments: unreadNumbers.comments,
.subscriptions: unreadNumbers.subscriptions,
]
}
}

View File

@ -1,6 +1,6 @@
public extension NotificationFeed {
/// Holds numbers of unread notifications for each type of notification.
struct UnreadNumbers: Decodable, Hashable {
struct UnreadNumbers: Decodable, Hashable, Sendable {
/// The total number of unread notifications
public let all: Int

View File

@ -1,5 +1,5 @@
public extension NotificationFeed {
struct UserInfo: Hashable {
struct UserInfo: Hashable, Sendable {
public let avatar: User.Avatar
public let username: String
public let userId: String //TODO: why is this String? The other user ids are Int.

View File

@ -1,8 +1,8 @@
import Foundation
/// Contains a list of all notifications for the logged in user and the numbers of unread notifications.
public struct NotificationFeed: Hashable {
public enum Category: String, CaseIterable {
public struct NotificationFeed: Hashable, Sendable {
public enum Category: String, CaseIterable, Sendable {
case all = ""
case upvotes = "upvotes"
case mentions = "mentions"

View File

@ -1,5 +1,5 @@
public extension Profile.Content {
struct Elements: Hashable {
struct Elements: Hashable, Sendable {
/// The rants that the user has created.
public let rants: [Rant]

View File

@ -1,5 +1,5 @@
public extension Profile.Content {
struct Numbers: Hashable {
struct Numbers: Hashable, Sendable {
/// The number of rants that the user has created.
public let rants: Int

View File

@ -1,5 +1,5 @@
public extension Profile {
struct Content: Hashable {
struct Content: Hashable, Sendable {
public let elements: Elements
public let numbers: Numbers

View File

@ -1,7 +1,7 @@
import Foundation
/// Holds information, content and the activity history of a user.
public struct Profile: Hashable {
public struct Profile: Hashable, Sendable {
/// The user's alias.
public let username: String
@ -39,7 +39,7 @@ public struct Profile: Hashable {
public let devRantSupporter: Bool
/// True if the logged in user is subscribed to the user of this profile.
public let subscribed: Bool //TODO: where is this set? It's not in the json data of the profile
public var subscribed: Bool //TODO: where is this set? It's not in the json data of the profile
public init(username: String, score: Int, created: Date, about: String?, location: String?, skills: String?, github: String?, website: String?, content: Profile.Content, avatarLarge: User.Avatar, avatarSmall: User.Avatar, devRantSupporter: Bool, subscribed: Bool) {
self.username = username
@ -59,7 +59,7 @@ public struct Profile: Hashable {
}
public extension Profile {
enum ContentType: String {
enum ContentType: String, Sendable {
/// All user content.
case all = "all"

View File

@ -1,5 +1,5 @@
public extension Rant {
public enum Kind: Int {
public enum Kind: Int, Sendable {
case rant = 1
case collaboration = 2
case meme = 3

View File

@ -1,6 +1,6 @@
public extension Rant {
/// Holds information about a specific weekly group rant.
struct Weekly: Hashable {
struct Weekly: Hashable, Sendable {
public let week: Int
public let topic: String
public let date: String

View File

@ -1,6 +1,6 @@
import Foundation
public struct Rant: Identifiable, Hashable {
public struct Rant: Identifiable, Hashable, Sendable {
/// The id of this rant.
public let id: Int
@ -23,7 +23,7 @@ public struct Rant: Identifiable, Hashable {
public let isEdited: Bool
/// True if this rant has been marked as a favorite by the logged in user.
public let isFavorite: Bool
public var isFavorite: Bool
/// The text contents of this rant.
public let text: String

View File

@ -1,8 +1,8 @@
public extension RantFeed {
/// Contains information about news given in rant feeds.
/// - note: This is mostly used for weekly group rants.
struct News: Hashable, Identifiable {
public enum Action: String {
struct News: Hashable, Identifiable, Sendable {
public enum Action: String, Sendable {
case groupRant = "grouprant"
case none = "none"
case rant = "rant"

View File

@ -1,5 +1,5 @@
/// Contains the list of rants for the logged in user and other random things.
public struct RantFeed: Hashable {
public struct RantFeed: Hashable, Sendable {
public let rants: [Rant]
public let sessionHash: String?
@ -25,7 +25,7 @@ public struct RantFeed: Hashable {
}
public extension RantFeed {
enum Sort {
enum Sort: Sendable {
/// The devRant algorithm decides what rants appear in the feed.
case algorithm
@ -36,7 +36,7 @@ public extension RantFeed {
case top(range: Range)
}
enum Range {
enum Range: Sendable {
/// Rants from the one day.
case day

View File

@ -1,11 +1,13 @@
import Foundation
public extension User {
struct Avatar: Hashable {
struct Avatar: Hashable, Sendable {
public let colorHex: String
public let imageUrlPath: String?
public var imageUrl: String? {
imageUrlPath.flatMap { "https://avatars.devrant.com/\($0)" }
public var imageUrl: URL? {
imageUrlPath.flatMap { URL(string: "https://avatars.devrant.com/\($0)") }
}
public init(colorHex: String, imageUrlPath: String?) {

View File

@ -1,5 +1,5 @@
/// Represents a user.
public struct User: Identifiable, Hashable {
public struct User: Identifiable, Hashable, Sendable {
public let id: Int
public let name: String

View File

@ -1,5 +1,5 @@
/// Represents the different kinds of votes that a rant or comment can have.
public enum VoteState: Int, Hashable {
public enum VoteState: Int, Hashable, Sendable {
/// A given ++ vote.
case upvoted = 1

View File

@ -1,5 +1,5 @@
/// The weekly item data for the list of weeklies.
public struct Weekly: Hashable, Identifiable {
public struct Weekly: Hashable, Identifiable, Sendable {
/// The number of the week. The first week starts with 1.
public let week: Int

View File

@ -1,7 +1,7 @@
import Foundation
import KreeRequest
public struct SwiftDevRant {
public struct SwiftDevRant { //TODO: rename to something else to not collide with the module name
let request: KreeRequest
let backend = DevRantBackend()