Compare commits
3 Commits
452ccfacd6
...
7015ccd41f
| Author | SHA1 | Date | |
|---|---|---|---|
| 7015ccd41f | |||
| 9172a0b353 | |||
| da5745cad8 |
@ -2842,9 +2842,6 @@
|
|||||||
},
|
},
|
||||||
"Сообщение" : {
|
"Сообщение" : {
|
||||||
|
|
||||||
},
|
|
||||||
"Сообщение слишком длинное." : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"Сообщения будут с рожками и ножками." : {
|
"Сообщения будут с рожками и ножками." : {
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ final class PrivateChatViewModel: ObservableObject {
|
|||||||
private let chatId: String
|
private let chatId: String
|
||||||
private let currentUserId: String?
|
private let currentUserId: String?
|
||||||
private let pageSize: Int
|
private let pageSize: Int
|
||||||
private let maxMessageLength: Int = 4096
|
let maxMessageLength: Int = 4096
|
||||||
private var didLoadInitially: Bool = false
|
private var didLoadInitially: Bool = false
|
||||||
private var messageObserver: NSObjectProtocol?
|
private var messageObserver: NSObjectProtocol?
|
||||||
|
|
||||||
@ -74,11 +74,7 @@ final class PrivateChatViewModel: ObservableObject {
|
|||||||
completion(false)
|
completion(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guard trimmed.count <= maxMessageLength else {
|
|
||||||
sendingErrorMessage = NSLocalizedString("Сообщение слишком длинное.", comment: "")
|
|
||||||
completion(false)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
guard !isSending else {
|
guard !isSending else {
|
||||||
sendingErrorMessage = NSLocalizedString("Дождитесь отправки предыдущего сообщения.", comment: "")
|
sendingErrorMessage = NSLocalizedString("Дождитесь отправки предыдущего сообщения.", comment: "")
|
||||||
completion(false)
|
completion(false)
|
||||||
@ -92,8 +88,17 @@ final class PrivateChatViewModel: ObservableObject {
|
|||||||
isSending = true
|
isSending = true
|
||||||
sendingErrorMessage = nil
|
sendingErrorMessage = nil
|
||||||
|
|
||||||
chatService.sendPrivateMessage(chatId: chatId, content: trimmed) { [weak self] result in
|
let chunks = splitMessage(trimmed, maxLength: maxMessageLength)
|
||||||
guard let self else { return }
|
let dispatchGroup = DispatchGroup()
|
||||||
|
var overallSuccess = true
|
||||||
|
|
||||||
|
for chunk in chunks {
|
||||||
|
dispatchGroup.enter()
|
||||||
|
chatService.sendPrivateMessage(chatId: chatId, content: chunk) { [weak self] result in
|
||||||
|
guard let self else {
|
||||||
|
dispatchGroup.leave()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let data):
|
case .success(let data):
|
||||||
@ -103,7 +108,7 @@ final class PrivateChatViewModel: ObservableObject {
|
|||||||
chatId: data.chatId,
|
chatId: data.chatId,
|
||||||
senderId: currentUserId,
|
senderId: currentUserId,
|
||||||
senderData: nil,
|
senderData: nil,
|
||||||
content: trimmed,
|
content: chunk,
|
||||||
mediaLink: nil,
|
mediaLink: nil,
|
||||||
isViewed: true,
|
isViewed: true,
|
||||||
viewedAt: nil,
|
viewedAt: nil,
|
||||||
@ -111,17 +116,33 @@ final class PrivateChatViewModel: ObservableObject {
|
|||||||
updatedAt: data.createdAt,
|
updatedAt: data.createdAt,
|
||||||
forwardMetadata: nil
|
forwardMetadata: nil
|
||||||
)
|
)
|
||||||
|
|
||||||
self.messages = Self.merge(existing: self.messages, newMessages: [newMessage])
|
self.messages = Self.merge(existing: self.messages, newMessages: [newMessage])
|
||||||
self.errorMessage = nil
|
|
||||||
completion(true)
|
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
self.sendingErrorMessage = self.message(for: error)
|
self.sendingErrorMessage = self.message(for: error)
|
||||||
completion(false)
|
overallSuccess = false
|
||||||
|
}
|
||||||
|
dispatchGroup.leave()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispatchGroup.notify(queue: .main) {
|
||||||
self.isSending = false
|
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() {
|
func refresh() {
|
||||||
|
|||||||
@ -625,6 +625,14 @@ struct PrivateChatView: View {
|
|||||||
.padding(.bottom, 10)
|
.padding(.bottom, 10)
|
||||||
.frame(maxWidth: .infinity, minHeight: 40, alignment: .bottomLeading)
|
.frame(maxWidth: .infinity, minHeight: 40, alignment: .bottomLeading)
|
||||||
|
|
||||||
|
HStack{
|
||||||
|
if draftText.count > 2047 {
|
||||||
|
Text("\(draftText.count) / \(viewModel.maxMessageLength)")
|
||||||
|
.font(.caption2)
|
||||||
|
.fontWeight(.medium)
|
||||||
|
.foregroundColor(draftText.count > viewModel.maxMessageLength ? .red : .secondary)
|
||||||
|
}
|
||||||
|
|
||||||
Button(action: { }) { // переключатель на стикеры
|
Button(action: { }) { // переключатель на стикеры
|
||||||
Image(systemName: "face.smiling")
|
Image(systemName: "face.smiling")
|
||||||
.font(.system(size: 18, weight: .semibold))
|
.font(.system(size: 18, weight: .semibold))
|
||||||
@ -633,6 +641,17 @@ struct PrivateChatView: View {
|
|||||||
.padding(.trailing, 12)
|
.padding(.trailing, 12)
|
||||||
.padding(.bottom, 10)
|
.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)
|
.frame(minHeight: 40, alignment: .bottom)
|
||||||
.background(Color(.secondarySystemBackground))
|
.background(Color(.secondarySystemBackground))
|
||||||
.clipShape(RoundedRectangle(cornerRadius: 18, style: .continuous))
|
.clipShape(RoundedRectangle(cornerRadius: 18, style: .continuous))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user