don't filter chats on link in search, allow to paste text with link

This commit is contained in:
spaced4ndy 2023-12-04 14:29:15 +04:00
parent b11aaf161b
commit a27a70981e
3 changed files with 55 additions and 17 deletions

View File

@ -15,6 +15,7 @@ struct ChatListView: View {
@State private var searchMode = false @State private var searchMode = false
@FocusState private var searchFocussed @FocusState private var searchFocussed
@State private var searchText = "" @State private var searchText = ""
@State private var searchShowingSimplexLink = false
@State private var newChatMenuOption: NewChatMenuOption? = nil @State private var newChatMenuOption: NewChatMenuOption? = nil
@State private var userPickerVisible = false @State private var userPickerVisible = false
@State private var showConnectDesktop = false @State private var showConnectDesktop = false
@ -145,9 +146,14 @@ struct ChatListView: View {
VStack { VStack {
List { List {
if !chatModel.chats.isEmpty { if !chatModel.chats.isEmpty {
ChatListSearchBar(searchMode: $searchMode, searchFocussed: $searchFocussed, searchText: $searchText) ChatListSearchBar(
.listRowSeparator(.hidden) searchMode: $searchMode,
.frame(maxWidth: .infinity) searchFocussed: $searchFocussed,
searchText: $searchText,
searchShowingSimplexLink: $searchShowingSimplexLink
)
.listRowSeparator(.hidden)
.frame(maxWidth: .infinity)
} }
ForEach(cs, id: \.viewId) { chat in ForEach(cs, id: \.viewId) { chat in
ChatListNavLink(chat: chat) ChatListNavLink(chat: chat)
@ -221,7 +227,7 @@ struct ChatListView: View {
private func filteredChats() -> [Chat] { private func filteredChats() -> [Chat] {
let s = searchText.trimmingCharacters(in: .whitespaces).localizedLowercase let s = searchText.trimmingCharacters(in: .whitespaces).localizedLowercase
return s == "" && !showUnreadAndFavorites return (s == "" && !showUnreadAndFavorites || searchShowingSimplexLink)
? chatModel.chats ? chatModel.chats
: chatModel.chats.filter { chat in : chatModel.chats.filter { chat in
let cInfo = chat.chatInfo let cInfo = chat.chatInfo
@ -260,6 +266,7 @@ struct ChatListSearchBar: View {
@Binding var searchMode: Bool @Binding var searchMode: Bool
@FocusState.Binding var searchFocussed: Bool @FocusState.Binding var searchFocussed: Bool
@Binding var searchText: String @Binding var searchText: String
@Binding var searchShowingSimplexLink: Bool
@State private var cancelVisible = false @State private var cancelVisible = false
@State private var pasteboardHasString = false @State private var pasteboardHasString = false
@State private var showScanCodeSheet = false @State private var showScanCodeSheet = false
@ -272,11 +279,10 @@ struct ChatListSearchBar: View {
HStack(spacing: 4) { HStack(spacing: 4) {
Image(systemName: "magnifyingglass") Image(systemName: "magnifyingglass")
TextField("Search or paste SimpleX link", text: $searchText) TextField("Search or paste SimpleX link", text: $searchText)
.truncationMode(.middle)
.focused($searchFocussed) .focused($searchFocussed)
.foregroundColor(.primary) .foregroundColor(.primary)
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
if searchMode { if searchMode || searchShowingSimplexLink {
Image(systemName: "xmark.circle.fill") Image(systemName: "xmark.circle.fill")
.opacity(searchText == "" ? 0 : 1) .opacity(searchText == "" ? 0 : 1)
.onTapGesture { .onTapGesture {
@ -328,7 +334,7 @@ struct ChatListSearchBar: View {
.onChange(of: searchFocussed) { sf in .onChange(of: searchFocussed) { sf in
if sf { if sf {
withAnimation { searchMode = true } withAnimation { searchMode = true }
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
withAnimation { cancelVisible = true } withAnimation { cancelVisible = true }
} }
} else { } else {
@ -339,12 +345,16 @@ struct ChatListSearchBar: View {
} }
} }
.onChange(of: searchText) { t in .onChange(of: searchText) { t in
let link = t.trimmingCharacters(in: .whitespaces) if let link = strHasSingleSimplexLink(t.trimmingCharacters(in: .whitespaces)) { // if SimpleX link is pasted, show connection dialogue
if strIsSimplexLink(link) { // if SimpleX link is pasted, show connection dialogue
searchFocussed = false searchFocussed = false
connect(link) searchText = link.text
} else if t != "" { // if some other text is pasted, enter search mode searchShowingSimplexLink = true
searchFocussed = true connect(link.text)
} else {
if t != "" { // if some other text is pasted, enter search mode
searchFocussed = true
}
searchShowingSimplexLink = false
} }
} }
.alert(item: $alert) { a in .alert(item: $alert) { a in

View File

@ -330,9 +330,8 @@ private struct ConnectView: View {
if pastedLink == "" { if pastedLink == "" {
Button { Button {
if let str = UIPasteboard.general.string { if let str = UIPasteboard.general.string {
let link = str.trimmingCharacters(in: .whitespaces) if let link = strHasSingleSimplexLink(str.trimmingCharacters(in: .whitespaces)) {
if strIsSimplexLink(link) { pastedLink = link.text
pastedLink = link
// It would be good to hide it, but right now it is not clear how to release camera in CodeScanner // It would be good to hide it, but right now it is not clear how to release camera in CodeScanner
// https://github.com/twostraws/CodeScanner/issues/121 // https://github.com/twostraws/CodeScanner/issues/121
// No known tricks worked (changing view ID, wrapping it in another view, etc.) // No known tricks worked (changing view ID, wrapping it in another view, etc.)
@ -350,7 +349,14 @@ private struct ConnectView: View {
} }
.frame(maxWidth: .infinity, alignment: .center) .frame(maxWidth: .infinity, alignment: .center)
} else { } else {
linkTextView(pastedLink) HStack {
linkTextView(pastedLink)
Button {
pastedLink = ""
} label: {
Image(systemName: "xmark.circle")
}
}
} }
} }
@ -406,7 +412,7 @@ private struct ConnectView: View {
switch resp { switch resp {
case let .success(r): case let .success(r):
let link = r.string let link = r.string
if strIsSimplexLink(link) { if strIsSimplexLink(r.string) {
connect(link) connect(link)
} else { } else {
alert = .newChatSomeAlert(alert: .someAlert( alert = .newChatSomeAlert(alert: .someAlert(
@ -470,6 +476,19 @@ func strIsSimplexLink(_ str: String) -> Bool {
} }
} }
func strHasSingleSimplexLink(_ str: String) -> FormattedText? {
if let parsedMd = parseSimpleXMarkdown(str) {
let parsedLinks = parsedMd.filter({ $0.format?.isSimplexLink ?? false })
if parsedLinks.count == 1 {
return parsedLinks[0]
} else {
return nil
}
} else {
return nil
}
}
struct IncognitoToggle: View { struct IncognitoToggle: View {
@Binding var incognitoEnabled: Bool @Binding var incognitoEnabled: Bool
@State private var showIncognitoSheet = false @State private var showIncognitoSheet = false

View File

@ -3120,6 +3120,15 @@ public enum Format: Decodable, Equatable {
case simplexLink(linkType: SimplexLinkType, simplexUri: String, smpHosts: [String]) case simplexLink(linkType: SimplexLinkType, simplexUri: String, smpHosts: [String])
case email case email
case phone case phone
public var isSimplexLink: Bool {
get {
switch (self) {
case .simplexLink: return true
default: return false
}
}
}
} }
public enum SimplexLinkType: String, Decodable { public enum SimplexLinkType: String, Decodable {