mastodon-ios/Mastodon/Diffiable/Item/Item.swift

185 lines
6.3 KiB
Swift
Raw Normal View History

2021-01-28 09:10:30 +01:00
//
// Item.swift
// Mastodon
//
// Created by sxiaojian on 2021/1/27.
//
import CoreData
import CoreDataStack
2021-02-03 06:01:50 +01:00
import Foundation
import MastodonSDK
2021-01-28 09:10:30 +01:00
/// Note: update Equatable when change case
enum Item {
// timeline
2021-03-05 06:41:48 +01:00
case homeTimelineIndex(objectID: NSManagedObjectID, attribute: StatusAttribute)
2021-04-13 13:46:42 +02:00
// thread
case root(statusObjectID: NSManagedObjectID, attribute: StatusAttribute)
case reply(statusObjectID: NSManagedObjectID, attribute: StatusAttribute)
case leaf(statusObjectID: NSManagedObjectID, attribute: StatusAttribute)
case leafBottomLoader(statusObjectID: NSManagedObjectID)
2021-02-07 07:42:50 +01:00
2021-01-28 09:10:30 +01:00
// normal list
2021-04-01 08:39:15 +02:00
case status(objectID: NSManagedObjectID, attribute: StatusAttribute)
2021-02-03 06:01:50 +01:00
2021-02-04 08:09:58 +01:00
// loader
2021-02-07 07:42:50 +01:00
case homeMiddleLoader(upperTimelineIndexAnchorObjectID: NSManagedObjectID)
2021-04-01 08:39:15 +02:00
case publicMiddleLoader(statusID: String)
2021-04-13 13:46:42 +02:00
case topLoader
2021-02-03 06:01:50 +01:00
case bottomLoader
case emptyStateHeader(attribute: EmptyStateHeaderAttribute)
2021-01-28 09:10:30 +01:00
}
protocol StatusContentWarningAttribute {
2021-04-01 08:39:15 +02:00
var isStatusTextSensitive: Bool? { get set }
var isStatusSensitive: Bool? { get set }
}
2021-02-07 07:42:50 +01:00
extension Item {
2021-04-01 08:39:15 +02:00
class StatusAttribute: StatusContentWarningAttribute {
var isStatusTextSensitive: Bool?
var isStatusSensitive: Bool?
2021-04-13 13:46:42 +02:00
var isSeparatorLineHidden: Bool
2021-02-07 07:42:50 +01:00
2021-04-01 08:39:15 +02:00
init(
isStatusTextSensitive: Bool? = nil,
2021-04-13 13:46:42 +02:00
isStatusSensitive: Bool? = nil,
isSeparatorLineHidden: Bool = false
) {
self.isStatusTextSensitive = isStatusTextSensitive
self.isStatusSensitive = isStatusSensitive
2021-04-13 13:46:42 +02:00
self.isSeparatorLineHidden = isSeparatorLineHidden
}
2021-04-01 08:39:15 +02:00
// delay attribute init
func setupForStatus(status: Status) {
if isStatusTextSensitive == nil {
isStatusTextSensitive = {
guard let spoilerText = status.spoilerText, !spoilerText.isEmpty else { return false }
return true
}()
}
if isStatusSensitive == nil {
isStatusSensitive = status.sensitive
}
2021-02-07 07:42:50 +01:00
}
}
2021-04-13 13:46:42 +02:00
// class LeafAttribute {
// let identifier = UUID()
// let statusID: Status.ID
// var level: Int = 0
// var hasReply: Bool = true
//
// init(
// statusID: Status.ID,
// level: Int,
// hasReply: Bool = true
// ) {
// self.statusID = statusID
// self.level = level
// self.hasReply = hasReply
// }
// }
class EmptyStateHeaderAttribute: Hashable {
let id = UUID()
let reason: Reason
enum Reason: Equatable {
case noStatusFound
case blocking
case blocked
case suspended(name: String?)
static func == (lhs: Item.EmptyStateHeaderAttribute.Reason, rhs: Item.EmptyStateHeaderAttribute.Reason) -> Bool {
switch (lhs, rhs) {
case (.noStatusFound, noStatusFound): return true
case (.blocking, blocking): return true
case (.blocked, blocked): return true
case (.suspended(let nameLeft), .suspended(let nameRight)): return nameLeft == nameRight
default: return false
}
}
}
init(reason: Reason) {
self.reason = reason
}
static func == (lhs: Item.EmptyStateHeaderAttribute, rhs: Item.EmptyStateHeaderAttribute) -> Bool {
return lhs.reason == rhs.reason
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
2021-02-07 07:42:50 +01:00
}
2021-01-28 09:10:30 +01:00
extension Item: Equatable {
static func == (lhs: Item, rhs: Item) -> Bool {
switch (lhs, rhs) {
2021-02-07 07:42:50 +01:00
case (.homeTimelineIndex(let objectIDLeft, _), .homeTimelineIndex(let objectIDRight, _)):
return objectIDLeft == objectIDRight
2021-04-13 13:46:42 +02:00
case (.root(let objectIDLeft, _), .root(let objectIDRight, _)):
return objectIDLeft == objectIDRight
case (.reply(let objectIDLeft, _), .reply(let objectIDRight, _)):
return objectIDLeft == objectIDRight
case (.leaf(let objectIDLeft, _), .leaf(let objectIDRight, _)):
return objectIDLeft == objectIDRight
case (.leafBottomLoader(let objectIDLeft), .leafBottomLoader(let objectIDRight)):
return objectIDLeft == objectIDRight
2021-04-01 08:39:15 +02:00
case (.status(let objectIDLeft, _), .status(let objectIDRight, _)):
2021-01-28 09:10:30 +01:00
return objectIDLeft == objectIDRight
2021-02-07 07:42:50 +01:00
case (.homeMiddleLoader(let upperLeft), .homeMiddleLoader(let upperRight)):
2021-02-04 08:09:58 +01:00
return upperLeft == upperRight
case (.publicMiddleLoader(let upperLeft), .publicMiddleLoader(let upperRight)):
return upperLeft == upperRight
2021-04-13 13:46:42 +02:00
case (.topLoader, .topLoader):
return true
case (.bottomLoader, .bottomLoader):
return true
case (.emptyStateHeader(let attributeLeft), .emptyStateHeader(let attributeRight)):
return attributeLeft == attributeRight
2021-02-03 06:01:50 +01:00
default:
return false
2021-01-28 09:10:30 +01:00
}
}
}
extension Item: Hashable {
func hash(into hasher: inout Hasher) {
switch self {
2021-02-07 07:42:50 +01:00
case .homeTimelineIndex(let objectID, _):
hasher.combine(objectID)
2021-04-13 13:46:42 +02:00
case .root(let objectID, _):
hasher.combine(objectID)
case .reply(let objectID, _):
hasher.combine(objectID)
case .leaf(let objectID, _):
hasher.combine(objectID)
case .leafBottomLoader(let objectID):
hasher.combine(objectID)
2021-04-01 08:39:15 +02:00
case .status(let objectID, _):
2021-01-28 09:10:30 +01:00
hasher.combine(objectID)
2021-02-07 07:42:50 +01:00
case .homeMiddleLoader(upperTimelineIndexAnchorObjectID: let upper):
hasher.combine(String(describing: Item.homeMiddleLoader.self))
2021-02-04 08:09:58 +01:00
hasher.combine(upper)
case .publicMiddleLoader(let upper):
hasher.combine(String(describing: Item.publicMiddleLoader.self))
hasher.combine(upper)
2021-04-13 13:46:42 +02:00
case .topLoader:
hasher.combine(String(describing: Item.topLoader.self))
2021-02-03 06:01:50 +01:00
case .bottomLoader:
hasher.combine(String(describing: Item.bottomLoader.self))
case .emptyStateHeader(let attribute):
hasher.combine(attribute)
2021-01-28 09:10:30 +01:00
}
}
}