| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- //
- // LNProfileManager.swift
- // Lanu
- //
- // Created by OneeChan on 2025/11/6.
- //
- import Foundation
- protocol LNProfileManagerNotify {
- func onUserInfoChanged(userInfo: LNUserProfileVO)
- func onBindPhoneCaptchaCoolDownChanged(time: Int)
- func onUserVoiceBarInfoChanged()
- }
- extension LNProfileManagerNotify {
- func onUserInfoChanged(userInfo: LNUserProfileVO) { }
- func onBindPhoneCaptchaCoolDownChanged(time: Int) { }
- func onUserVoiceBarInfoChanged() { }
- }
- var myUserInfo: LNUserProfileVO {
- LNProfileManager.shared.myUserInfo
- }
- var myVoiceBarInfo: LNUserVoiceStateVO {
- LNProfileManager.shared.myVoiceState
- }
- class LNProfileManager {
- static let shared = LNProfileManager()
- static let nameMaxInput = 25
- static let bioMaxInput = 100
-
- fileprivate var myUserInfo: LNUserProfileVO = LNUserProfileVO()
- fileprivate var myVoiceState: LNUserVoiceStateVO = LNUserVoiceStateVO()
-
- private var randomProfile: LNRandomProfileResponse?
-
- private let captchaCoolDown = 60
- private var captchaRemain = 0
- private var captchaTimer: Timer?
- var canSendCaptcha: Bool {
- captchaRemain == 0
- }
-
- private init() {
- LNEventDeliver.addObserver(self)
- }
- }
- extension LNProfileManager {
- func reloadMyProfile() {
- LNHttpManager.shared.getMyProfile { [weak self] res, err in
- guard let self else { return }
- guard err == nil, let res else { return }
- if let relation = res.userFollowStat {
- LNRelationManager.shared.updateMyRelationInfo(relation)
- }
- if let voice = res.userVoice {
- myVoiceState = voice
- notifyUserVoiceBarInfoChanged()
- }
- }
- getUserProfile(uid: myUid) { _ in }
- }
-
- func modifyMyProfile(config: LNProfileUpdateConfig, queue: DispatchQueue = .main,
- handler: @escaping (Bool) -> Void) {
- LNHttpManager.shared.modifyMyProfile(
- config: config) { [weak self] err in
- guard let self else { return }
- if let err {
- showToast(err.errorDesc)
- } else {
- reloadMyProfile()
- if config.interest != nil {
- LNGameMateManager.shared.getGameTypeList { _ in }
- }
- }
- queue.asyncIfNotGlobal {
- handler(err == nil)
- }
- }
- }
-
- func setMyVoiceBar(url: String, duration: Int, queue: DispatchQueue = .main,
- handler: @escaping (Bool) -> Void) {
- LNHttpManager.shared.setMyVoiceBar(url: url, duration: duration) { [weak self] err in
- queue.asyncIfNotGlobal {
- handler(err == nil)
- }
- if let err {
- showToast(err.errorDesc)
- } else {
- guard let self else { return }
- reloadMyProfile()
- }
- }
- }
-
- func cleanVoiceBar(queue: DispatchQueue = .main, handler: @escaping (Bool) -> Void) {
- LNHttpManager.shared.cleanVoiceBar { [weak self] err in
- queue.asyncIfNotGlobal {
- handler(err == nil)
- }
- if let err {
- showToast(err.errorDesc)
- } else {
- guard let self else { return }
- reloadMyProfile()
- }
- }
- }
- }
- extension LNProfileManager {
- func getUserProfile(uid: String, queue: DispatchQueue = .main, handler: @escaping (LNUserProfileVO?) -> Void) {
- LNHttpManager.shared.getUsersInfo(uids: [uid]) { [weak self] res, err in
- guard let self else { return }
- if let res, err == nil {
- res.list.forEach {
- if $0.userNo.isMyUid {
- self.myUserInfo = $0
- }
- self.notifyUserInfoChanged(newInfo: $0)
- }
- } else {
- showToast(err?.errorDesc)
- }
- queue.asyncIfNotGlobal {
- handler(res?.list.first)
- }
- }
- }
-
- func getRandomProfile(queue: DispatchQueue = .main,
- handler: @escaping (LNProfileRandomInfoVO?, LNProfileRandomInfoVO?) -> Void) {
- if let randomProfile {
- handler(randomProfile.male, randomProfile.female)
- return
- }
- LNHttpManager.shared.getRandomProfile { [weak self] res, err in
- if let self, let res {
- randomProfile = res
- }
- queue.asyncIfNotGlobal {
- handler(res?.male, res?.female)
- }
- }
- }
-
- // func getUserOnlineState(uids: [String], queue: DispatchQueue = .main, handler: @escaping ([String: Bool]) -> Void) {
- // LNHttpManager.shared.getUserOnlineState(uids: uids) { res, err in
- // queue.asyncIfNotGlobal {
- // handler(res?.list.reduce(into: [String: Bool](), { partialResult, state in
- // partialResult[state.userNo] = state.online
- // }) ?? [:])
- // }
- // }
- // }
- }
- extension LNProfileManager {
- func getBindPhoneCaptcha(code: String, phone: String,
- queue: DispatchQueue = .main,
- handler: @escaping (Bool) -> Void) {
- LNHttpManager.shared.getBindPhoneCaptcha(code: code, phone: phone) { [weak self] err in
- queue.asyncIfNotGlobal {
- handler(err == nil)
- }
- guard let self else { return }
- if let err {
- showToast(err.errorDesc)
- } else {
- captchaRemain = captchaCoolDown
- notifyCaptchaTime(time: captchaRemain)
- startCaptchaTimer()
- }
- }
- }
-
- func bindPhone(code: String, phone: String,
- queue: DispatchQueue = .main,
- captcha: String, handler: @escaping (Bool) -> Void) {
- LNHttpManager.shared.bindPhone(code: code, phone: phone, captcha: captcha) { err in
- queue.asyncIfNotGlobal {
- handler(err == nil)
- }
- if let err {
- showToast(err.errorDesc)
- }
- }
- }
-
- private func startCaptchaTimer() {
- DispatchQueue.main.async { [weak self] in
- guard let self else { return }
- stopCaptchaTimer()
-
- let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in
- guard let self else { return }
- captchaRemain -= 1
- notifyCaptchaTime(time: captchaRemain)
- if captchaRemain == 0 {
- stopCaptchaTimer()
- }
- }
- RunLoop.main.add(timer, forMode: .common)
- captchaTimer = timer
- }
- }
-
- private func stopCaptchaTimer() {
- captchaTimer?.invalidate()
- captchaTimer = nil
- }
- }
- extension LNProfileManager {
- func reportCurrentLanguage(code: String,
- queue: DispatchQueue = .main,
- handler: @escaping (Bool) -> Void) {
- LNHttpManager.shared.reportCurrentLanguage(code: code) { err in
- queue.asyncIfNotGlobal {
- handler(err == nil)
- }
- }
- }
- }
- extension LNProfileManager: LNAccountManagerNotify {
- func onUserLogin() {
- reloadMyProfile()
- }
-
- func onUserLogout() {
- myUserInfo = LNUserProfileVO()
- }
- }
- extension LNProfileManager {
- private func notifyUserInfoChanged(newInfo: LNUserProfileVO) {
- LNEventDeliver.notifyEvent { ($0 as? LNProfileManagerNotify)?.onUserInfoChanged(userInfo: newInfo) }
- }
-
- private func notifyCaptchaTime(time: Int) {
- LNEventDeliver.notifyEvent {
- ($0 as? LNProfileManagerNotify)?.onBindPhoneCaptchaCoolDownChanged(time: time)
- }
- }
-
- private func notifyUserVoiceBarInfoChanged() {
- LNEventDeliver.notifyEvent { ($0 as? LNProfileManagerNotify)?.onUserVoiceBarInfoChanged() }
- }
- }
|