mirror of
https://github.com/MinimalBible/MinimalBible
synced 2025-07-12 19:25:06 -04:00
Display search result items
Still plenty of TODO items, but making great progress Make sure all the tests pass too
This commit is contained in:
@ -10,22 +10,22 @@ import org.crosswire.jsword.index.IndexManager
|
||||
* This is the entry point for handling the actual bible search. Likely will support
|
||||
* an "advanced" search in the future, but for now, basicTextSearch is what you get.
|
||||
*/
|
||||
class SearchProvider(val indexManager: IndexManager, val b: Book?) {
|
||||
class SearchProvider(val indexManager: IndexManager, val book: Book?) {
|
||||
|
||||
val defaultSearchType = SearchType.ANY_WORDS
|
||||
|
||||
[suppress("UNUSED_PARAMETER")]
|
||||
public fun basicTextSearch(text: String): List<Verse> {
|
||||
if (!isSearchAvailable()) {
|
||||
Log.w("SearchProvider", "Search unavailable, index status of ${b?.getInitials()}: ${b?.getIndexStatus()}")
|
||||
Log.w("SearchProvider", "Search unavailable, index status of ${book?.getInitials()}: ${book?.getIndexStatus()}")
|
||||
return listOf()
|
||||
}
|
||||
|
||||
val searchText = defaultSearchType decorate text
|
||||
// We already checked for null in isSearchAvailable(), but Kotlin
|
||||
// doesn't keep track of that (yet)
|
||||
val results = b!!.find(searchText)
|
||||
return results map { it as Verse }
|
||||
return book!!.find(searchText)
|
||||
.map { it as Verse }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -34,7 +34,7 @@ class SearchProvider(val indexManager: IndexManager, val b: Book?) {
|
||||
* This check MUST guarantee that the book is not null.
|
||||
*/
|
||||
public fun isSearchAvailable(): Boolean =
|
||||
b != null &&
|
||||
indexManager isIndexed b
|
||||
book != null &&
|
||||
indexManager isIndexed book
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,77 @@
|
||||
package org.bspeice.minimalbible.activity.search
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.LinearLayout
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.view.LayoutInflater
|
||||
import org.bspeice.minimalbible.R
|
||||
import org.crosswire.jsword.passage.Verse
|
||||
import android.widget.TextView
|
||||
import org.bspeice.minimalbible.service.format.osisparser.OsisParser
|
||||
import org.crosswire.jsword.book.Book
|
||||
import android.view.ViewGroup
|
||||
|
||||
/**
|
||||
* Created by bspeice on 2/26/15.
|
||||
*/
|
||||
class SearchResultsListView(val ctx: Context, val attrs: AttributeSet) : LinearLayout(ctx, attrs) {
|
||||
|
||||
val layoutManager = LinearLayoutManager(ctx)
|
||||
val inflater = ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val contentView = inflater.inflate(R.layout.view_search_results_list, this, true)
|
||||
val searchResults = contentView.findViewById(R.id.search_results) as RecyclerView;
|
||||
|
||||
{
|
||||
searchResults setLayoutManager layoutManager
|
||||
}
|
||||
|
||||
fun initialize(b: Book, resultsList: List<Verse>) {
|
||||
searchResults.setAdapter(SearchResultsAdapter(b, resultsList))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Handle clicking an item and navigating on the main screen
|
||||
class SearchResultsAdapter(val b: Book, val results: List<Verse>)
|
||||
: RecyclerView.Adapter<ResultViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ResultViewHolder? {
|
||||
val resultView = SearchResultView(parent)
|
||||
return ResultViewHolder(resultView)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ResultViewHolder?, position: Int) {
|
||||
holder?.bind(b, results[position])
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = results.size()
|
||||
}
|
||||
|
||||
/**
|
||||
* The ViewHolder object for an individual search result
|
||||
* TODO: Bold the text found in the query
|
||||
*/
|
||||
class ResultViewHolder(val view: SearchResultView) : RecyclerView.ViewHolder(view.contentView) {
|
||||
|
||||
// TODO: Need a nicer way of displaying the book name - currently is ALL CAPS
|
||||
fun buildVerseName(v: Verse) = "${v.getBook().name()} ${v.getChapter()}:${v.getVerse()}"
|
||||
|
||||
fun buildVerseContent(b: Book, v: Verse, o: OsisParser) = o.parseVerse(b, v)
|
||||
|
||||
fun bind(b: Book, verse: Verse) {
|
||||
view.verseName setText buildVerseName(verse)
|
||||
view.verseContent setText buildVerseContent(b, verse, OsisParser())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom view to wrap showing a search result
|
||||
*/
|
||||
class SearchResultView(val group: ViewGroup?) {
|
||||
val inflater = LayoutInflater.from(group?.getContext())
|
||||
val contentView = inflater.inflate(R.layout.view_search_result, group, false)
|
||||
|
||||
val verseName = contentView.findViewById(R.id.verseName) as TextView
|
||||
val verseContent = contentView.findViewById(R.id.verseContent) as TextView
|
||||
}
|
@ -13,13 +13,13 @@ import org.bspeice.minimalbible.activity.viewer.BookAdapter.ChapterInfo
|
||||
import rx.subjects.PublishSubject
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.util.TypedValue
|
||||
import org.bspeice.minimalbible.service.format.osisparser.OsisParser
|
||||
import android.util.Log
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.widget.LinearLayout
|
||||
import android.view.View
|
||||
import org.bspeice.minimalbible.service.format.osisparser.OsisParser
|
||||
|
||||
class BibleView(val ctx: Context, val attrs: AttributeSet) : LinearLayout(ctx, attrs) {
|
||||
|
||||
@ -120,7 +120,7 @@ class BookAdapter(val b: Book, val prefs: BibleViewerPreferences)
|
||||
override fun getItemCount(): Int = chapterList.size()
|
||||
|
||||
public fun bindScrollHandler(provider: PublishSubject<BookScrollEvent>,
|
||||
lM: RecyclerView.LayoutManager) {
|
||||
lM: RecyclerView.LayoutManager) {
|
||||
provider subscribe {
|
||||
val event = it
|
||||
lM scrollToPosition
|
||||
@ -145,7 +145,8 @@ class PassageView(val v: TextView, val b: Book)
|
||||
|
||||
fun getAllVerses(verses: Progression<Int>, info: ChapterInfo): SpannableStringBuilder {
|
||||
val builder = SpannableStringBuilder()
|
||||
verses.forEach { OsisParser(builder).appendVerse(b, buildOrdinal(it, info)) }
|
||||
val parser = OsisParser()
|
||||
verses.forEach { parser.appendVerse(b, buildOrdinal(it, info), builder) }
|
||||
return builder
|
||||
}
|
||||
|
||||
|
@ -16,23 +16,41 @@ import org.bspeice.minimalbible.service.format.osisparser.handler.DivineHandler
|
||||
|
||||
/**
|
||||
* Parse out the OSIS XML into whatever we want!
|
||||
* This takes in a SpannableStringBuilder to modify. Normally I'm not a fan
|
||||
* of mutability, but due to the need for absolute efficiency in this class,
|
||||
* that's what we're going with.
|
||||
* TODO: Speed up parsing. This is the single most expensive repeated operation
|
||||
*/
|
||||
class OsisParser(val builder: SpannableStringBuilder) : DefaultHandler() {
|
||||
class OsisParser() : DefaultHandler() {
|
||||
|
||||
// Don't pass a verse as part of the constructor, but still guarantee
|
||||
// that it will exist
|
||||
var verseContent: VerseContent by Delegates.notNull()
|
||||
var builder: SpannableStringBuilder by Delegates.notNull()
|
||||
|
||||
// TODO: Implement a stack to keep min API 8
|
||||
val handlerStack = ArrayDeque<TagHandler>()
|
||||
|
||||
fun appendVerse(b: Book, v: Verse): VerseContent {
|
||||
fun appendVerse(b: Book, v: Verse,
|
||||
builder: SpannableStringBuilder): VerseContent {
|
||||
verseContent = VerseContent(v)
|
||||
this.builder = builder
|
||||
BookData(b, v).getSAXEventProvider() provideSAXEvents this
|
||||
return verseContent
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a verse and return its content
|
||||
* Only good for parsing a single verse at a time,
|
||||
* but gives a cleaner API to work with (and means that
|
||||
* we can just use the default constructor)
|
||||
*/
|
||||
fun parseVerse(b: Book, v: Verse): SpannableStringBuilder {
|
||||
val mBuilder = SpannableStringBuilder()
|
||||
appendVerse(b, v, mBuilder)
|
||||
return mBuilder
|
||||
}
|
||||
|
||||
override fun startElement(uri: String, localName: String,
|
||||
qName: String, attributes: Attributes) {
|
||||
when (localName) {
|
||||
|
Reference in New Issue
Block a user