Skip to content

Commit

Permalink
Sort using Nook Phone order
Browse files Browse the repository at this point in the history
Nook Phone ignores dashes, "-", when sorting items. This commit ignores dashes when sorting by name or when searching, so that the results match the list in Nook Phone, making it easier to catalog items.

This commit also moves the list ot current items to the view model.
  • Loading branch information
otaviocc committed Oct 6, 2020
1 parent c6d1123 commit bb31378
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 49 deletions.
98 changes: 63 additions & 35 deletions ACHNBrowserUI/ACHNBrowserUI/viewModels/ItemsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,9 @@ import Combine
import Backend

class ItemsViewModel: ObservableObject {
@Published var items: [Item] = []
@Published var sortedItems: [Item] = []
@Published var searchItems: [Item] = []
@Published var searchText = ""

public let category: Backend.Category

private var itemCancellable: AnyCancellable?
private var searchCancellable: AnyCancellable?

private static var META_KEYWORD_CACHE: [String: [Item]] = [:]


// MARK: - Nested types

enum Sort: String, CaseIterable {
case name, buy, sell, set, similar, critterpedia

Expand All @@ -41,78 +32,107 @@ class ItemsViewModel: ObservableObject {
}
}
}


// MARK: - Properties

@Published var allItems: [Item] = []
@Published var sortedItems: [Item] = []
@Published var searchItems: [Item] = []
@Published var searchText = ""

var items: [Item] {
if !searchText.isEmpty {
return searchItems
} else if sort != nil {
return sortedItems
} else {
return allItems
}
}

public let category: Backend.Category

var sort: Sort? {
didSet {
guard let sort = sort else { return }
switch sort {
case .name:
let order: ComparisonResult = sort == oldValue ? .orderedAscending : .orderedDescending
sortedItems = items.sorted{ $0.localizedName.localizedCompare($1.localizedName) == order }
sortedItems = allItems
.sorted(by: removingOccurrences(of: "-", order: order))
case .buy:
let compare: (Int, Int) -> Bool = sort == oldValue ? (<) : (>)
sortedItems = items.filter{ $0.buy != nil}.sorted{ compare($0.buy!, $1.buy!) }
sortedItems = allItems.filter { $0.buy != nil}.sorted { compare($0.buy!, $1.buy!) }
case .sell:
let compare: (Int, Int) -> Bool = sort == oldValue ? (<) : (>)
sortedItems = items.filter{ $0.sell != nil}.sorted{ compare($0.sell!, $1.sell!) }
sortedItems = allItems.filter { $0.sell != nil}.sorted { compare($0.sell!, $1.sell!) }
case .set:
let compare: (String, String) -> Bool = sort == oldValue ? (<) : (>)
sortedItems = items.filter{ $0.set != nil}.sorted{ compare($0.set!, $1.set!) }
sortedItems = allItems.filter { $0.set != nil}.sorted { compare($0.set!, $1.set!) }
case .similar:
let compare: (String, String) -> Bool = sort == oldValue ? (<) : (>)
sortedItems = items.filter{ $0.tag != nil}.sorted{ compare($0.tag!, $1.tag!) }
sortedItems = allItems.filter { $0.tag != nil}.sorted { compare($0.tag!, $1.tag!) }
case .critterpedia:
let compare: (Int, Int) -> Bool = sort == oldValue ? (>) : (<)
sortedItems = items.filter{ $0.critterId != nil}
.sorted{ compare($0.critterId!, $1.critterId!) }
sortedItems = allItems
.filter { $0.critterId != nil}
.sorted{ compare($0.critterId!, $1.critterId!) }
}
}
}

public init(category: Backend.Category, items: [Item]) {

private var itemCancellable: AnyCancellable?
private var searchCancellable: AnyCancellable?
private static var META_KEYWORD_CACHE: [String: [Item]] = [:]

// MARK: - Life cycle

public init(category: Backend.Category, items allItems: [Item]) {
self.category = category
self.items = items
setupSearch()

self.allItems = allItems
setUpSearch()
}

public init(category: Backend.Category) {
self.category = category
setupSearch()
setUpSearch()

itemCancellable = Items.shared.$categories
.subscribe(on: DispatchQueue.global())
.map{ $0[category]?.sorted{ $0.localizedName.localizedCompare($1.localizedName) == .orderedAscending } ?? [] }
.receive(on: DispatchQueue.main)
.sink { [weak self] in
self?.items = $0
self?.allItems = $0
}
}

public init(meta: String) {
self.category = .other
if let items = Self.META_KEYWORD_CACHE[meta] {
self.items = items
self.allItems = items
} else {
itemCancellable = Items.shared.$categories
.subscribe(on: DispatchQueue.global())
.map{ $0.values.flatMap{ $0 }.filter({ $0.metas.contains(meta) }) }
.receive(on: DispatchQueue.main)
.sink { [weak self] items in
Self.META_KEYWORD_CACHE[meta] = items
self?.items = items
.sink { [weak self] allItems in
Self.META_KEYWORD_CACHE[meta] = allItems
self?.allItems = allItems
}
}
setupSearch()
setUpSearch()
}

// MARK: - Private

private func items(with string: String) -> [Item] {
items.filter {
allItems.filter {
$0.localizedName.lowercased().contains(string.lowercased())
}
.sorted(by: removingOccurrences(of: "-", order: .orderedAscending))
}
private func setupSearch() {

private func setUpSearch() {
searchCancellable = $searchText
.debounce(for: .milliseconds(300), scheduler: DispatchQueue.main)
.removeDuplicates()
Expand All @@ -122,4 +142,12 @@ class ItemsViewModel: ObservableObject {
self?.searchItems = $0
}
}

private func removingOccurrences(of string: String, order: ComparisonResult) -> (Item, Item) -> Bool {
{
let first = $0.localizedName.replacingOccurrences(of: string, with: " ")
let second = $1.localizedName.replacingOccurrences(of: string, with: " ")
return first.localizedCompare(second) == order
}
}
}
16 changes: 2 additions & 14 deletions ACHNBrowserUI/ACHNBrowserUI/views/items/ItemsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,6 @@ struct ItemsView: View {
}
}

var currentItems: [Item] {
get {
if !viewModel.searchText.isEmpty {
return viewModel.searchItems
} else if viewModel.sort != nil {
return viewModel.sortedItems
} else {
return viewModel.items
}
}
}

private var sortButton: some View {
Menu {
ForEach(ItemsViewModel.Sort.allCases(for: viewModel.category), id: \.self) { sort in
Expand Down Expand Up @@ -125,7 +113,7 @@ struct ItemsView: View {
if contentMode == .grid {
ScrollView {
LazyVGrid(columns: [GridItem(.adaptive(minimum: 120), spacing: 16)], spacing: 16) {
ForEach(currentItems) { item in
ForEach(viewModel.items) { item in
ItemGridItemView(item: item)
}
}
Expand All @@ -135,7 +123,7 @@ struct ItemsView: View {
} else {
List {
Section(header: SearchField(searchText: $viewModel.searchText)) {
ForEach(currentItems) { item in
ForEach(viewModel.items) { item in
NavigationLink(destination: LazyView(ItemDetailView(item: item))) {
ItemRowView(displayMode: contentMode == .listLarge ? .large : .compact,
item: item)
Expand Down

0 comments on commit bb31378

Please sign in to comment.