ios: add chat to created list (#5407)

* ios: add chat to created list

* do not include muted chats in unread tags
This commit is contained in:
Evgeny 2024-12-23 16:31:47 +00:00 committed by GitHub
parent 0160d57e58
commit ba601552d2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 60 additions and 47 deletions

View file

@ -118,7 +118,7 @@ class ChatTagsModel: ObservableObject {
newPresetTags[tag] = (newPresetTags[tag] ?? 0) + 1 newPresetTags[tag] = (newPresetTags[tag] ?? 0) + 1
} }
} }
if chat.isUnread, let tags = chat.chatInfo.chatTags { if chat.unreadTag, let tags = chat.chatInfo.chatTags {
for tag in tags { for tag in tags {
newUnreadTags[tag] = (newUnreadTags[tag] ?? 0) + 1 newUnreadTags[tag] = (newUnreadTags[tag] ?? 0) + 1
} }
@ -162,14 +162,14 @@ class ChatTagsModel: ObservableObject {
} }
func markChatTagRead(_ chat: Chat) -> Void { func markChatTagRead(_ chat: Chat) -> Void {
if chat.isUnread, let tags = chat.chatInfo.chatTags { if chat.unreadTag, let tags = chat.chatInfo.chatTags {
markChatTagRead_(chat, tags) markChatTagRead_(chat, tags)
} }
} }
func updateChatTagRead(_ chat: Chat, wasUnread: Bool) -> Void { func updateChatTagRead(_ chat: Chat, wasUnread: Bool) -> Void {
guard let tags = chat.chatInfo.chatTags else { return } guard let tags = chat.chatInfo.chatTags else { return }
let nowUnread = chat.isUnread let nowUnread = chat.unreadTag
if nowUnread && !wasUnread { if nowUnread && !wasUnread {
for tag in tags { for tag in tags {
unreadTags[tag] = (unreadTags[tag] ?? 0) + 1 unreadTags[tag] = (unreadTags[tag] ?? 0) + 1
@ -694,7 +694,7 @@ final class ChatModel: ObservableObject {
// update preview // update preview
let markedCount = chat.chatStats.unreadCount - unreadBelow let markedCount = chat.chatStats.unreadCount - unreadBelow
if markedCount > 0 { if markedCount > 0 {
let wasUnread = chat.isUnread let wasUnread = chat.unreadTag
chat.chatStats.unreadCount -= markedCount chat.chatStats.unreadCount -= markedCount
ChatTagsModel.shared.updateChatTagRead(chat, wasUnread: wasUnread) ChatTagsModel.shared.updateChatTagRead(chat, wasUnread: wasUnread)
self.decreaseUnreadCounter(user: self.currentUser!, by: markedCount) self.decreaseUnreadCounter(user: self.currentUser!, by: markedCount)
@ -709,7 +709,7 @@ final class ChatModel: ObservableObject {
func markChatUnread(_ cInfo: ChatInfo, unreadChat: Bool = true) { func markChatUnread(_ cInfo: ChatInfo, unreadChat: Bool = true) {
_updateChat(cInfo.id) { chat in _updateChat(cInfo.id) { chat in
let wasUnread = chat.isUnread let wasUnread = chat.unreadTag
chat.chatStats.unreadChat = unreadChat chat.chatStats.unreadChat = unreadChat
ChatTagsModel.shared.updateChatTagRead(chat, wasUnread: wasUnread) ChatTagsModel.shared.updateChatTagRead(chat, wasUnread: wasUnread)
} }
@ -847,7 +847,7 @@ final class ChatModel: ObservableObject {
} }
func changeUnreadCounter(_ chatIndex: Int, by count: Int) { func changeUnreadCounter(_ chatIndex: Int, by count: Int) {
let wasUnread = chats[chatIndex].isUnread let wasUnread = chats[chatIndex].unreadTag
chats[chatIndex].chatStats.unreadCount = chats[chatIndex].chatStats.unreadCount + count chats[chatIndex].chatStats.unreadCount = chats[chatIndex].chatStats.unreadCount + count
ChatTagsModel.shared.updateChatTagRead(chats[chatIndex], wasUnread: wasUnread) ChatTagsModel.shared.updateChatTagRead(chats[chatIndex], wasUnread: wasUnread)
changeUnreadCounter(user: currentUser!, by: count) changeUnreadCounter(user: currentUser!, by: count)
@ -1055,8 +1055,8 @@ final class Chat: ObservableObject, Identifiable, ChatLike {
} }
} }
var isUnread: Bool { var unreadTag: Bool {
chatStats.unreadCount > 0 || chatStats.unreadChat chatInfo.ntfsEnabled && (chatStats.unreadCount > 0 || chatStats.unreadChat)
} }
var id: ChatId { get { chatInfo.id } } var id: ChatId { get { chatInfo.id } }

View file

@ -2009,6 +2009,7 @@ func updateChatSettings(_ chat: Chat, chatSettings: ChatSettings) {
await MainActor.run { await MainActor.run {
let wasFavorite = chat.chatInfo.chatSettings?.favorite ?? false let wasFavorite = chat.chatInfo.chatSettings?.favorite ?? false
ChatTagsModel.shared.updateChatFavorite(favorite: chatSettings.favorite, wasFavorite: wasFavorite) ChatTagsModel.shared.updateChatFavorite(favorite: chatSettings.favorite, wasFavorite: wasFavorite)
let wasUnread = chat.unreadTag
switch chat.chatInfo { switch chat.chatInfo {
case var .direct(contact): case var .direct(contact):
contact.chatSettings = chatSettings contact.chatSettings = chatSettings
@ -2018,6 +2019,7 @@ func updateChatSettings(_ chat: Chat, chatSettings: ChatSettings) {
ChatModel.shared.updateGroup(groupInfo) ChatModel.shared.updateGroup(groupInfo)
default: () default: ()
} }
ChatTagsModel.shared.updateChatTagRead(chat, wasUnread: wasUnread)
} }
} catch let error { } catch let error {
logger.error("apiSetChatSettings error \(responseError(error))") logger.error("apiSetChatSettings error \(responseError(error))")

View file

@ -568,7 +568,6 @@ struct TagEditorNavParams {
struct ChatListTag: View { struct ChatListTag: View {
var chat: Chat? = nil var chat: Chat? = nil
var showEditButton: Bool = false
@Environment(\.dismiss) var dismiss: DismissAction @Environment(\.dismiss) var dismiss: DismissAction
@EnvironmentObject var theme: AppTheme @EnvironmentObject var theme: AppTheme
@EnvironmentObject var chatTagsModel: ChatTagsModel @EnvironmentObject var chatTagsModel: ChatTagsModel
@ -603,7 +602,7 @@ struct ChatListTag: View {
.contentShape(Rectangle()) .contentShape(Rectangle())
.onTapGesture { .onTapGesture {
if let c = chat { if let c = chat {
setTag(tagId: selected ? nil : tagId, chat: c) setChatTag(tagId: selected ? nil : tagId, chat: c) { dismiss() }
} else { } else {
tagEditorNavParams = TagEditorNavParams(chat: nil, chatListTag: ChatTagData(emoji: emoji, text: text), tagId: tagId) tagEditorNavParams = TagEditorNavParams(chat: nil, chatListTag: ChatTagData(emoji: emoji, text: text), tagId: tagId)
} }
@ -665,7 +664,7 @@ struct ChatListTag: View {
Label("Create list", systemImage: "plus") Label("Create list", systemImage: "plus")
} }
} header: { } header: {
if showEditButton { if chat == nil {
editTagsButton() editTagsButton()
.textCase(nil) .textCase(nil)
.frame(maxWidth: .infinity, alignment: .trailing) .frame(maxWidth: .infinity, alignment: .trailing)
@ -714,36 +713,6 @@ struct ChatListTag: View {
} }
} }
private func setTag(tagId: Int64?, chat: Chat) {
Task {
do {
let tagIds: [Int64] = if let t = tagId { [t] } else {[]}
let (userTags, chatTags) = try await apiSetChatTags(
type: chat.chatInfo.chatType,
id: chat.chatInfo.apiId,
tagIds: tagIds
)
await MainActor.run {
chatTagsModel.userTags = userTags
if var contact = chat.chatInfo.contact {
contact.chatTags = chatTags
m.updateContact(contact)
} else if var group = chat.chatInfo.groupInfo {
group.chatTags = chatTags
m.updateGroup(group)
}
dismiss()
}
} catch let error {
showAlert(
NSLocalizedString("Error saving chat list", comment: "alert title"),
message: responseError(error)
)
}
}
}
private func deleteTag(_ tagId: Int64) { private func deleteTag(_ tagId: Int64) {
Task { Task {
try await apiDeleteChatTag(tagId: tagId) try await apiDeleteChatTag(tagId: tagId)
@ -767,6 +736,37 @@ struct ChatListTag: View {
} }
} }
private func setChatTag(tagId: Int64?, chat: Chat, closeSheet: @escaping () -> Void) {
Task {
do {
let tagIds: [Int64] = if let t = tagId { [t] } else {[]}
let (userTags, chatTags) = try await apiSetChatTags(
type: chat.chatInfo.chatType,
id: chat.chatInfo.apiId,
tagIds: tagIds
)
await MainActor.run {
let m = ChatModel.shared
ChatTagsModel.shared.userTags = userTags
if var contact = chat.chatInfo.contact {
contact.chatTags = chatTags
m.updateContact(contact)
} else if var group = chat.chatInfo.groupInfo {
group.chatTags = chatTags
m.updateGroup(group)
}
closeSheet()
}
} catch let error {
showAlert(
NSLocalizedString("Error saving chat list", comment: "alert title"),
message: responseError(error)
)
}
}
}
struct EmojiPickerView: UIViewControllerRepresentable { struct EmojiPickerView: UIViewControllerRepresentable {
@Binding var selectedEmoji: String? @Binding var selectedEmoji: String?
@Binding var showingPicker: Bool @Binding var showingPicker: Bool
@ -817,11 +817,11 @@ struct EmojiPickerView: UIViewControllerRepresentable {
} }
struct ChatListTagEditor: View { struct ChatListTagEditor: View {
var chat: Chat? = nil
var tagId: Int64? = nil
@Environment(\.dismiss) var dismiss: DismissAction @Environment(\.dismiss) var dismiss: DismissAction
@EnvironmentObject var chatTagsModel: ChatTagsModel @EnvironmentObject var chatTagsModel: ChatTagsModel
@EnvironmentObject var theme: AppTheme @EnvironmentObject var theme: AppTheme
var chat: Chat? = nil
var tagId: Int64? = nil
var emoji: String? var emoji: String?
var name: String = "" var name: String = ""
@State private var newEmoji: String? @State private var newEmoji: String?
@ -860,7 +860,13 @@ struct ChatListTagEditor: View {
createChatTag() createChatTag()
} }
} label: { } label: {
Text(NSLocalizedString(tagId == nil ? "Create list" : "Save list", comment: "list editor button")) Text(
chat != nil
? "Add to list"
: tagId == nil
? "Create list"
: "Save list"
)
} }
.disabled(saving != nil || (trimmedName == name && newEmoji == emoji) || trimmedName.isEmpty || isDuplicateEmojiOrName) .disabled(saving != nil || (trimmedName == name && newEmoji == emoji) || trimmedName.isEmpty || isDuplicateEmojiOrName)
} footer: { } footer: {
@ -893,13 +899,18 @@ struct ChatListTagEditor: View {
private func createChatTag() { private func createChatTag() {
Task { Task {
do { do {
let text = trimmedName
let userTags = try await apiCreateChatTag( let userTags = try await apiCreateChatTag(
tag: ChatTagData(emoji: newEmoji , text: trimmedName) tag: ChatTagData(emoji: newEmoji , text: text)
) )
await MainActor.run { await MainActor.run {
saving = false saving = false
chatTagsModel.userTags = userTags chatTagsModel.userTags = userTags
dismiss() }
if let chat, let tag = userTags.first(where: { $0.chatTagText == text && $0.chatTagEmoji == newEmoji}) {
setChatTag(tagId: tag.chatTagId, chat: chat) { dismiss() }
} else {
await MainActor.run { dismiss() }
} }
} catch let error { } catch let error {
await MainActor.run { await MainActor.run {

View file

@ -717,7 +717,7 @@ struct ChatTagsView: View {
content: { content: {
AnyView( AnyView(
NavigationView { NavigationView {
ChatListTag(chat: nil, showEditButton: true) ChatListTag(chat: nil)
.modifier(ThemedBackground(grouped: true)) .modifier(ThemedBackground(grouped: true))
} }
) )