summaryrefslogtreecommitdiff
path: root/Sora/Views/SearchSuggestionsView.swift
blob: 244de497fdf8364d74f43481f74f5e6a5f3f1ac0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import SwiftUI

struct SearchSuggestionsView: View {
  var items: [Either<BooruTag, BooruSearchQuery>]
  @Binding var searchText: String
  private var lastSearchTag: String {
    String(searchText.split(separator: " ").last ?? "").lowercased()
  }
  private var filteredItems: [Either<BooruTag, BooruSearchQuery>] {
    guard !lastSearchTag.isEmpty else { return [] }

    var seen = Set<String>()

    return items.filter { item in
      switch item {
      case .left(let tag):
        return tag.name.lowercased().contains(lastSearchTag)
          && seen.insert(tag.name.lowercased()).inserted

      case .right(let query):
        let newTags = query.tags.filter { tag in
          tag.lowercased().contains(lastSearchTag)
            && seen.insert(tag.lowercased()).inserted
        }

        return !newTags.isEmpty
      }
    }
  }

  var body: some View {
    ForEach(filteredItems, id: \.self) { item in
      switch item {
      case .left(let tag):
        Button {
          if let range = searchText.range(of: lastSearchTag, options: .backwards) {
            searchText.replaceSubrange(range, with: tag.name)
          }
        } label: {
          Text(tag.name)
        }

      case .right(let query):
        Button {
          if let range = searchText.range(of: lastSearchTag, options: .backwards),
            let matchingTag = query.tags.first(where: { $0.lowercased().contains(lastSearchTag) })
          {
            searchText.replaceSubrange(range, with: matchingTag)
          }
        } label: {
          if let matchingTag = query.tags.first(where: { $0.lowercased().contains(lastSearchTag) })
          {
            Text(matchingTag)
          } else {
            Text(query.tags.first ?? "")
          }
        }
      }
    }
  }
}