Tusker/Tusker/Models/PinnedTimeline.swift

130 lines
3.9 KiB
Swift

//
// PinnedTimeline.swift
// Tusker
//
// Created by Shadowfacts on 1/27/23.
// Copyright © 2023 Shadowfacts. All rights reserved.
//
import UIKit
import Pachyderm
enum PinnedTimeline: Codable, Equatable, Hashable {
case home
case `public`(local: Bool)
case tag(hashtag: String)
case list(id: String)
case instance(URL)
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let type = try container.decode(String.self, forKey: .type)
switch type {
case "home":
self = .home
case "public":
self = .public(local: try container.decode(Bool.self, forKey: .local))
case "tag":
self = .tag(hashtag: try container.decode(String.self, forKey: .hashtag))
case "list":
self = .list(id: try container.decode(String.self, forKey: .listID))
case "instance":
self = .instance(try container.decode(URL.self, forKey: .instanceURL))
default:
throw DecodingError.dataCorruptedError(forKey: CodingKeys.type, in: container, debugDescription: "PinnedTimeline type must be one of 'home', 'local', 'tag', 'list', or 'instance'")
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .home:
try container.encode("home", forKey: .type)
case .public(let local):
try container.encode("public", forKey: .type)
try container.encode(local, forKey: .local)
case .tag(let hashtag):
try container.encode("tag", forKey: .type)
try container.encode(hashtag, forKey: .hashtag)
case .list(let id):
try container.encode("list", forKey: .type)
try container.encode(id, forKey: .listID)
case .instance(let url):
try container.encode("instance", forKey: .type)
try container.encode(url, forKey: .instanceURL)
}
}
init?(timeline: Timeline) {
switch timeline {
case .home:
self = .home
case .public(let local):
self = .public(local: local)
case .tag(let hashtag):
self = .tag(hashtag: hashtag)
case .list(let id):
self = .list(id: id)
case .direct:
return nil
}
}
var timeline: Timeline? {
switch self {
case .home:
return .home
case .public(let local):
return .public(local: local)
case .tag(let hashtag):
return .tag(hashtag: hashtag)
case .list(let id):
return .list(id: id)
case .instance(_):
return nil
}
}
var title: String {
switch self {
case .home:
return "Home"
case let .public(local):
return local ? "Local" : "Federated"
case let .tag(hashtag):
return "#\(hashtag)"
case .list:
return "List"
case .instance(let url):
return url.host!
}
}
var image: UIImage {
switch self {
case .home:
return UIImage(systemName: "house.fill")!
case let .public(local):
if local {
return UIImage(systemName: "person.and.person.fill")!
} else {
return UIImage(systemName: "globe")!
}
case .list(id: _):
return UIImage(systemName: "list.bullet")!
case .tag(hashtag: _):
return UIImage(systemName: "number")!
case .instance(_):
return UIImage(systemName: "globe")!
}
}
private enum CodingKeys: String, CodingKey {
case type
case local
case hashtag
case listID
case instanceURL
}
}