Models WIP: AttachedImage, Link, Rant.Weekly, User.Avatar
This commit is contained in:
parent
2781bf4bdd
commit
2e4d605ecc
30
Sources/SwiftDevRant/Models/AttachedImage.swift
Normal file
30
Sources/SwiftDevRant/Models/AttachedImage.swift
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/// An image that the user has uploaded for his rant or comment.
|
||||||
|
public struct AttachedImage: Hashable {
|
||||||
|
public let url: String
|
||||||
|
public let width: Int
|
||||||
|
public let height: Int
|
||||||
|
|
||||||
|
public init(url: String, width: Int, height: Int) {
|
||||||
|
self.url = url
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AttachedImage {
|
||||||
|
struct CodingData: Codable {
|
||||||
|
let url: String
|
||||||
|
let width: Int
|
||||||
|
let height: Int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AttachedImage.CodingData {
|
||||||
|
var decoded: AttachedImage {
|
||||||
|
.init(
|
||||||
|
url: url,
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -4,4 +4,12 @@ public struct Collaboration: Hashable {
|
|||||||
public let techStack: String
|
public let techStack: String
|
||||||
public let teamSize: String
|
public let teamSize: String
|
||||||
public let url: String
|
public let url: String
|
||||||
|
|
||||||
|
public init(type: String, description: String, techStack: String, teamSize: String, url: String) {
|
||||||
|
self.type = type
|
||||||
|
self.description = description
|
||||||
|
self.techStack = techStack
|
||||||
|
self.teamSize = teamSize
|
||||||
|
self.url = url
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
58
Sources/SwiftDevRant/Models/Link.swift
Normal file
58
Sources/SwiftDevRant/Models/Link.swift
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/// A URL or a user mention link in a rant or comment.
|
||||||
|
public struct Link: Hashable {
|
||||||
|
public enum Kind {
|
||||||
|
case url
|
||||||
|
case userMention
|
||||||
|
}
|
||||||
|
|
||||||
|
public let kind: Kind
|
||||||
|
|
||||||
|
/// The full URL.
|
||||||
|
public let url: String
|
||||||
|
|
||||||
|
public let shortURL: String? //TODO: what is this and what is it used for?
|
||||||
|
|
||||||
|
/// The url as it is visible in the text of the rant or comment.
|
||||||
|
public let title: String
|
||||||
|
|
||||||
|
/// The starting position of the link in the overall text of the rant or comment.
|
||||||
|
/// - Important: The devRant API returns offsets for links in byte offsets and not in normalized character offsets. Please take this into account when using these offsets.
|
||||||
|
public let start: Int?
|
||||||
|
|
||||||
|
/// The ending position of the link in the overall text of the rant or comment.
|
||||||
|
/// - Important: The devRant API returns offsets for links in byte offsets and not in normalized character offsets. Please take this into account when using these offsets.
|
||||||
|
public let end: Int?
|
||||||
|
|
||||||
|
public init(kind: Link.Kind, url: String, shortURL: String?, title: String, start: Int?, end: Int?) {
|
||||||
|
self.kind = kind
|
||||||
|
self.url = url
|
||||||
|
self.shortURL = shortURL
|
||||||
|
self.title = title
|
||||||
|
self.start = start
|
||||||
|
self.end = end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Link {
|
||||||
|
struct CodingData: Codable {
|
||||||
|
let type: String
|
||||||
|
let url: String
|
||||||
|
let short_url: String
|
||||||
|
let title: String
|
||||||
|
let start: Int?
|
||||||
|
let end: Int?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Link.CodingData {
|
||||||
|
var decoded: Link {
|
||||||
|
.init(
|
||||||
|
kind: type == "mention" ? .userMention : .url,
|
||||||
|
url: url,
|
||||||
|
shortURL: short_url,
|
||||||
|
title: title,
|
||||||
|
start: start,
|
||||||
|
end: end
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
36
Sources/SwiftDevRant/Models/Rant.Weekly.swift
Normal file
36
Sources/SwiftDevRant/Models/Rant.Weekly.swift
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
public extension Rant {
|
||||||
|
/// Holds information about a specific weekly group rant.
|
||||||
|
struct Weekly: Hashable {
|
||||||
|
public let week: Int
|
||||||
|
public let topic: String
|
||||||
|
public let date: String
|
||||||
|
public let uiHeight: Int
|
||||||
|
|
||||||
|
public init(week: Int, topic: String, date: String, uiHeight: Int) {
|
||||||
|
self.week = week
|
||||||
|
self.topic = topic
|
||||||
|
self.date = date
|
||||||
|
self.uiHeight = uiHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Rant.Weekly {
|
||||||
|
struct CodingData: Codable {
|
||||||
|
let week: Int
|
||||||
|
let topic: String
|
||||||
|
let date: String
|
||||||
|
let height: Int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Rant.Weekly.CodingData {
|
||||||
|
var decoded: Rant.Weekly {
|
||||||
|
.init(
|
||||||
|
week: week,
|
||||||
|
topic: topic,
|
||||||
|
date: date,
|
||||||
|
uiHeight: height
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public struct Rant: Identifiable, Hashable {
|
public struct Rant: Identifiable, Hashable {
|
||||||
//TODO: public let weekly: Weekly?
|
|
||||||
|
|
||||||
/// The id of this rant.
|
/// The id of this rant.
|
||||||
public let id: Int
|
public let id: Int
|
||||||
|
|
||||||
@ -15,8 +13,8 @@ public struct Rant: Identifiable, Hashable {
|
|||||||
/// The time when this rant was created.
|
/// The time when this rant was created.
|
||||||
public let created: Date
|
public let created: Date
|
||||||
|
|
||||||
/// If the rant has an image attached to it, a URL of the image will be stored in this.
|
/// The optional image that the user has uploaded for this rant.
|
||||||
//TODO: public let attachedImage: AttachedImage?
|
public let image: AttachedImage?
|
||||||
|
|
||||||
/// The number of comments that this rant has.
|
/// The number of comments that this rant has.
|
||||||
public let numberOfComments: Int
|
public let numberOfComments: Int
|
||||||
@ -33,17 +31,20 @@ public struct Rant: Identifiable, Hashable {
|
|||||||
/// True if this rant has been marked as a favorite by the logged in user.
|
/// True if this rant has been marked as a favorite by the logged in user.
|
||||||
public var isFavorite: Bool
|
public var isFavorite: Bool
|
||||||
|
|
||||||
/// A url link to this rant.
|
/// A URL link to this rant.
|
||||||
public let link: String?
|
public let linkToRant: String?
|
||||||
|
|
||||||
/// If the rant includes URLs in the text, those that were successfully parsed by the server will be in this array.
|
/// The URLs and user mentions inside of the text of this rant.
|
||||||
//TODO: public var links: [Link]?
|
public var linksInText: [Link]
|
||||||
|
|
||||||
|
/// Holds information about the weekly topic if this rant is of type weekly.
|
||||||
|
public let weekly: Weekly?
|
||||||
|
|
||||||
/// Holds information about the collaboration project if this rant is of type collaboration.
|
/// Holds information about the collaboration project if this rant is of type collaboration.
|
||||||
let collaboration: Collaboration?
|
public let collaboration: Collaboration?
|
||||||
|
|
||||||
/// The user who wrote this rant.
|
/// The user who wrote this rant.
|
||||||
let author: User
|
public let author: User
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Rant {
|
extension Rant {
|
||||||
@ -52,15 +53,15 @@ extension Rant {
|
|||||||
let text: String
|
let text: String
|
||||||
let score: Int
|
let score: Int
|
||||||
let created_time: Int
|
let created_time: Int
|
||||||
//TODO: let attachedImage: AttachedImage?
|
let attached_image: AttachedImage.CodingData?
|
||||||
let num_comments: Int
|
let num_comments: Int
|
||||||
let tags: [String]
|
let tags: [String]
|
||||||
let vote_state: Int
|
let vote_state: Int
|
||||||
//TODO: let weekly: Weekly?
|
|
||||||
let edited: Bool
|
let edited: Bool
|
||||||
let favorited: Int?
|
let favorited: Int?
|
||||||
let link: String?
|
let link: String?
|
||||||
//TODO: let links: [Link]
|
let links: [Link.CodingData]?
|
||||||
|
let weekly: Weekly.CodingData?
|
||||||
let c_type_long: String?
|
let c_type_long: String?
|
||||||
let c_description: String?
|
let c_description: String?
|
||||||
let c_tech_stack: String?
|
let c_tech_stack: String?
|
||||||
@ -69,8 +70,8 @@ extension Rant {
|
|||||||
let user_id: Int
|
let user_id: Int
|
||||||
let user_username: String
|
let user_username: String
|
||||||
let user_score: Int
|
let user_score: Int
|
||||||
//TODO: let user_avatar: UserAvatar
|
let user_avatar: User.Avatar.CodingData
|
||||||
//TODO: let user_avatar_lg: UserAvatar
|
let user_avatar_lg: User.Avatar.CodingData
|
||||||
let user_dpp: Int?
|
let user_dpp: Int?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,18 +83,23 @@ extension Rant.CodingData {
|
|||||||
text: text,
|
text: text,
|
||||||
score: score,
|
score: score,
|
||||||
created: Date(timeIntervalSince1970: TimeInterval(created_time)),
|
created: Date(timeIntervalSince1970: TimeInterval(created_time)),
|
||||||
|
image: attached_image?.decoded,
|
||||||
numberOfComments: num_comments,
|
numberOfComments: num_comments,
|
||||||
tags: tags,
|
tags: tags,
|
||||||
voteState: .init(rawValue: vote_state) ?? .unvoted,
|
voteState: .init(rawValue: vote_state) ?? .unvoted,
|
||||||
isEdited: edited,
|
isEdited: edited,
|
||||||
isFavorite: (favorited ?? 0) != 0,
|
isFavorite: (favorited ?? 0) != 0,
|
||||||
link: link,
|
linkToRant: link,
|
||||||
|
linksInText: links?.map(\.decoded) ?? [],
|
||||||
|
weekly: weekly?.decoded,
|
||||||
collaboration: decodedCollaboration,
|
collaboration: decodedCollaboration,
|
||||||
author: .init(
|
author: .init(
|
||||||
id: user_id,
|
id: user_id,
|
||||||
name: user_username,
|
name: user_username,
|
||||||
score: user_score,
|
score: user_score,
|
||||||
devRantSupporter: (user_dpp ?? 0) != 0
|
devRantSupporter: (user_dpp ?? 0) != 0,
|
||||||
|
avatar: user_avatar.decoded,
|
||||||
|
avatarLarge: user_avatar_lg.decoded
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
27
Sources/SwiftDevRant/Models/User.Avatar.swift
Normal file
27
Sources/SwiftDevRant/Models/User.Avatar.swift
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
public extension User {
|
||||||
|
struct Avatar: Hashable {
|
||||||
|
public let colorHex: String
|
||||||
|
|
||||||
|
public let imageUrlPath: String?
|
||||||
|
|
||||||
|
public var imageUrl: String? {
|
||||||
|
imageUrlPath.flatMap { "https://avatars.devrant.com/\($0)" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension User.Avatar {
|
||||||
|
struct CodingData: Codable {
|
||||||
|
let b: String
|
||||||
|
let i: String?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension User.Avatar.CodingData {
|
||||||
|
var decoded: User.Avatar {
|
||||||
|
.init(
|
||||||
|
colorHex: b,
|
||||||
|
imageUrlPath: i
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -4,9 +4,9 @@ public struct User: Identifiable, Hashable {
|
|||||||
public let score: Int
|
public let score: Int
|
||||||
public let devRantSupporter: Bool
|
public let devRantSupporter: Bool
|
||||||
|
|
||||||
/// The author's avatar, can be used optimally for small portraits of the user.
|
/// A small avatar for the rant views and comment views.
|
||||||
//TODO: public let userAvatar: UserAvatar
|
public let avatar: Avatar
|
||||||
|
|
||||||
/// A larger version of the author's avatar, can be used optimally for profile screens.
|
/// A large avatar for the profile view.
|
||||||
//TODO: public let userAvatarLarge: UserAvatar
|
public let avatarLarge: Avatar
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user