Skip to content

Commit

Permalink
Merge pull request EventFahrplan#681 from EventFahrplan/search-functi…
Browse files Browse the repository at this point in the history
…onality

Add search functionality.
  • Loading branch information
johnjohndoe authored Nov 3, 2024
2 parents 2cbec1b + 404b905 commit eadc1e7
Show file tree
Hide file tree
Showing 34 changed files with 1,682 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Please read the instructions in the [contribution guide](CONTRIBUTING.md) in ord
* View program by day and rooms (side by side)
* Custom grid layout for smartphones (**try landscape mode**) and tablets
* Read detailed descriptions (speaker names, start time, room name, links, ...) of events
* Search through all events
* Add events to favorites list
* Export favorites list
* Setup alarms for individual events
Expand Down
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ dependencies {

implementation Compose.material

implementation Libs.activityCompose
implementation Libs.appCompat
implementation Libs.betterLinkMovementMethod
implementation Libs.constraintLayout
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,12 @@
android:label="@string/schedule_statistic_title"
android:resizeableActivity="true" >
</activity>
<activity
android:name="nerd.tuxmobil.fahrplan.congress.search.SearchActivity"
android:theme="@style/Theme.Congress.NoActionBar"
android:parentActivityName="nerd.tuxmobil.fahrplan.congress.schedule.MainActivity"
android:label="@string/search_title"
android:resizeableActivity="true" >
</activity>
</application>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class RealSharedPreferencesRepository(val context: Context) : SharedPreferencesR
const val ENGELSYSTEM_SHIFTS_HASH_KEY = "nerd.tuxmobil.fahrplan.congress.Prefs.ENGELSYSTEM_SHIFTS_HASH"
const val SCHEDULE_LAST_FETCHED_AT_KEY = "nerd.tuxmobil.fahrplan.congress.Prefs.SCHEDULE_LAST_FETCHED_AT"
const val SELECTED_SESSION_ID_KEY = "nerd.tuxmobil.fahrplan.congress.Prefs.SELECTED_SESSION_ID_KEY"
const val SEARCH_HISTORY_KEY = "nerd.tuxmobil.fahrplan.congress.Prefs.SEARCH_HISTORY_KEY"
const val SEARCH_HISTORY_SEPARATOR = ";"

}

Expand Down Expand Up @@ -121,4 +123,15 @@ class RealSharedPreferencesRepository(val context: Context) : SharedPreferencesR
.putString(SELECTED_SESSION_ID_KEY, sessionId)
.commit()

override fun getSearchHistory(): List<String> {
return preferences.getString(SEARCH_HISTORY_KEY, "")!!
.split(SEARCH_HISTORY_SEPARATOR)
}

