ios_app_v2/yobble/ViewModels/PrivateChatsViewModel.swift
2025-10-21 03:55:48 +03:00

95 lines
3.5 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Foundation
final class PrivateChatsViewModel: ObservableObject {
@Published private(set) var chats: [PrivateChatListItem] = []
@Published private(set) var isInitialLoading: Bool = false
@Published private(set) var isLoadingMore: Bool = false
@Published var errorMessage: String?
private let chatService: ChatService
private let pageSize: Int
private var offset: Int = 0
private var hasMore: Bool = true
init(chatService: ChatService = ChatService(), pageSize: Int = 20) {
self.chatService = chatService
self.pageSize = pageSize
}
func loadInitialChats(force: Bool = false) {
guard !isInitialLoading else { return }
if !force && !chats.isEmpty { return }
isInitialLoading = true
errorMessage = nil
let previousOffset = offset
let previousHasMore = hasMore
offset = 0
hasMore = true
chatService.fetchPrivateChats(offset: 0, limit: pageSize) { [weak self] result in
guard let self else { return }
self.isInitialLoading = false
defer {
NotificationCenter.default.post(name: .chatsReloadCompleted, object: nil)
}
switch result {
case .success(let data):
self.chats = data.items
self.offset = data.items.count
self.hasMore = data.hasMore
case .failure(let error):
self.errorMessage = self.message(for: error)
self.offset = previousOffset
self.hasMore = previousHasMore
}
}
}
func refresh() {
loadInitialChats(force: true)
}
func loadMoreIfNeeded(currentItem item: PrivateChatListItem) {
guard hasMore, !isLoadingMore, item.id == chats.last?.id else { return }
isLoadingMore = true
chatService.fetchPrivateChats(offset: offset, limit: pageSize) { [weak self] result in
guard let self else { return }
self.isLoadingMore = false
switch result {
case .success(let data):
self.chats.append(contentsOf: data.items)
self.offset = self.chats.count
self.hasMore = data.hasMore
case .failure(let error):
self.errorMessage = self.message(for: error)
}
}
}
private func message(for error: Error) -> String {
if let chatError = error as? ChatServiceError {
return chatError.errorDescription ?? NSLocalizedString("Не удалось загрузить чаты.", comment: "")
}
if let networkError = error as? NetworkError {
switch networkError {
case .unauthorized:
return NSLocalizedString("Сессия истекла. Войдите снова.", comment: "")
case .invalidURL, .noResponse:
return NSLocalizedString("Ошибка соединения с сервером.", comment: "")
case .network(let underlying):
return String(format: NSLocalizedString("Ошибка сети: %@", comment: ""), underlying.localizedDescription)
case .server(let statusCode, _):
return String(format: NSLocalizedString("Ошибка сервера (%@).", comment: ""), "\(statusCode)")
}
}
return NSLocalizedString("Неизвестная ошибка. Попробуйте позже.", comment: "")
}
}