diff --git a/app/build.gradle b/app/build.gradle index f5032d7f..46a23698 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -63,8 +63,8 @@ android { namespace "ca.rmen.android.poetassistant" minSdkVersion 21 targetSdkVersion 35 - versionCode 113010 - versionName "1.30.10" + versionCode 113100 + versionName "1.31.0" // setting vectorDrawables.useSupportLibrary = true means pngs won't be generated at // build time: http://android-developers.blogspot.fr/2016/02/android-support-library-232.html vectorDrawables.useSupportLibrary = true diff --git a/app/src/androidTest/java/ca/rmen/android/poetassistant/main/IntegrationTest.java b/app/src/androidTest/java/ca/rmen/android/poetassistant/main/IntegrationTest.java index f61db6bb..06eb65d1 100644 --- a/app/src/androidTest/java/ca/rmen/android/poetassistant/main/IntegrationTest.java +++ b/app/src/androidTest/java/ca/rmen/android/poetassistant/main/IntegrationTest.java @@ -130,11 +130,11 @@ private void runIntegrationTest(IntegrationTestScenario data) { checkAllStarredWords(context, data.secondSynonymForFirstRhyme); swipeViewPagerRight(3); checkStarredInList(data.secondSynonymForFirstRhyme); - addFilter(data.thesaurusFilter, data.thesaurusFilterMatch); - clearFilter(data.firstSynonymForFirstRhyme); + addFilter(Tab.THESAURUS, data.thesaurusFilter, data.thesaurusFilterMatch); + clearFilter(Tab.THESAURUS, data.firstSynonymForFirstRhyme); swipeViewPagerRight(1); - addFilter(data.rhymerFilter, data.rhymerFilterMatch); - clearFilter(data.firstRhyme); + addFilter(Tab.RHYMER, data.rhymerFilter, data.rhymerFilterMatch); + clearFilter(Tab.RHYMER, data.firstRhyme); swipeViewPagerLeft(3); typeAndSpeakPoem(data.poem); clearPoem(); @@ -161,11 +161,11 @@ private void runCleanLayoutIntegrationTest(IntegrationTestScenario data) { checkAllStarredWords(context, data.secondSynonymForFirstRhyme); swipeViewPagerRight(3); checkStarredInList(data.secondSynonymForFirstRhyme); - addFilter(data.thesaurusFilter, data.thesaurusFilterMatch); - clearFilter(data.firstSynonymForFirstRhyme); + addFilter(Tab.THESAURUS, data.thesaurusFilter, data.thesaurusFilterMatch); + clearFilter(Tab.THESAURUS, data.firstSynonymForFirstRhyme); swipeViewPagerRight(1); - addFilter(data.rhymerFilter, data.rhymerFilterMatch); - clearFilter(data.firstRhyme); + addFilter(Tab.RHYMER, data.rhymerFilter, data.rhymerFilterMatch); + clearFilter(Tab.RHYMER, data.firstRhyme); swipeViewPagerLeft(3); typeAndSpeakPoem(data.poem); clearPoem(); diff --git a/app/src/androidTest/java/ca/rmen/android/poetassistant/main/PoemTest.java b/app/src/androidTest/java/ca/rmen/android/poetassistant/main/PoemTest.java index 56b23c8b..4372d37d 100644 --- a/app/src/androidTest/java/ca/rmen/android/poetassistant/main/PoemTest.java +++ b/app/src/androidTest/java/ca/rmen/android/poetassistant/main/PoemTest.java @@ -150,12 +150,10 @@ public void testLookupSetting() { swipeViewPagerLeft(3); String poemText = "Here is a poem with lookup disabled"; typePoem(poemText); - pressBack(); assertPopupMissing("rhymer"); assertPopupMissing("thesaurus"); assertPopupMissing("dictionary"); - pressBack(); closeSoftKeyboard(); openMenuItem(R.string.action_settings); diff --git a/app/src/androidTest/java/ca/rmen/android/poetassistant/main/RandomWordTest.java b/app/src/androidTest/java/ca/rmen/android/poetassistant/main/RandomWordTest.java index 4fb0d055..b2202965 100644 --- a/app/src/androidTest/java/ca/rmen/android/poetassistant/main/RandomWordTest.java +++ b/app/src/androidTest/java/ca/rmen/android/poetassistant/main/RandomWordTest.java @@ -72,7 +72,7 @@ public class RandomWordTest { @Test public void openWotdListTest() { openMenuItem(R.string.action_wotd_history); - Matcher latestEntryViewMatcher = childAtPosition(withId(R.id.recycler_view), 0); + Matcher latestEntryViewMatcher = childAtPosition(withId(R.id.wotd_recycler_view), 0); // Check that the date field in the first (most recent) entry in the Wotd list contains today's date. Calendar cal = Calendar.getInstance(); int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH); @@ -90,7 +90,7 @@ public void openWotdListTest() { onView(allOf(withId(R.id.btn_star_result), isDescendantOfA(latestEntryViewMatcher))) .perform(click()); swipeViewPagerRight(1); - onView(allOf(withId(R.id.recycler_view), isDisplayed())).check(matches(withAdapterItemCount(1))); + onView(allOf(withId(R.id.favorites_recycler_view), isDisplayed())).check(matches(withAdapterItemCount(1))); } diff --git a/app/src/androidTest/java/ca/rmen/android/poetassistant/main/SearchTest.java b/app/src/androidTest/java/ca/rmen/android/poetassistant/main/SearchTest.java index 6e8dfd71..75a3cc05 100644 --- a/app/src/androidTest/java/ca/rmen/android/poetassistant/main/SearchTest.java +++ b/app/src/androidTest/java/ca/rmen/android/poetassistant/main/SearchTest.java @@ -21,6 +21,8 @@ import android.content.Context; + +import androidx.test.espresso.Espresso; import androidx.test.espresso.ViewInteraction; import androidx.test.filters.LargeTest; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -104,9 +106,14 @@ public void searchHistoryTest() { searchAutoComplete.perform(typeText("o")); checkSearchSuggestions("awesome", "awesomely"); + Espresso.pressBack(); + Espresso.onIdle(); searchAutoComplete.perform(clearText()); searchAutoComplete.perform(typeText("carme")); checkSearchSuggestions("carmen", "carmelite"); + Espresso.pressBack(); + Espresso.pressBack(); + Espresso.onIdle(); clearSearchHistory(); @@ -144,7 +151,7 @@ public void patternSearchWithFavoriteTest() { @Test public void patternSearchTooManyResultsTest() { search("a*"); - onView(allOf(withId(R.id.recycler_view), isDisplayed())) + onView(allOf(withId(R.id.pattern_recycler_view), isDisplayed())) .check(matches(withAdapterItemCount(501))); } diff --git a/app/src/androidTest/java/ca/rmen/android/poetassistant/main/ShareTest.java b/app/src/androidTest/java/ca/rmen/android/poetassistant/main/ShareTest.java index 8a450cc6..cbadd5c0 100644 --- a/app/src/androidTest/java/ca/rmen/android/poetassistant/main/ShareTest.java +++ b/app/src/androidTest/java/ca/rmen/android/poetassistant/main/ShareTest.java @@ -86,7 +86,7 @@ public void shareFilteredThesaurusTest() { Context context = mActivityTestRule.getActivity(); search("happy"); swipeViewPagerLeft(1); - addFilter("messed", "blessed"); + addFilter(Tab.THESAURUS, "messed", "blessed"); openMenuItem(R.string.share); String expectedContent = context.getString(R.string.share_thesaurus_title_with_filter, "happy", "messed"); checkShareIntentContains(expectedContent); diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 94526bc3..f1bf14e7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -44,6 +44,7 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" + android:enableOnBackInvokedCallback="true" android:theme="@style/AppTheme"> - val themedLayoutInflater = LayoutInflater.from(ContextThemeWrapper(context, R.style.AppAlertDialog)) - val binding = DataBindingUtil.inflate(themedLayoutInflater, + val layoutInflater = LayoutInflater.from(context) + val binding = DataBindingUtil.inflate(layoutInflater, R.layout.input_dialog_edit_text, null, false) arguments?.let { args -> binding.edit.setText(args.getString(EXTRA_TEXT)) diff --git a/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/ResultListFactory.kt b/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/ResultListFactory.kt index ed8e550a..a5f34f08 100644 --- a/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/ResultListFactory.kt +++ b/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/ResultListFactory.kt @@ -28,6 +28,7 @@ import android.os.Bundle import androidx.fragment.app.Fragment import android.util.Log import android.view.View +import androidx.annotation.IdRes import ca.rmen.android.poetassistant.Constants import ca.rmen.android.poetassistant.R import ca.rmen.android.poetassistant.TtsState @@ -201,6 +202,21 @@ object ResultListFactory { } } + /** + * Determine if the matched word in the results list header should be selectable + * (for copying/pasting). + * + * If we make the matched word always selectable, this causes issues with the + * app bar: When loading the app, the content scrolls up, partially hiding the + * top bar. + * + * Maybe there's a better way to avoid this scrolling. But in any case, it doesn't + * make sense for the text to be selectable if it's empty, or if it's just a "label" + * as in the case of the favorites result list header. + */ + fun getMatchedWordSelectability(tab: Tab, matchedWord: String) = + matchedWord.isNotBlank() && tab != Tab.FAVORITES + fun getTabName(context: Context, tab: Tab): String { return when (tab) { Tab.PATTERN -> context.getString(R.string.tab_pattern) @@ -212,4 +228,14 @@ object ResultListFactory { else -> context.getString(R.string.tab_reader) } } + @IdRes + fun getRecyclerViewId(tab: Tab): Int = when (tab) { + Tab.PATTERN -> R.id.pattern_recycler_view + Tab.FAVORITES -> R.id.favorites_recycler_view + Tab.WOTD -> R.id.wotd_recycler_view + Tab.RHYMER -> R.id.rhymer_recycler_view + Tab.THESAURUS -> R.id.thesaurus_recycler_view + Tab.DICTIONARY -> R.id.dictionary_recycler_view + else -> R.id.recycler_view + } } diff --git a/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/ResultListFragment.kt b/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/ResultListFragment.kt index 350219ce..3b62e4b5 100644 --- a/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/ResultListFragment.kt +++ b/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/ResultListFragment.kt @@ -82,6 +82,7 @@ class ResultListFragment : Fragment() { rightMargin = insets.right } } + mBinding.recyclerView.id = ResultListFactory.getRecyclerViewId(it) @Suppress("UNCHECKED_CAST") mViewModel = ResultListFactory.createViewModel(it, this) as ResultListViewModel mBinding.viewModel = mViewModel @@ -221,7 +222,12 @@ class ResultListFragment : Fragment() { private val mFavoritesObserver = Observer> { reload() } - private val mUsedQueryWordChanged = Observer { usedQueryWord -> mHeaderViewModel.query.set(usedQueryWord) } + private val mUsedQueryWordChanged = Observer { usedQueryWord -> + mHeaderViewModel.query.set(usedQueryWord) + mTab?.let { + mHeaderViewModel.isMatchedWordSelectable.set(ResultListFactory.getMatchedWordSelectability(it, usedQueryWord)) + } + } private val mEmptyTextObserver = Observer { emptyText -> mBinding.empty.text = when (emptyText) { diff --git a/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/ResultListHeaderViewModel.kt b/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/ResultListHeaderViewModel.kt index 5d63462b..682dba95 100644 --- a/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/ResultListHeaderViewModel.kt +++ b/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/ResultListHeaderViewModel.kt @@ -37,6 +37,7 @@ import javax.inject.Inject class ResultListHeaderViewModel(application: Application) : AndroidViewModel(application) { val query = ObservableField() + val isMatchedWordSelectable = ObservableField(false) val filter = ObservableField() val isFavorite = ObservableBoolean() val showHeader = ObservableBoolean() diff --git a/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/search/Search.kt b/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/search/Search.kt index 333dce61..30c81a04 100644 --- a/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/search/Search.kt +++ b/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/search/Search.kt @@ -21,13 +21,12 @@ package ca.rmen.android.poetassistant.main.dictionaries.search import android.app.Activity import android.app.SearchManager -import android.content.ComponentName import android.content.ContentValues -import android.content.Context +import android.util.Log import androidx.annotation.MainThread +import androidx.lifecycle.viewModelScope +import androidx.recyclerview.widget.RecyclerView import androidx.viewpager.widget.ViewPager -import androidx.appcompat.widget.SearchView -import android.util.Log import ca.rmen.android.poetassistant.Constants import ca.rmen.android.poetassistant.R import ca.rmen.android.poetassistant.Threading @@ -36,7 +35,10 @@ import ca.rmen.android.poetassistant.main.PagerAdapter import ca.rmen.android.poetassistant.main.Tab import ca.rmen.android.poetassistant.main.dictionaries.ResultListFragment import ca.rmen.android.poetassistant.main.dictionaries.dictionary.Dictionary +import ca.rmen.android.poetassistant.widget.DebounceTextWatcher import ca.rmen.android.poetassistant.widget.ViewShownScheduler +import com.google.android.material.search.SearchView +import kotlinx.coroutines.launch import java.util.Locale import javax.inject.Inject @@ -65,11 +67,45 @@ class Search constructor(private val searchableActivity: Activity, private val v mPagerAdapter = viewPager.adapter as PagerAdapter } - fun setSearchView(searchView: SearchView) { - (searchableActivity.getSystemService(Context.SEARCH_SERVICE) as SearchManager?)?.let { - val searchableActivityComponentName = ComponentName(searchableActivity, searchableActivity.javaClass) - searchView.queryHint = searchableActivity.getString(R.string.search_hint) // To hopefully prevent some crashes (!!) :( - searchView.setSearchableInfo(it.getSearchableInfo(searchableActivityComponentName)) + fun setSearchView(searchView: SearchView, suggestionsViewModel: SuggestionsViewModel) { + searchView.hint = + searchableActivity.getString(R.string.search_hint) // To hopefully prevent some crashes (!!) :( + // Step 1: Setup suggestions + val suggestionsList: RecyclerView = searchView.findViewById(R.id.search_suggestions_list) + val adapter = SuggestionsAdapter() + suggestionsList.adapter = adapter + // Step 1a: Fetch suggestions from the disk when the user stops typing. + DebounceTextWatcher.debounce(searchView.editText, { + val typedText = searchView.editText.text.toString() + suggestionsViewModel.fetchSuggestions(typedText) + }) + // Step 2a: When the suggestions list is updated, notify the recycler view adapter. + suggestionsViewModel.viewModelScope.launch { + suggestionsViewModel.suggestions.collect { value -> + Log.d(TAG, "Emitted $value") + adapter.suggestions.clear() + adapter.suggestions.addAll(value) + adapter.notifyDataSetChanged() + } + } + + // Step 2: Listen for search events: + fun searchTermSelected(searchTerm: String) { + searchView.hide() + if (searchTerm.isNotBlank()) { + addSuggestions(searchTerm) + search(searchTerm) + } + } + + // Case 2a: Handle when the user taps enter from the search widget + searchView.editText.setOnEditorActionListener { _, _, _ -> + searchTermSelected(searchView.editText.text.toString()) + false + } + // Case 2b: Handle when the user clicked on a search suggestion. + adapter.listener = { value -> + searchTermSelected(value) } } diff --git a/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/search/SuggestionsAdapter.kt b/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/search/SuggestionsAdapter.kt new file mode 100644 index 00000000..699b3ad1 --- /dev/null +++ b/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/search/SuggestionsAdapter.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025 - current Carmen Alvarez + * + * This file is part of Poet Assistant. + * + * Poet Assistant is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Poet Assistant is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Poet Assistant. If not, see . + */ + +package ca.rmen.android.poetassistant.main.dictionaries.search + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import ca.rmen.android.poetassistant.R + +class SuggestionsAdapter : RecyclerView.Adapter() { + val suggestions = mutableListOf() + + class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) { + val icon: ImageView = view.findViewById(android.R.id.icon1) + val text: TextView = view.findViewById(android.R.id.text1) + } + + var listener: ((String) -> Unit)? = null + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.suggested_word, parent, false) + val vh = ViewHolder(view) + view.setOnClickListener { + listener?.invoke(vh.text.text.toString()) + } + return vh + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.text.text = suggestions[position].word + holder.icon.setImageResource(suggestions[position].iconResource) + } + + override fun getItemCount() = suggestions.size + +} \ No newline at end of file diff --git a/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/search/SuggestionsViewModel.kt b/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/search/SuggestionsViewModel.kt new file mode 100644 index 00000000..0ac824e0 --- /dev/null +++ b/app/src/main/kotlin/ca/rmen/android/poetassistant/main/dictionaries/search/SuggestionsViewModel.kt @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2025 - current Carmen Alvarez + * + * This file is part of Poet Assistant. + * + * Poet Assistant is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Poet Assistant is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Poet Assistant. If not, see . + */ + +package ca.rmen.android.poetassistant.main.dictionaries.search + +import android.app.Application +import android.app.SearchManager +import android.util.Log +import androidx.annotation.DrawableRes +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.viewModelScope +import ca.rmen.android.poetassistant.Constants +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.launch + +class SuggestionsViewModel(private val application: Application) : AndroidViewModel(application) { + + data class SearchSuggestion( + val word: String, + @DrawableRes val iconResource: Int + ) + + companion object { + private val TAG = Constants.TAG + SuggestionsViewModel::class.java.simpleName + } + + private val _suggestions = MutableStateFlow>(emptyList()) + val suggestions: Flow> = _suggestions + + fun fetchSuggestions(typedText: String) { + viewModelScope.launch(Dispatchers.IO) { + + val foundSuggestions = mutableListOf() + SuggestionsCursor(application, typedText).use { cursor -> + val wordColumn = cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1) + val iconColumn = cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1) + Log.d(TAG, "${cursor.count} results for $typedText") + while (cursor.moveToNext()) { + foundSuggestions.add( + SearchSuggestion( + cursor.getString(wordColumn), + cursor.getInt(iconColumn), + ) + ) + } + } + _suggestions.value = foundSuggestions + } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/ca/rmen/android/poetassistant/main/reader/ReaderFragment.kt b/app/src/main/kotlin/ca/rmen/android/poetassistant/main/reader/ReaderFragment.kt index 7bd754f8..98b6be64 100644 --- a/app/src/main/kotlin/ca/rmen/android/poetassistant/main/reader/ReaderFragment.kt +++ b/app/src/main/kotlin/ca/rmen/android/poetassistant/main/reader/ReaderFragment.kt @@ -31,6 +31,9 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.annotation.IdRes +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment import androidx.lifecycle.Observer @@ -104,6 +107,13 @@ class ReaderFragment : Fragment(), ConfirmDialogFragment.ConfirmDialogListener { DebounceTextWatcher.debounce(mBinding.tvText) { mViewModel.updateWordCount() } TextPopupMenu.addSelectionPopupMenu(mBinding.root, mBinding.tvText, activity as OnWordClickListener) mViewModel.playButtonStateLiveData.observe(this, mPlayButtonStateObserver) + ViewCompat.setOnApplyWindowInsetsListener(mBinding.tvText) { _, insets -> + val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom + mBinding.readerContent.updatePadding( + bottom = imeHeight + ) + insets + } return mBinding.root } @@ -218,7 +228,7 @@ class ReaderFragment : Fragment(), ConfirmDialogFragment.ConfirmDialogListener { Log.v(TAG, "updatePlayButton: playButtonState $playButtonState") if (playButtonState != null) { mBinding.btnPlay.isEnabled = playButtonState.isEnabled - mBinding.btnPlay.setImageResource(playButtonState.iconId) + mBinding.btnPlay.setIconResource(playButtonState.iconId) } } diff --git a/app/src/main/res/drawable/ic_clear.xml b/app/src/main/res/drawable/ic_clear.xml index a2258ed5..36ecbb6c 100644 --- a/app/src/main/res/drawable/ic_clear.xml +++ b/app/src/main/res/drawable/ic_clear.xml @@ -23,6 +23,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_play_disabled.xml b/app/src/main/res/drawable/ic_play_disabled.xml index 32ef3877..ea56859e 100644 --- a/app/src/main/res/drawable/ic_play_disabled.xml +++ b/app/src/main/res/drawable/ic_play_disabled.xml @@ -1,5 +1,5 @@ diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index 1edfb111..61300a78 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -46,10 +46,4 @@ android:title="@string/action_about" android:orderInCategory="100" app:showAsAction="never" /> - diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 13552420..7be327cf 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -18,6 +18,13 @@ --> + + @color/surface + #f88 + #181818 + #deffffff + #000 + #A5B7C0 #859AA4 #cccccc #727272 @@ -25,4 +32,5 @@ #383838 #303030 #1fffffff + #444 diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index a96d34be..9c1c5786 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -18,9 +18,16 @@ --> + #fff + #f00 + + #f6f7f9 + #de000000 + #fff + #607D8B #455A64 - #ffff00 + @color/primary @color/primary #212121 #727272 @@ -31,5 +38,5 @@ #1f000000 #FFFFFF #b3ffffff - #ffffff + @color/on_primary diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml new file mode 100644 index 00000000..6e146746 --- /dev/null +++ b/app/src/main/res/values/ids.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index e927a025..2416949a 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -20,17 +20,51 @@ - + + + - - - - - - - - - - - -