override fun setSearchHistory(history: List<String>) {
preferences.edit {
putString(SEARCH_HISTORY_KEY, history.joinToString(SEARCH_HISTORY_SEPARATOR))
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,7 @@ interface SharedPreferencesRepository {
fun getSelectedSessionId(): String
fun setSelectedSessionId(sessionId: String): Boolean

fun getSearchHistory(): List<String>
fun setSearchHistory(history: List<String>)

}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import nerd.tuxmobil.fahrplan.congress.repositories.LoadScheduleState.ParseSucce
import nerd.tuxmobil.fahrplan.congress.repositories.LoadScheduleState.Parsing
import nerd.tuxmobil.fahrplan.congress.schedule.Conference
import nerd.tuxmobil.fahrplan.congress.schedule.FahrplanViewModel
import nerd.tuxmobil.fahrplan.congress.search.SearchRepository
import nerd.tuxmobil.fahrplan.congress.serialization.ScheduleChanges.Companion.computeSessionsWithChangeFlags
import nerd.tuxmobil.fahrplan.congress.utils.AlarmToneConversion
import nerd.tuxmobil.fahrplan.congress.validation.MetaValidation.validate
Expand All @@ -82,7 +83,7 @@ import info.metadude.android.eventfahrplan.network.models.Meta as MetaNetworkMod
import nerd.tuxmobil.fahrplan.congress.models.Meta as MetaAppModel
import nerd.tuxmobil.fahrplan.congress.models.Session as SessionAppModel

object AppRepository {
object AppRepository : SearchRepository {

/**
* Name used as the display title for the Engelsystem column and
Expand Down Expand Up @@ -320,6 +321,27 @@ object AppRepository {
.flowOn(executionContext.database)
}

private val refreshSearchHistorySignal = MutableSharedFlow<Unit>()

private fun refreshSearchHistory() {
logging.d(LOG_TAG, "Refreshing search history ...")
val requestIdentifier = "refreshSearchHistory"
parentJobs[requestIdentifier] = databaseScope.launchNamed(requestIdentifier) {
refreshSearchHistorySignal.emit(Unit)
}
}

/**
* Emits the search history from the database.
*/
@OptIn(ExperimentalCoroutinesApi::class)
override val searchHistory: Flow<List<String>> by lazy {
refreshSearchHistorySignal
.onStart { emit(Unit) }
.mapLatest { readSearchHistory() }
.flowOn(executionContext.database)
}

fun initialize(
context: Context,
logging: Logging,
Expand Down Expand Up @@ -936,4 +958,13 @@ object AppRepository {
fun readInsistentAlarmsEnabled() =
sharedPreferencesRepository.isInsistentAlarmsEnabled()

private fun readSearchHistory(): List<String> {
return sharedPreferencesRepository.getSearchHistory()
}

override fun updateSearchHistory(history: List<String>) {
sharedPreferencesRepository.setSearchHistory(history)
refreshSearchHistory()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ import nerd.tuxmobil.fahrplan.congress.reporting.TraceDroidEmailSender
import nerd.tuxmobil.fahrplan.congress.repositories.AppRepository
import nerd.tuxmobil.fahrplan.congress.schedule.FahrplanFragment.OnSessionClickListener
import nerd.tuxmobil.fahrplan.congress.schedule.observables.LoadScheduleUiState
import nerd.tuxmobil.fahrplan.congress.search.SearchActivity
import nerd.tuxmobil.fahrplan.congress.search.SearchFragment
import nerd.tuxmobil.fahrplan.congress.settings.SettingsActivity
import nerd.tuxmobil.fahrplan.congress.sidepane.OnSidePaneCloseListener
import nerd.tuxmobil.fahrplan.congress.utils.ConfirmationDialog.OnConfirmationDialogClicked
Expand Down Expand Up @@ -109,6 +111,7 @@ class MainActivity : BaseActivity(),
private var isScreenLocked = false
private var isAlarmsInSidePane = false
private var isFavoritesInSidePane = false
private var isSearchInSidePane = false
private var shouldScrollToCurrent = true

override fun onAttachedToWindow() {
Expand Down Expand Up @@ -258,6 +261,7 @@ class MainActivity : BaseActivity(),
R.id.menu_item_about -> viewModel.showAboutDialog()
R.id.menu_item_alarms -> openAlarms()
R.id.menu_item_settings -> SettingsActivity.startForResult(this)
R.id.menu_item_search -> openSearch()
R.id.menu_item_schedule_changes -> openSessionChanges()
R.id.menu_item_favorites -> openFavorites()
else -> return false
Expand All @@ -284,6 +288,9 @@ class MainActivity : BaseActivity(),
if (fragmentTag == StarredListFragment.FRAGMENT_TAG) {
isFavoritesInSidePane = false
}
if (fragmentTag == SearchFragment.FRAGMENT_TAG) {
isSearchInSidePane = false
}
removeFragment(fragmentTag)
}

Expand Down Expand Up @@ -363,7 +370,8 @@ class MainActivity : BaseActivity(),
findViewById<View>(detailView)?.let { view ->
isAlarmsInSidePane = hasFragment && fragment is AlarmsFragment
isFavoritesInSidePane = hasFragment && fragment is StarredListFragment
view.isVisible = (!isAlarmsInSidePane || !isFavoritesInSidePane || !isScreenLocked) && hasFragment
isSearchInSidePane = hasFragment && fragment is SearchFragment
view.isVisible = (!isAlarmsInSidePane || !isFavoritesInSidePane || !isScreenLocked || !isSearchInSidePane) && hasFragment
}
}

Expand Down Expand Up @@ -399,6 +407,17 @@ class MainActivity : BaseActivity(),
}
}

private fun openSearch() {
val sidePaneView = findViewById<FragmentContainerView>(R.id.detail)
if (sidePaneView == null) {
SearchActivity.start(this)
} else {
sidePaneView.isVisible = true
isSearchInSidePane = true
SearchFragment.replaceAtBackStack(supportFragmentManager, R.id.detail, true)
}
}

override fun onAccepted(requestCode: Int) {
if (requestCode == StarredListFragment.DELETE_ALL_FAVORITES_REQUEST_CODE) {
findFragment(StarredListFragment.FRAGMENT_TAG)?.let {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package nerd.tuxmobil.fahrplan.congress.search

import android.content.Context
import android.content.Intent
import android.os.Bundle
import nerd.tuxmobil.fahrplan.congress.R
import nerd.tuxmobil.fahrplan.congress.base.AbstractListFragment.OnSessionListClick
import nerd.tuxmobil.fahrplan.congress.base.BaseActivity
import nerd.tuxmobil.fahrplan.congress.details.SessionDetailsActivity
import nerd.tuxmobil.fahrplan.congress.repositories.AppRepository

class SearchActivity :
BaseActivity(),
OnSessionListClick {

companion object {
fun start(context: Context) {
val intent = Intent(context, SearchActivity::class.java)
context.startActivity(intent)
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search)
if (savedInstanceState == null) {
addFragment(R.id.container, SearchFragment(), SearchFragment.FRAGMENT_TAG)
}
}

override fun onSessionListClick(sessionId: String) {
if (AppRepository.updateSelectedSessionId(sessionId)) {
SessionDetailsActivity.start(this)
}
}

}
Loading

0 comments on commit eadc1e7

Please sign in to comment.