2021-04-09 11:31:43 +02:00
|
|
|
//
|
|
|
|
// ProfileHeaderViewModel.swift
|
|
|
|
// Mastodon
|
|
|
|
//
|
|
|
|
// Created by MainasuK Cirno on 2021-4-9.
|
|
|
|
//
|
|
|
|
|
2021-05-27 07:56:55 +02:00
|
|
|
import os.log
|
2021-04-09 11:31:43 +02:00
|
|
|
import UIKit
|
|
|
|
import Combine
|
2022-05-26 17:19:47 +02:00
|
|
|
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
|
2022-05-26 17:19:47 +02:00
|
|
|
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)
|
2021-05-27 07:56:55 +02:00
|
|
|
static let maxProfileFieldCount = 4
|
|
|
|
|
2021-04-09 11:31:43 +02:00
|
|
|
var disposeBag = Set<AnyCancellable>()
|
|
|
|
|
|
|
|
// input
|
|
|
|
let context: AppContext
|
2022-10-09 14:07:57 +02:00
|
|
|
let authContext: AuthContext
|
|
|
|
|
2022-05-26 17:19:47 +02:00
|
|
|
@Published var user: MastodonUser?
|
|
|
|
@Published var relationshipActionOptionSet: RelationshipActionOptionSet = .none
|
|
|
|
|
2022-12-13 16:07:37 +01:00
|
|
|
@Published var isMyself = false
|
2022-01-27 14:23:39 +01:00
|
|
|
@Published var isEditing = false
|
2022-05-26 17:19:47 +02:00
|
|
|
@Published var isUpdating = false
|
2022-01-27 14:23:39 +01:00
|
|
|
|
2022-05-26 17:19:47 +02:00
|
|
|
@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
|
2022-05-26 17:19:47 +02:00
|
|
|
let profileInfo = ProfileInfo()
|
|
|
|
let profileInfoEditing = ProfileInfo()
|
|
|
|
|
|
|
|
@Published var isTitleViewDisplaying = false
|
|
|
|
@Published var isTitleViewContentOffsetSet = false
|
2022-01-27 14:23:39 +01:00
|
|
|
|
2022-10-09 14:07:57 +02:00
|
|
|
init(context: AppContext, authContext: AuthContext) {
|
2021-04-09 11:31:43 +02:00
|
|
|
self.context = context
|
2022-10-09 14:07:57 +02:00
|
|
|
self.authContext = authContext
|
2022-01-27 14:23:39 +01:00
|
|
|
|
2022-05-26 17:19:47 +02:00
|
|
|
$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
|
2022-05-26 17:19:47 +02:00
|
|
|
// 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 {
|
2022-01-27 14:23:39 +01:00
|
|
|
class ProfileInfo {
|
|
|
|
// input
|
2022-11-17 04:49:49 +01:00
|
|
|
@Published var header: UIImage?
|
2022-05-26 17:19:47 +02:00
|
|
|
@Published var avatar: UIImage?
|
2022-01-27 14:23:39 +01:00
|
|
|
@Published var name: String?
|
|
|
|
@Published var note: String?
|
2021-05-27 07:56:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-09 11:31:43 +02:00
|
|
|
extension ProfileHeaderViewModel {
|
|
|
|
|
|
|
|
static func normalize(note: String?) -> String? {
|
2022-05-07 09:12:00 +02:00
|
|
|
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
|
|
|
|
}
|
2022-01-27 14:23:39 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: - ProfileViewModelEditable
|
|
|
|
extension ProfileHeaderViewModel: ProfileViewModelEditable {
|
2022-05-26 17:19:47 +02:00
|
|
|
var isEdited: Bool {
|
2022-01-27 14:23:39 +01:00
|
|
|
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 }
|
2022-05-26 17:19:47 +02:00
|
|
|
guard profileInfoEditing.avatar == nil else { return true }
|
|
|
|
guard profileInfo.name == profileInfoEditing.name else { return true }
|
|
|
|
guard profileInfo.note == profileInfoEditing.note else { return true }
|
2022-01-27 14:23:39 +01:00
|
|
|
|
2021-04-09 11:31:43 +02:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|