mastodon-ios/Mastodon/Scene/Profile/Header/ProfileHeaderViewModel.swift

116 lines
3.5 KiB
Swift
Raw Normal View History

2021-04-09 11:31:43 +02:00
//
// ProfileHeaderViewModel.swift
// Mastodon
//
// Created by MainasuK Cirno on 2021-4-9.
//
import os.log
2021-04-09 11:31:43 +02:00
import UIKit
import Combine
import CoreDataStack
2021-04-09 11:31:43 +02:00
import Kanna
import MastodonSDK
2021-07-23 13:10:27 +02:00
import MastodonMeta
2022-10-08 07:43:06 +02:00
import MastodonCore
import MastodonUI
2021-04-09 11:31:43 +02:00
final class ProfileHeaderViewModel {
2022-01-07 11:49:37 +01:00
static let avatarImageMaxSizeInPixel = CGSize(width: 400, height: 400)
2022-11-17 04:52:44 +01:00
static let bannerImageMaxSizeInPixel = CGSize(width: 1500, height: 500)
static let maxProfileFieldCount = 4
2021-04-09 11:31:43 +02:00
var disposeBag = Set<AnyCancellable>()
// input
let context: AppContext
let authContext: AuthContext
@Published var user: MastodonUser?
@Published var relationshipActionOptionSet: RelationshipActionOptionSet = .none
@Published var isMyself = false
@Published var isEditing = false
@Published var isUpdating = false
@Published var accountForEdit: Mastodon.Entity.Account?
// let needsFiledCollectionViewHidden = CurrentValueSubject<Bool, Never>(false)
2021-04-09 13:44:48 +02:00
2021-04-09 11:31:43 +02:00
// output
let profileInfo = ProfileInfo()
let profileInfoEditing = ProfileInfo()
@Published var isTitleViewDisplaying = false
@Published var isTitleViewContentOffsetSet = false
init(context: AppContext, authContext: AuthContext) {
2021-04-09 11:31:43 +02:00
self.context = context
self.authContext = authContext
$accountForEdit
.receive(on: DispatchQueue.main)
.sink { [weak self] account in
guard let self = self else { return }
guard let account = account else { return }
2022-11-17 04:49:49 +01:00
// banner
self.profileInfo.header = nil
self.profileInfoEditing.header = nil
// avatar
self.profileInfo.avatar = nil
self.profileInfoEditing.avatar = nil
// name
let name = account.displayNameWithFallback
self.profileInfo.name = name
self.profileInfoEditing.name = name
// bio
let note = ProfileHeaderViewModel.normalize(note: account.note)
self.profileInfo.note = note
self.profileInfoEditing.note = note
}
.store(in: &disposeBag)
2021-04-09 11:31:43 +02:00
}
}
extension ProfileHeaderViewModel {
class ProfileInfo {
// input
2022-11-17 04:49:49 +01:00
@Published var header: UIImage?
@Published var avatar: UIImage?
@Published var name: String?
@Published var note: String?
}
}
2021-04-09 11:31:43 +02:00
extension ProfileHeaderViewModel {
static func normalize(note: String?) -> String? {
let _note = note?.replacingOccurrences(of: "<br>|<br />", with: "\u{2028}", options: .regularExpression, range: nil)
.replacingOccurrences(of: "</p>", with: "</p>\u{2029}", range: nil)
.trimmingCharacters(in: .whitespacesAndNewlines)
guard let note = _note, !note.isEmpty else {
2021-04-09 11:31:43 +02:00
return nil
}
let html = try? HTML(html: note, encoding: .utf8)
return html?.text
}
}
// MARK: - ProfileViewModelEditable
extension ProfileHeaderViewModel: ProfileViewModelEditable {
var isEdited: Bool {
guard isEditing else { return false }
2021-04-09 11:31:43 +02:00
2022-11-17 04:49:49 +01:00
guard profileInfoEditing.header == nil else { return true }
guard profileInfoEditing.avatar == nil else { return true }
guard profileInfo.name == profileInfoEditing.name else { return true }
guard profileInfo.note == profileInfoEditing.note else { return true }
2021-04-09 11:31:43 +02:00
return false
}
}