Compare commits

...

3 Commits

Author SHA1 Message Date
7015ccd41f update chetchik 2025-12-12 03:10:03 +03:00
9172a0b353 add chetchik 2025-12-12 02:39:23 +03:00
da5745cad8 add send long msg 2025-12-12 02:26:28 +03:00
3 changed files with 80 additions and 43 deletions

View File

@ -2842,9 +2842,6 @@
},
"Сообщение" : {
},
"Сообщение слишком длинное." : {
},
"Сообщения будут с рожками и ножками." : {

View File

@ -14,7 +14,7 @@ final class PrivateChatViewModel: ObservableObject {
private let chatId: String
private let currentUserId: String?
private let pageSize: Int
private let maxMessageLength: Int = 4096
let maxMessageLength: Int = 4096
private var didLoadInitially: Bool = false
private var messageObserver: NSObjectProtocol?
@ -74,11 +74,7 @@ final class PrivateChatViewModel: ObservableObject {
completion(false)
return
}
guard trimmed.count <= maxMessageLength else {
sendingErrorMessage = NSLocalizedString("Сообщение слишком длинное.", comment: "")
completion(false)
return
}
guard !isSending else {
sendingErrorMessage = NSLocalizedString("Дождитесь отправки предыдущего сообщения.", comment: "")
completion(false)
@ -92,36 +88,61 @@ final class PrivateChatViewModel: ObservableObject {
isSending = true
sendingErrorMessage = nil
chatService.sendPrivateMessage(chatId: chatId, content: trimmed) { [weak self] result in
guard let self else { return }
let chunks = splitMessage(trimmed, maxLength: maxMessageLength)
let dispatchGroup = DispatchGroup()
var overallSuccess = true
switch result {
case .success(let data):
let newMessage = MessageItem(
messageId: data.messageId,
messageType: "text",
chatId: data.chatId,
senderId: currentUserId,
senderData: nil,
content: trimmed,
mediaLink: nil,
isViewed: true,
viewedAt: nil,
createdAt: data.createdAt,
updatedAt: data.createdAt,
forwardMetadata: nil
)
for chunk in chunks {
dispatchGroup.enter()
chatService.sendPrivateMessage(chatId: chatId, content: chunk) { [weak self] result in
guard let self else {
dispatchGroup.leave()
return
}
self.messages = Self.merge(existing: self.messages, newMessages: [newMessage])
self.errorMessage = nil
completion(true)
case .failure(let error):
self.sendingErrorMessage = self.message(for: error)
completion(false)
switch result {
case .success(let data):
let newMessage = MessageItem(
messageId: data.messageId,
messageType: "text",
chatId: data.chatId,
senderId: currentUserId,
senderData: nil,
content: chunk,
mediaLink: nil,
isViewed: true,
viewedAt: nil,
createdAt: data.createdAt,
updatedAt: data.createdAt,
forwardMetadata: nil
)
self.messages = Self.merge(existing: self.messages, newMessages: [newMessage])
case .failure(let error):
self.sendingErrorMessage = self.message(for: error)
overallSuccess = false
}
dispatchGroup.leave()
}
self.isSending = false
}
dispatchGroup.notify(queue: .main) {
self.isSending = false
if overallSuccess {
self.errorMessage = nil
}
completion(overallSuccess)
}
}
private func splitMessage(_ message: String, maxLength: Int) -> [String] {
var chunks: [String] = []
var remaining = message
while !remaining.isEmpty {
let chunk = String(remaining.prefix(maxLength))
chunks.append(chunk)
remaining = String(remaining.dropFirst(maxLength))
}
return chunks
}
func refresh() {
@ -216,4 +237,4 @@ final class PrivateChatViewModel: ObservableObject {
return lhs.messageId < rhs.messageId
}
}
}

View File

@ -624,14 +624,33 @@ struct PrivateChatView: View {
.padding(.trailing, 44)
.padding(.bottom, 10)
.frame(maxWidth: .infinity, minHeight: 40, alignment: .bottomLeading)
Button(action: { }) { // переключатель на стикеры
Image(systemName: "face.smiling")
.font(.system(size: 18, weight: .semibold))
.foregroundColor(.secondary)
HStack{
if draftText.count > 2047 {
Text("\(draftText.count) / \(viewModel.maxMessageLength)")
.font(.caption2)
.fontWeight(.medium)
.foregroundColor(draftText.count > viewModel.maxMessageLength ? .red : .secondary)
}
Button(action: { }) { // переключатель на стикеры
Image(systemName: "face.smiling")
.font(.system(size: 18, weight: .semibold))
.foregroundColor(.secondary)
}
.padding(.trailing, 12)
.padding(.bottom, 10)
}
.padding(.trailing, 12)
.padding(.bottom, 10)
// if draftText.count > 300 {
// Text("\(draftText.count) / \(viewModel.maxMessageLength)")
// .font(.caption2)
// .fontWeight(.medium)
// .foregroundColor(draftText.count > viewModel.maxMessageLength ? .red : .secondary)
// .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)
// .padding(.trailing, 12)
// .padding(.top, 4)
// }
}
.frame(minHeight: 40, alignment: .bottom)
.background(Color(.secondarySystemBackground))