diff --git a/src/main/java/com/projecturanus/betterp2p/client/gui/InfoFilter.kt b/src/main/java/com/projecturanus/betterp2p/client/gui/InfoFilter.kt new file mode 100644 index 0000000..88302c9 --- /dev/null +++ b/src/main/java/com/projecturanus/betterp2p/client/gui/InfoFilter.kt @@ -0,0 +1,74 @@ +package com.projecturanus.betterp2p.client.gui + +/** + * Extend the default filtering. Holds information about the search filter. + * + * There are 3 modes of filtering: + * - By input/output: Using `@in/@out` filters by input/output respectively. + * - By bound/unbound: Use `@b` or `@u` filters by input/output respectively. + * - By name: Use the name + * If someone comes and says "sort by freq pls" then we can add it at that time + */ +class InfoFilter { + + /** + * Active filters to use when filtering entries. + */ + val activeFilters: MutableMap?> = mutableMapOf() + + /** + * Parse the query string for filters and update the active + * filter list. + */ + fun updateFilter(query: String) { + val tokens = query.split("\\s+".toRegex()) // split by whitespace + activeFilters.clear() + tokens.forEach { + when { + it.matches(Filter.INPUT.pattern) -> { + activeFilters.putIfAbsent(Filter.INPUT, null) + } + it.matches(Filter.OUTPUT.pattern) -> { + activeFilters.putIfAbsent(Filter.OUTPUT, null) + } + it.matches(Filter.BOUND.pattern) -> { + activeFilters.putIfAbsent(Filter.BOUND, null) + } + it.matches(Filter.UNBOUND.pattern) -> { + activeFilters.putIfAbsent(Filter.UNBOUND, null) + } + else -> { + activeFilters.putIfAbsent(Filter.NAME, mutableListOf()) + activeFilters[Filter.NAME]!!.add(it) + } + } + } + } +} + +/** + * The different filter types. Probably will let these be adjustable in the + * config. + */ +enum class Filter(val pattern: Regex, val filter: (InfoWrapper, List?) -> Boolean) { + INPUT("\\A@in\\z".toRegex(), { it, _ -> !it.output }), + OUTPUT("\\A@out\\z".toRegex(), { it, _ -> it.output }), + BOUND("\\A@b\\z".toRegex(), { it, _ -> it.frequency != 0L }), + UNBOUND("\\A@u\\z".toRegex(), { it, _ -> it.frequency == 0L || it.error }), + NAME("\"?.+\"?".toRegex(), filter@{ it, strs -> + val name = it.name.lowercase() + for (f in strs!!) { + // Ppl better not troll and use double quotes in their P2P tunnel names + val query = f.removeSurrounding("\"") + if (name.contains(query)) { + return@filter true + } + } + false + }); + +} + +//fun parseQuery(search: String): InfoFilter { +// +//} diff --git a/src/main/java/com/projecturanus/betterp2p/client/gui/InfoList.kt b/src/main/java/com/projecturanus/betterp2p/client/gui/InfoList.kt index 2f60e06..cae8a91 100644 --- a/src/main/java/com/projecturanus/betterp2p/client/gui/InfoList.kt +++ b/src/main/java/com/projecturanus/betterp2p/client/gui/InfoList.kt @@ -31,6 +31,8 @@ class InfoList (initList: Collection, */ var filtered: List = listOf() + private val filter: InfoFilter = InfoFilter() + /** * Binding to the search string in the text box */ @@ -69,12 +71,24 @@ class InfoList (initList: Collection, * Updates the filtered list. */ fun refilter() { + filter.updateFilter(searchStr.lowercase()) filtered = sorted.filter { - it.frequency.toHexString().contains(searchStr.uppercase()) || - it.frequency.toHexString().format4().contains(searchStr.uppercase()) || - it.name.lowercase().contains(searchStr.lowercase()) || - it.code == selectedEntry + if (it.code == selectedEntry) { + return@filter true + } + for ((f, strs) in filter.activeFilters) { + if(!f.filter(it, strs?.toList())) { + return@filter false + } + } + true } +// filtered = sorted.filter { +// it.frequency.toHexString().contains(searchStr.uppercase()) || +// it.frequency.toHexString().format4().contains(searchStr.uppercase()) || +// it.name.lowercase().contains(searchStr.lowercase()) || +// it.code == selectedEntry +// } } /**