Author: Adam Pioterek <adam.pioterek@protonmail.ch>
new search bar
%!v(PANIC=String method: strings: negative Repeat count)
diff --git a/app/build.gradle b/app/build.gradle index 04479a25f93c37a117a1a81152f7fbeafe6eb9b5..ac5d2cf405e6b9b958c6d687dbc214b60c501e61 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,17 +29,21 @@ exclude group: 'com.android.support', module: 'support-annotations' }) implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.cardview:cardview:1.0.0' - implementation 'com.google.android.material:material:1.1.0-alpha01' implementation 'androidx.vectordrawable:vectordrawable:1.0.1' implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2' + + implementation 'com.google.android.material:material:1.1.0-alpha01' + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'com.github.arimorty:floatingsearchview:2.1.1' - implementation 'com.google.code.gson:gson:2.8.2' - implementation 'com.squareup.okhttp3:okhttp:3.10.0' - implementation 'io.requery:sqlite-android:3.22.0' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.27.0-eap13' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:0.27.0-eap13' + testImplementation 'junit:junit:4.12' + + implementation 'io.requery:sqlite-android:3.22.0' + implementation 'com.google.code.gson:gson:2.8.2' + implementation 'com.squareup.okhttp3:okhttp:3.10.0' + implementation 'com.github.mancj:MaterialSearchBar:0.8.1' } repositories { maven { url "https://maven.google.com" } diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt index 4ea2d18684dbc87c372054090c654a2fc0155d69..3ea37db9c54afed9b83800a02ac5a1306d965836 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt @@ -5,8 +5,9 @@ import android.app.Activity import android.content.* import android.os.* import android.preference.PreferenceManager.getDefaultSharedPreferences +import android.text.Editable import androidx.appcompat.app.* -import android.text.Html +import android.text.TextWatcher import android.view.* import android.view.inputmethod.InputMethodManager import kotlin.collections.ArrayList @@ -21,14 +22,14 @@ import ml.adamsprogs.bimba.models.suggestions.* import ml.adamsprogs.bimba.models.adapters.* import ml.adamsprogs.bimba.collections.* -import com.arlib.floatingsearchview.FloatingSearchView -import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion import com.google.android.material.navigation.NavigationView import com.google.android.material.snackbar.Snackbar +import com.mancj.materialsearchbar.MaterialSearchBar +import com.mancj.materialsearchbar.MaterialSearchBar.BUTTON_BACK +import com.mancj.materialsearchbar.MaterialSearchBar.BUTTON_NAVIGATION -//todo<p:1> searchView integration class DashActivity : AppCompatActivity(), MessageReceiver.OnTimetableDownloadListener, - FavouritesAdapter.OnMenuItemClickListener, FavouritesAdapter.ViewHolder.OnClickListener, ProviderProxy.OnDeparturesReadyListener { + FavouritesAdapter.OnMenuItemClickListener, FavouritesAdapter.ViewHolder.OnClickListener, ProviderProxy.OnDeparturesReadyListener, SuggestionsAdapter.OnSuggestionClickListener { val context: Context = this private val receiver = MessageReceiver.getMessageReceiver() @@ -37,13 +38,14 @@ private var suggestions: List? = null private lateinit var drawerLayout: androidx.drawerlayout.widget.DrawerLayout private lateinit var drawerView: NavigationView lateinit var favouritesList: androidx.recyclerview.widget.RecyclerView - lateinit var searchView: FloatingSearchView + lateinit var searchView: MaterialSearchBar private lateinit var favourites: FavouriteStorage private lateinit var adapter: FavouritesAdapter private val actionModeCallback = ActionModeCallback() private var actionMode: ActionMode? = null private var isWarned = false private lateinit var providerProxy: ProviderProxy + private lateinit var suggestionsAdapter: SuggestionsAdapter companion object { const val REQUEST_EDIT_FAVOURITE = 1 @@ -89,63 +91,76 @@ showValidityInDrawer() searchView = search_view + searchView.setCardViewElevation(8) + suggestionsAdapter = SuggestionsAdapter(layoutInflater, this, this) + searchView.setCustomSuggestionAdapter(suggestionsAdapter) - searchView.setOnFocusChangeListener(object : FloatingSearchView.OnFocusChangeListener { - override fun onFocus() { - favouritesList.visibility = View.GONE - providerProxy.getSuggestions(searchView.query) { - searchView.swapSuggestions(it) + searchView.addTextChangeListener(object : TextWatcher { + override fun afterTextChanged(s: Editable?) { + if (searchView.isSearchEnabled) { + searchView.clearSuggestions() + searchView.updateLastSuggestions(listOf<GtfsSuggestion>()) + providerProxy.getSuggestions(s.toString()) { suggestions -> + suggestions.forEach { + if (it.name.contains(s as CharSequence, true)) { + suggestionsAdapter.addSuggestion(it) + } + } + searchView.showSuggestionsList() + } } } - override fun onFocusCleared() { - favouritesList.visibility = View.VISIBLE + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + } + }) - searchView.setOnQueryChangeListener { oldQuery, newQuery -> - if (oldQuery != "" && newQuery == "") - searchView.clearSuggestions() - providerProxy.getSuggestions(newQuery) { - searchView.swapSuggestions(it) + searchView.setOnSearchActionListener(object : MaterialSearchBar.OnSearchActionListener { + override fun onButtonClicked(buttonCode: Int) { + when (buttonCode) { + BUTTON_NAVIGATION -> { + if (drawerLayout.isDrawerOpen(drawerView)) + drawerLayout.closeDrawer(drawerView) + else + drawerLayout.openDrawer(drawerView) + } + BUTTON_BACK -> { + searchView.disableSearch() + } + } } - } - searchView.setOnSearchListener(object : FloatingSearchView.OnSearchListener { - override fun onSuggestionClicked(searchSuggestion: SearchSuggestion) { - val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager - var view = (context as DashActivity).currentFocus - if (view == null) { - view = View(context) - } - imm.hideSoftInputFromWindow(view.windowToken, 0) - if (searchSuggestion is StopSuggestion) { - val intent = Intent(context, StopSpecifyActivity::class.java) - intent.putExtra(StopSpecifyActivity.EXTRA_STOP_NAME, searchSuggestion.name) - startActivity(intent) - } else if (searchSuggestion is LineSuggestion) { - val intent = Intent(context, LineSpecifyActivity::class.java) - intent.putExtra(LineSpecifyActivity.EXTRA_LINE_ID, searchSuggestion.name) - startActivity(intent) - } + override fun onSearchStateChanged(enabled: Boolean) { } - override fun onSearchAction(query: String) { + override fun onSearchConfirmed(text: CharSequence?) { + // todo re-search + println("OnSearchConfirmed") } + }) + } - searchView.setOnBindSuggestionCallback { _, iconView, textView, item, _ -> - val suggestion = item as GtfsSuggestion - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - textView.text = Html.fromHtml(item.body, Html.FROM_HTML_MODE_LEGACY) - } else { - @Suppress("DEPRECATION") - textView.text = Html.fromHtml(item.body) - } - iconView.setImageDrawable(getDrawable(suggestion.getIcon(), context)) + override fun onSuggestionClickListener(suggestion: GtfsSuggestion) { + val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager + var view = (context as DashActivity).currentFocus + if (view == null) { + view = View(context) } - - //searchView.attachNavigationDrawerToMenuButton(drawer_layout as androidx.drawerlayout.widget.DrawerLayout) + imm.hideSoftInputFromWindow(view.windowToken, 0) + if (suggestion is StopSuggestion) { + val intent = Intent(context, StopSpecifyActivity::class.java) + intent.putExtra(StopSpecifyActivity.EXTRA_STOP_NAME, suggestion.name) + startActivity(intent) + } else if (suggestion is LineSuggestion) { + val intent = Intent(context, LineSpecifyActivity::class.java) + intent.putExtra(LineSpecifyActivity.EXTRA_LINE_ID, suggestion.name) + startActivity(intent) + } } override fun onRestart() { @@ -256,8 +271,10 @@ showError(drawer_layout, code, this) } private fun getSuggestions() { - providerProxy.getSuggestions { - searchView.swapSuggestions(it) + providerProxy.getSuggestions { suggestions -> + suggestions.forEach { + suggestionsAdapter.addSuggestion(it) + } } } @@ -274,12 +291,14 @@ if (getDefaultSharedPreferences(this).getBoolean(getString(R.string.key_timetable_automatic_update), false) or force) startService(Intent(context, TimetableDownloader::class.java)) } - override fun onBackPressed() { //fixme + override fun onBackPressed() { if (drawerLayout.isDrawerOpen(drawerView)) { drawerLayout.closeDrawer(drawerView) return } - if (!searchView.setSearchFocused(false)) { + if (searchView.isSearchEnabled) { + searchView.disableSearch() + } else { super.onBackPressed() } } diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/adapters/SuggestionsAdapter.kt b/app/src/main/java/ml/adamsprogs/bimba/models/adapters/SuggestionsAdapter.kt new file mode 100644 index 0000000000000000000000000000000000000000..4769220894b85cb69b1596ece78cf47291d1e34b --- /dev/null +++ b/app/src/main/java/ml/adamsprogs/bimba/models/adapters/SuggestionsAdapter.kt @@ -0,0 +1,70 @@ +package ml.adamsprogs.bimba.models.adapters + +import android.content.Context +import android.graphics.PorterDuff +import android.os.Build +import android.text.Html +import android.view.* +import android.widget.* +import androidx.core.content.ContextCompat.getColor +import ml.adamsprogs.bimba.R +import ml.adamsprogs.bimba.getDrawable +import com.mancj.materialsearchbar.adapter.SuggestionsAdapter as SearchBarSuggestionsAdapter +import ml.adamsprogs.bimba.models.suggestions.GtfsSuggestion +import ml.adamsprogs.bimba.models.suggestions.LineSuggestion +import ml.adamsprogs.bimba.models.suggestions.StopSuggestion + +class SuggestionsAdapter(inflater: LayoutInflater, private val onSuggestionClickListener: OnSuggestionClickListener, private val context: Context) : + SearchBarSuggestionsAdapter<GtfsSuggestion, SuggestionsAdapter.ViewHolder>(inflater) { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val rowView = layoutInflater.inflate(R.layout.row_suggestion, parent, false) + return ViewHolder(rowView) + } + + override fun getSingleViewHeight(): Int = 48 + + override fun onBindSuggestionHolder(suggestion: GtfsSuggestion, holder: ViewHolder?, pos: Int) { + holder!!.root.setOnClickListener { + onSuggestionClickListener.onSuggestionClickListener(suggestion) + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + holder.text.text = Html.fromHtml(suggestion.getBody(), Html.FROM_HTML_MODE_LEGACY) + } else { + @Suppress("DEPRECATION") + holder.text.text = Html.fromHtml(suggestion.getBody()) + } + + holder.text.setTextColor(getColor(context, R.color.textDark)) + + val icon = getDrawable(suggestion.getIcon(), context) + icon.mutate() + icon.colorFilter = null + if (suggestion is StopSuggestion) + when (suggestion.zone) { + "A" -> icon.setColorFilter(getColor(context, R.color.zoneA), PorterDuff.Mode.SRC_IN) + "B" -> icon.setColorFilter(getColor(context, R.color.zoneB), PorterDuff.Mode.SRC_IN) + "C" -> icon.setColorFilter(getColor(context, R.color.zoneC), PorterDuff.Mode.SRC_IN) + else -> icon.setColorFilter(getColor(context, R.color.textDark), PorterDuff.Mode.SRC_IN) + } + else if (suggestion is LineSuggestion) { + icon.setColorFilter(suggestion.getColour(), PorterDuff.Mode.SRC_IN) + holder.icon.setBackgroundColor(suggestion.getBgColour()) + } + holder.icon.setImageDrawable(icon) + + } + + operator fun contains(suggestion: GtfsSuggestion): Boolean { + return suggestion in suggestions || suggestion in suggestions_clone + } + + inner class ViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView.ViewHolder(itemView) { + val root: View = itemView.findViewById(R.id.row_suggestion) + val icon: ImageView = itemView.findViewById(R.id.suggestion_row_image) + val text: TextView = itemView.findViewById(R.id.suggestion_row_text) + } + + interface OnSuggestionClickListener { + fun onSuggestionClickListener(suggestion: GtfsSuggestion) + } +} diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/GtfsSuggestion.kt b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/GtfsSuggestion.kt index 1fab1c029c41a7e5dc26178ae5f5e86b33ab375a..da730c9e177b77109707e111e790a19a59f0f3ec 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/GtfsSuggestion.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/GtfsSuggestion.kt @@ -1,11 +1,11 @@ package ml.adamsprogs.bimba.models.suggestions -import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion - -abstract class GtfsSuggestion(val name: String) : SearchSuggestion, Comparable<GtfsSuggestion> { +abstract class GtfsSuggestion(val name: String) : Comparable<GtfsSuggestion> { abstract fun getIcon(): Int abstract fun getColour(): Int abstract fun getBgColour(): Int + + abstract fun getBody(): String } \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/LineSuggestion.kt b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/LineSuggestion.kt index 0b71ad0cce6bf32496a79b791082caa7a5ebf5c6..1014c31c25da4d8e854c5e035df24eba42fa9ea9 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/LineSuggestion.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/LineSuggestion.kt @@ -1,24 +1,9 @@ package ml.adamsprogs.bimba.models.suggestions -import android.os.Parcel -import android.os.Parcelable import ml.adamsprogs.bimba.R import ml.adamsprogs.bimba.models.gtfs.Route class LineSuggestion(name: String, private val route: Route) : GtfsSuggestion(name) { - constructor(parcel: Parcel) : this( - parcel.readString(), - parcel.readParcelable(Route::class.java.classLoader)) - - override fun writeToParcel(parcel: Parcel, flags: Int) { - parcel.writeString(name) - parcel.writeParcelable(route, flags) - } - - override fun describeContents(): Int { - return 0 - } - override fun getIcon(): Int { return when (route.type) { Route.TYPE_BUS -> R.drawable.ic_bus @@ -46,13 +31,18 @@ else name.compareTo(other.name) } - companion object CREATOR : Parcelable.Creator<LineSuggestion> { - override fun createFromParcel(parcel: Parcel): LineSuggestion { - return LineSuggestion(parcel) - } + override fun equals(other: Any?): Boolean { + if (other == null || other !is GtfsSuggestion) + return false + return if (other is LineSuggestion) + name.padStart(3, '0') == other.name.padStart(3, '0') + else + name == other.name + } - override fun newArray(size: Int): Array<LineSuggestion?> { - return arrayOfNulls(size) - } + override fun hashCode(): Int { + var result = route.hashCode() + result = 31 * result + name.hashCode() + return result } } \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/StopSuggestion.kt b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/StopSuggestion.kt index cd3ef7762cb9f0e16a905cba2df8193e9d8b4568..cd3c4c7c57cda7ec6e1b6ab88a3d1ad6463fce3b 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/StopSuggestion.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/StopSuggestion.kt @@ -1,22 +1,8 @@ package ml.adamsprogs.bimba.models.suggestions -import android.os.Parcel -import android.os.Parcelable import ml.adamsprogs.bimba.R -class StopSuggestion(name: String, private val zone: String, private val zoneColour: String) : GtfsSuggestion(name){ - @Suppress("UNCHECKED_CAST") - constructor(parcel: Parcel) : this(parcel.readString(), parcel.readString(), parcel.readString()) - - override fun describeContents(): Int { - return Parcelable.CONTENTS_FILE_DESCRIPTOR - } - - override fun writeToParcel(dest: Parcel?, flags: Int) { - dest?.writeString(name) - dest?.writeString(zone) - dest?.writeString(zoneColour) - } +class StopSuggestion(name: String, val zone: String, private val zoneColour: String) : GtfsSuggestion(name) { override fun getBody(): String { return name @@ -27,7 +13,7 @@ return R.drawable.ic_stop } override fun getColour(): Int { - return zoneColour.filter { it in "0123456789abcdef" }.toInt(16) + return 0xffffff } override fun getBgColour(): Int { @@ -38,13 +24,15 @@ override fun compareTo(other: GtfsSuggestion): Int { return name.compareTo(other.name) } - companion object CREATOR : Parcelable.Creator<StopSuggestion> { - override fun createFromParcel(parcel: Parcel): StopSuggestion { - return StopSuggestion(parcel) - } + override fun equals(other: Any?): Boolean { + if (other == null || other !is GtfsSuggestion) + return false + return name == other.name + } - override fun newArray(size: Int): Array<StopSuggestion?> { - return arrayOfNulls(size) - } + override fun hashCode(): Int { + var result = zone.hashCode() + result = 31 * result + name.hashCode() + return result } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_dash.xml b/app/src/main/res/layout/activity_dash.xml index d7c30f0ce549eb0ba692f4b96e273fa86f617c2e..a85c89ba8d5384563c3efc2eb8235cf69d24032d 100644 --- a/app/src/main/res/layout/activity_dash.xml +++ b/app/src/main/res/layout/activity_dash.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> @@ -33,35 +34,37 @@ android:id="@+id/favourites_list" android:layout_width="0dp" android:layout_height="0dp" - android:layout_marginBottom="0dp" - android:layout_marginTop="80dp" + android:layout_marginTop="8dp" android:scrollbars="none" + app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="@id/search_view" /> + app:layout_constraintTop_toBottomOf="@+id/search_view" /> - <com.arlib.floatingsearchview.FloatingSearchView + <com.mancj.materialsearchbar.MaterialSearchBar android:id="@+id/search_view" + style="@style/SearchBarTheme" android:layout_width="match_parent" - android:layout_height="match_parent" - app:floatingSearch_close_search_on_keyboard_dismiss="true" - app:floatingSearch_leftActionMode="showHamburger" - app:floatingSearch_searchBarMarginLeft="16dp" - app:floatingSearch_searchBarMarginRight="16dp" - app:floatingSearch_searchBarMarginTop="16dp" - app:floatingSearch_searchHint="@string/search_placeholder" - app:floatingSearch_showSearchKey="false" - app:floatingSearch_suggestionsListAnimDuration="250" /> - + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:fadeScrollbars="false" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:mt_hint="@string/search_placeholder" + app:mt_maxSuggestionsCount="10" + app:mt_navIconEnabled="true" + app:mt_placeholder="@string/search_placeholder" + app:mt_roundedSearchBarEnabled="true" + app:mt_speechMode="false" /> </androidx.constraintlayout.widget.ConstraintLayout> - <!-- The navigation drawer --> <com.google.android.material.navigation.NavigationView android:id="@+id/drawer" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" - app:menu="@menu/menu_drawer"> - </com.google.android.material.navigation.NavigationView> + app:menu="@menu/menu_drawer" /> </androidx.drawerlayout.widget.DrawerLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/row_suggestion.xml b/app/src/main/res/layout/row_suggestion.xml new file mode 100644 index 0000000000000000000000000000000000000000..7d5a28b73069aa5c15378d1f2094be901fd4ba94 --- /dev/null +++ b/app/src/main/res/layout/row_suggestion.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/row_suggestion" + android:layout_width="match_parent" + android:layout_height="48dp" + android:orientation="vertical"> + + + <ImageView + android:id="@+id/suggestion_row_image" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + android:contentDescription="@string/suggestion_row_image" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <TextView + android:id="@+id/suggestion_row_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:text="" + android:textAppearance="@style/TextAppearance.AppCompat.SearchResult.Title" + app:layout_constraintStart_toEndOf="@+id/suggestion_row_image" + app:layout_constraintTop_toTopOf="parent" /> +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 513e4652283dcb5cd773feefafbc6ce810b49bcd..ebccb8676c3f063a9db025b7aa91f8440dee7bb5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -91,4 +91,5 @@ Sat <string name="Sun">Sun</string> <string name="summary_timetable_automatic_update">Automatically check for and download timetable updates</string> <string name="server_error">Server error</string> + <string name="suggestion_row_image" translatable="false">suggestion row image</string> </resources> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 6e8b3469a57e5c647a8154d464cee71d51fd504d..6d69eba5bfa47ba8533df940f075bbf037a47384 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -27,4 +27,25 @@