updates to sheet

This commit is contained in:
Diogo
2024-12-12 11:15:18 +00:00
parent 0c007f8db0
commit 11cb2d866f
2 changed files with 117 additions and 109 deletions
@@ -46,6 +46,7 @@ struct ChatListNavLink: View {
@Environment(\.dynamicTypeSize) private var userFont: DynamicTypeSize
@AppStorage(GROUP_DEFAULT_ONE_HAND_UI, store: groupDefaults) private var oneHandUI = false
@ObservedObject var chat: Chat
@Binding var parentSheet: SomeSheet<AnyView>?
@State private var showContactRequestDialog = false
@State private var showJoinGroupDialog = false
@State private var showContactConnectionInfo = false
@@ -122,7 +123,6 @@ struct ChatListNavLink: View {
markReadButton()
toggleFavoriteButton()
toggleNtfsButton(chat: chat)
tagChatButton(chat)
}
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
if !chat.chatItems.isEmpty {
@@ -141,7 +141,7 @@ struct ChatListNavLink: View {
deleteLabel
}
.tint(.red)
untagChatButton(chat)
tagChatButton(chat)
}
.frame(height: dynamicRowHeight)
}
@@ -193,6 +193,7 @@ struct ChatListNavLink: View {
if groupInfo.canDelete {
deleteGroupChatButton(groupInfo)
}
tagChatButton(chat)
}
default:
NavLinkPlain(
@@ -215,7 +216,14 @@ struct ChatListNavLink: View {
leaveGroupChatButton(groupInfo)
}
if groupInfo.canDelete {
deleteGroupChatButton(groupInfo)
if !groupInfo.membership.memberCurrent {
deleteGroupChatButton(groupInfo)
tagChatButton(chat)
} else {
// TODO: Show ...
}
} else {
tagChatButton(chat)
}
}
}
@@ -311,37 +319,22 @@ struct ChatListNavLink: View {
private func tagChatButton(_ chat: Chat) -> some View {
Button {
sheet = SomeSheet(
parentSheet = SomeSheet(
content: {
AnyView(
ChatListTag(chat: chat)
NavigationView {
ChatListTag(chat: chat)
}
)
},
id: "tag sheet",
id: "lists sheet",
fraction: 0.7
)
} label: {
SwipeLabel(NSLocalizedString("Tag", comment: "swipe action"), systemImage: "tag.fill", inverted: oneHandUI)
SwipeLabel(NSLocalizedString("Lists", comment: "swipe action"), systemImage: "tag.fill", inverted: oneHandUI)
}
.tint(Color.indigo)
}
private func untagChatButton(_ chat: Chat) -> some View {
Button {
sheet = SomeSheet(
content: {
AnyView(
ChatListTag(chat: chat, untag: true)
)
},
id: "tag sheet",
fraction: 0.7
)
} label: {
SwipeLabel(NSLocalizedString("Untag", comment: "swipe action"), systemImage: "tag.fill", inverted: oneHandUI)
}
.tint(Color.yellow.opacity(0.8))
}
private func clearNoteFolderButton() -> some View {
Button {
@@ -522,99 +515,50 @@ struct ChatListNavLink: View {
struct ChatListTag: View {
var chat: Chat
var untag: Bool = false
@EnvironmentObject var chatTagsModel: ChatTagsModel
@EnvironmentObject var m: ChatModel
@State private var emoji: String = ""
@State private var name: String = ""
var chatTagsIds: [Int64] { chat.chatInfo.contact?.chatTags ?? chat.chatInfo.groupInfo?.chatTags ?? [] }
var body: some View {
List {
if untag {
untagView()
} else {
tagView()
}
}
}
@ViewBuilder private func tagView() -> some View {
Section {
TextField("Emoji..", text: $emoji)
TextField("Tag name...", text: $name)
Button {
createChatTag()
NavigationLink {
CreateChatListTag(chat: chat)
} label: {
Text("Create tag")
Label("Create list", systemImage: "plus")
}
}
let tagsToPick = chatTagsModel.tags.compactMap { tag in
if case let .chatTag(emoji, text, tagId) = tag, !chatTagsIds.contains(tagId) {
return (emoji, text, tagId)
} else {
return nil
}
}
if !tagsToPick.isEmpty {
Section {
ForEach(tagsToPick, id: \.0) { tag in
let (emoji, text, tagId) = tag
Button {
tagChat(tagId)
} label: {
Text("\(emoji) \(text)")
if !chatTagsModel.tags.isEmpty {
ForEach(chatTagsModel.tags) { tag in
if case let .chatTag(emoji, text, tagId) = tag {
let selected = chatTagsIds.contains(tagId)
HStack {
Text(emoji)
Text(text)
.padding(.leading, 12)
Spacer()
radioButton(selected: selected)
}
.onTapGesture {
if selected {
untagChat(tagId)
} else {
tagChat(tagId)
}
}
} else {
EmptyView()
}
}
} header: {
Text("Choose existing")
}
}
}
@ViewBuilder private func untagView() -> some View {
Section {
ForEach(chatTagsModel.tags) { tag in
if case let .chatTag(emoji, text, tagId) = tag, chatTagsIds.contains(tagId) {
Button {
untagChat(tagId)
} label: {
Text("\(emoji) \(text)")
}
} else {
EmptyView()
}
}
} header: {
Text("Choose existing")
}
}
private func createChatTag() {
Task {
do {
let (userTags, chatTags) = try await apiCreateChatTag(
type: chat.chatInfo.chatType,
id: chat.chatInfo.apiId,
tag: ChatTagData(emoji: emoji, text: name)
)
await MainActor.run {
chatTagsModel.tags = userTags.map {
.chatTag(emoji: $0.chatTagEmoji, text: $0.chatTagText, tagId: $0.chatTagId)
}
updateChatTags(chat: chat, chatTags: chatTags)
}
} catch let error {
showAlert(
NSLocalizedString("Error creating tag", comment: "alert title"),
message: responseError(error)
)
}
}
@ViewBuilder private func radioButton(selected: Bool) -> some View {
Image(systemName: selected ? "checkmark.circle.fill" : "circle")
.imageScale(.large)
.foregroundStyle(selected ? Color.accentColor : Color(.tertiaryLabel))
}
private func tagChat(_ tagId: Int64) {
@@ -634,7 +578,7 @@ struct ChatListTag: View {
}
} catch let error {
showAlert(
NSLocalizedString("Error tagging chat", comment: "alert title"),
NSLocalizedString("Error adding chat to list", comment: "alert title"),
message: responseError(error)
)
}
@@ -658,7 +602,7 @@ struct ChatListTag: View {
}
} catch let error {
showAlert(
NSLocalizedString("Error untagging chat", comment: "alert title"),
NSLocalizedString("Error removing chat from list", comment: "alert title"),
message: responseError(error)
)
}
@@ -677,6 +621,58 @@ struct ChatListTag: View {
}
}
struct CreateChatListTag: View {
var chat: Chat
@Environment(\.presentationMode) var presentationMode
@EnvironmentObject var chatTagsModel: ChatTagsModel
@EnvironmentObject var m: ChatModel
@State private var emoji: String = ""
@State private var name: String = ""
var body: some View {
List {
TextField("Emoji..", text: $emoji)
TextField("List name...", text: $name)
Button {
createChatTag()
} label: {
Text("Create list")
}
}
}
private func createChatTag() {
Task {
do {
let (userTags, chatTags) = try await apiCreateChatTag(
type: chat.chatInfo.chatType,
id: chat.chatInfo.apiId,
tag: ChatTagData(emoji: emoji, text: name)
)
await MainActor.run {
chatTagsModel.tags = userTags.map {
.chatTag(emoji: $0.chatTagEmoji, text: $0.chatTagText, tagId: $0.chatTagId)
}
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)
}
presentationMode.wrappedValue.dismiss()
}
} catch let error {
showAlert(
NSLocalizedString("Error creating list", comment: "alert title"),
message: responseError(error)
)
}
}
}
}
func rejectContactRequestAlert(_ contactRequest: UserContactRequest) -> Alert {
Alert(
title: Text("Reject contact request"),
@@ -778,15 +774,15 @@ struct ChatListNavLink_Previews: PreviewProvider {
ChatListNavLink(chat: Chat(
chatInfo: ChatInfo.sampleData.direct,
chatItems: [ChatItem.getSample(1, .directSnd, .now, "hello")]
))
), parentSheet: .constant(nil))
ChatListNavLink(chat: Chat(
chatInfo: ChatInfo.sampleData.direct,
chatItems: [ChatItem.getSample(1, .directSnd, .now, "hello")]
))
), parentSheet: .constant(nil))
ChatListNavLink(chat: Chat(
chatInfo: ChatInfo.sampleData.contactRequest,
chatItems: []
))
), parentSheet: .constant(nil))
}
.previewLayout(.fixed(width: 360, height: 82))
}
@@ -117,6 +117,7 @@ struct ChatListView: View {
@State private var searchChatFilteredBySimplexLink: String? = nil
@State private var scrollToSearchBar = false
@State private var userPickerShown: Bool = false
@State private var sheet: SomeSheet<AnyView>? = nil
@StateObject private var chatTagsModel = ChatTagsModel.shared
@AppStorage(DEFAULT_SHOW_UNREAD_AND_FAVORITES) private var showUnreadAndFavorites = false
@@ -163,6 +164,17 @@ struct ChatListView: View {
}
}
}
.sheet(item: $sheet) {
if #available(iOS 16.0, *) {
$0.content
.presentationDetents([.fraction($0.fraction)])
.environmentObject(chatTagsModel)
} else {
$0.content
.environmentObject(chatTagsModel)
}
}
}
private var chatListView: some View {
@@ -308,7 +320,7 @@ struct ChatListView: View {
}
if #available(iOS 16.0, *) {
ForEach(cs, id: \.viewId) { chat in
ChatListNavLink(chat: chat)
ChatListNavLink(chat: chat, parentSheet: $sheet)
.scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center)
.padding(.trailing, -16)
.disabled(chatModel.chatRunning != true || chatModel.deletedChats.contains(chat.chatInfo.id))
@@ -320,7 +332,7 @@ struct ChatListView: View {
VStack(spacing: .zero) {
Divider()
.padding(.leading, 16)
ChatListNavLink(chat: chat)
ChatListNavLink(chat: chat, parentSheet: $sheet)
.padding(.horizontal, 8)
.padding(.vertical, 6)
}