diff --git a/about/src/main/res/layout/fragment_about.xml b/about/src/main/res/layout/fragment_about.xml
index b8d0133..08ba83a 100644
--- a/about/src/main/res/layout/fragment_about.xml
+++ b/about/src/main/res/layout/fragment_about.xml
@@ -1,11 +1,10 @@
-
+ android:layout_width="match_parent">
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/about/src/main/res/layout/fragment_third_party_libraries.xml b/about/src/main/res/layout/fragment_third_party_libraries.xml
index 665c7e7..f203f8a 100644
--- a/about/src/main/res/layout/fragment_third_party_libraries.xml
+++ b/about/src/main/res/layout/fragment_third_party_libraries.xml
@@ -1,11 +1,10 @@
-
+ android:layout_width="match_parent">
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 7b0c14d..69d7163 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -48,7 +48,7 @@ android {
}
// Dynamic feature modules
- dynamicFeatures = [":about", ":merriamwebster"]
+ dynamicFeatures = [":about", ":merriamwebster", ":merriamwebster_thesaurus"]
// Compile options
compileOptions {
@@ -63,18 +63,18 @@ android {
lintOptions {
checkReleaseBuilds false
}
-
- // Testing
- // Add shared test dir to be used by both unit and instrumented tests
- sourceSets {
- String sharedTestDir = 'src/sharedTest/java'
- test {
- java.srcDir sharedTestDir
- }
- androidTest {
- java.srcDir sharedTestDir
- }
- }
+//
+// // Testing
+// // Add shared test dir to be used by both unit and instrumented tests
+// sourceSets {
+// String sharedTestDir = 'src/sharedTest/java'
+// test {
+// java.srcDir sharedTestDir
+// }
+// androidTest {
+// java.srcDir sharedTestDir
+// }
+// }
// Include Android resources for robolectric unit testing.
testOptions {
diff --git a/app/src/androidTest/java/space/narrate/waylan/android/ExampleInstrumentedTest.kt b/app/src/androidTest/java/space/narrate/waylan/android/ExampleInstrumentedTest.kt
deleted file mode 100644
index 55595e7..0000000
--- a/app/src/androidTest/java/space/narrate/waylan/android/ExampleInstrumentedTest.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package space.narrate.waylan.android
-
-
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.Assert.*
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * See [testing documentation](http://d.android.com/tools/testing).
- */
-@RunWith(AndroidJUnit4::class)
-class ExampleInstrumentedTest {
- @Test
- fun useAppContext() {
- // Context of the app under test.
- val appContext = androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().targetContext
- assertEquals("space.narrate.waylan.android", appContext.packageName)
- }
-}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f051882..85f018f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -8,7 +8,6 @@
-
diff --git a/app/src/main/java/space/narrate/waylan/android/di/AppModule.kt b/app/src/main/java/space/narrate/waylan/android/di/AppModule.kt
index 996a097..a1ad396 100644
--- a/app/src/main/java/space/narrate/waylan/android/di/AppModule.kt
+++ b/app/src/main/java/space/narrate/waylan/android/di/AppModule.kt
@@ -93,16 +93,26 @@ val appModule = module {
).newInstance() as DetailProviderFactory
}
- // Details
+ single(named("merriamWebsterThesaurusDetailDataProviderFactory")) {
+ Class.forName(
+ "space.narrate.waylan.merriamwebster_thesaurus.di.MerriamWebsterThesaurusModuleProviderFactory"
+ ).newInstance() as DetailProviderFactory
+ }
+
+ // DetailDataProviderRegistry
single {
val detailDataProviderRegistry = DetailDataProviderRegistry()
val merriamWebsterDetailProviderFactory: DetailProviderFactory =
get(named("merriamWebsterDetailProviderFactory"))
+ val merriamWebsterThesaurusDetailProviderFactory: DetailProviderFactory =
+ get(named("merriamWebsterThesaurusDetailDataProviderFactory"))
+
detailDataProviderRegistry.addProviders(
TitleDetailDataProvider(get()),
merriamWebsterDetailProviderFactory.getDetailDataProvider(),
+ merriamWebsterThesaurusDetailProviderFactory.getDetailDataProvider(),
WordsetDetailDataProvider(get()),
ExampleDetailDataProvider(get())
)
@@ -110,16 +120,21 @@ val appModule = module {
detailDataProviderRegistry
}
+ // DetailItemProviderRegistry
single {
val detailItemFactory = DetailItemProviderRegistry()
val merriamWebsterDetailProviderFactory: DetailProviderFactory =
get(named("merriamWebsterDetailProviderFactory"))
+ val merriamWebsterThesaurusDetailProviderFactory: DetailProviderFactory =
+ get(named("merriamWebsterThesaurusDetailDataProviderFactory"))
+
// Add the Merriam-Webster provider to the detailItemFactory
detailItemFactory.addProviders(
TitleDetailItemProvider(),
merriamWebsterDetailProviderFactory.getDetailItemProvider(),
+ merriamWebsterThesaurusDetailProviderFactory.getDetailItemProvider(),
WordsetDetailItemProvider(),
ExamplesDetailItemProvider()
)
diff --git a/app/src/main/java/space/narrate/waylan/android/ui/MainActivity.kt b/app/src/main/java/space/narrate/waylan/android/ui/MainActivity.kt
index 0e850e3..9bf5c29 100644
--- a/app/src/main/java/space/narrate/waylan/android/ui/MainActivity.kt
+++ b/app/src/main/java/space/narrate/waylan/android/ui/MainActivity.kt
@@ -214,8 +214,8 @@ class MainActivity : AppCompatActivity() {
}
- contextualSheetBehavior.bottomSheetCallback = contextualSheetCallback
- searchSheetBehavior.bottomSheetCallback = searchSheetCallback
+ contextualSheetBehavior.addBottomSheetCallback(contextualSheetCallback)
+ searchSheetBehavior.addBottomSheetCallback(searchSheetCallback)
}
/**
diff --git a/app/src/main/java/space/narrate/waylan/android/ui/auth/AuthActivity.kt b/app/src/main/java/space/narrate/waylan/android/ui/auth/AuthActivity.kt
index 32357f0..65422e2 100644
--- a/app/src/main/java/space/narrate/waylan/android/ui/auth/AuthActivity.kt
+++ b/app/src/main/java/space/narrate/waylan/android/ui/auth/AuthActivity.kt
@@ -13,8 +13,10 @@ import android.view.View
import android.widget.LinearLayout
import android.widget.ProgressBar
import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.widget.AppCompatEditText
import androidx.appcompat.widget.AppCompatTextView
+import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
@@ -300,8 +302,14 @@ class AuthActivity : AppCompatActivity(), CoroutineScope {
bgTransition.isCrossFadeEnabled = true
bgTransition.startTransition(200)
- val errorTextColor = getColorFromAttr(R.attr.colorOnErrorHighEmphasis)
- val errorHintColor = getColorFromAttr(R.attr.colorOnErrorLowEmphasis)
+ val errorTextColor = ContextCompat.getColor(
+ this,
+ R.color.on_error_emphasis_high_type
+ )
+ val errorHintColor = ContextCompat.getColor(
+ this,
+ R.color.on_error_emphasis_disabled
+ )
TransitionManager.beginDelayedTransition(containerLayout)
emailEditText.setTextColor(errorTextColor)
emailEditText.setHintTextColor(errorHintColor)
diff --git a/app/src/main/java/space/narrate/waylan/android/ui/details/DetailItemListMediatorLiveData.kt b/app/src/main/java/space/narrate/waylan/android/ui/details/DetailItemListMediatorLiveData.kt
index 6a520c3..7455044 100644
--- a/app/src/main/java/space/narrate/waylan/android/ui/details/DetailItemListMediatorLiveData.kt
+++ b/app/src/main/java/space/narrate/waylan/android/ui/details/DetailItemListMediatorLiveData.kt
@@ -9,6 +9,7 @@ class DetailItemListMediatorLiveData : MediatorLiveData>()
private var titleModel: DetailItemModel? = null
private var mwModel: DetailItemModel? = null
+ private var mwThesaurusModel: DetailItemModel? = null
private var wordsetModel: DetailItemModel? = null
private var examplesModel: DetailItemModel? = null
@@ -30,6 +31,12 @@ class DetailItemListMediatorLiveData : MediatorLiveData>()
updateList()
}
}
+ DetailItemType.MERRIAM_WEBSTER_THESAURUS -> {
+ if (shouldUpdateList(mwThesaurusModel, item)) {
+ mwThesaurusModel = item
+ updateList()
+ }
+ }
DetailItemType.WORDSET -> {
if (shouldUpdateList(wordsetModel, item)) {
wordsetModel = item
@@ -56,6 +63,7 @@ class DetailItemListMediatorLiveData : MediatorLiveData>()
listOfNotNull(
titleModel,
mwModel,
+ mwThesaurusModel,
wordsetModel,
examplesModel
).sortedBy { it.itemType.order }
diff --git a/app/src/main/java/space/narrate/waylan/android/ui/details/DetailsFragment.kt b/app/src/main/java/space/narrate/waylan/android/ui/details/DetailsFragment.kt
index d0c6cc6..bdaeec7 100644
--- a/app/src/main/java/space/narrate/waylan/android/ui/details/DetailsFragment.kt
+++ b/app/src/main/java/space/narrate/waylan/android/ui/details/DetailsFragment.kt
@@ -172,6 +172,10 @@ class DetailsFragment: BaseFragment(), DetailAdapterListener {
viewModel.onMerriamWebsterPermissionPaneDismissClicked()
}
+ override fun onMwThesaurusChipClicked(word: String) {
+ sharedViewModel.onChangeCurrentWord(word)
+ }
+
private fun showSnackbar(model: SnackbarModel) {
val snackbar = Snackbar.make(coordinatorLayout, model.textRes, when (model.length) {
SnackbarModel.LENGTH_INDEFINITE -> Snackbar.LENGTH_INDEFINITE
diff --git a/app/src/main/java/space/narrate/waylan/android/ui/list/ListItemViewHolder.kt b/app/src/main/java/space/narrate/waylan/android/ui/list/ListItemViewHolder.kt
index bdc53f1..d7a0f46 100644
--- a/app/src/main/java/space/narrate/waylan/android/ui/list/ListItemViewHolder.kt
+++ b/app/src/main/java/space/narrate/waylan/android/ui/list/ListItemViewHolder.kt
@@ -55,7 +55,7 @@ sealed class ListItemViewHolder(val view: View): RecyclerView
wordTextView.text = item.userWord.word
//Set part of speech
- partOfSpeechTextView.text = item.userWord.partOfSpeechPreview.keys.first()
+ partOfSpeechTextView.text = item.userWord.partOfSpeechPreview.keys.firstOrNull() ?: ""
//Set definition
item.userWord.defPreview.map { it.key }.firstOrNull()?.let {
@@ -64,8 +64,8 @@ sealed class ListItemViewHolder(val view: View): RecyclerView
//Set synonym chips
chipGroup.removeAllViews()
- item.userWord.synonymPreview.forEach {
- val synonym = Synonym(it.key, OffsetDateTime.now(), OffsetDateTime.now())
+ item.userWord.synonymPreview.forEach {syn ->
+ val synonym = Synonym(syn.key, OffsetDateTime.now(), OffsetDateTime.now())
chipGroup.addView(
synonym.toChip(view.context, view.expanded_chip_group) {
listener.onWordClicked(it.synonym)
diff --git a/app/src/main/java/space/narrate/waylan/android/ui/search/ContextualFragment.kt b/app/src/main/java/space/narrate/waylan/android/ui/search/ContextualFragment.kt
index 455b6dc..dd7197a 100644
--- a/app/src/main/java/space/narrate/waylan/android/ui/search/ContextualFragment.kt
+++ b/app/src/main/java/space/narrate/waylan/android/ui/search/ContextualFragment.kt
@@ -75,16 +75,19 @@ class ContextualFragment : BaseFragment() {
val materialShapeDrawable = MaterialShapeDrawable(
requireContext(),
null,
- R.attr.styleBottomSheetStandard,
- R.style.Widget_Words_BottomSheet_Standard
+ DEF_STYLE_ATTR,
+ DEF_STYLE_RES
).apply {
initializeElevationOverlay(requireContext())
elevation = contextualFrame.elevation
fillColor = ColorStateList.valueOf(
requireContext().getColorFromAttr(R.attr.colorSurface)
)
+ // Add a stroke to emphasize the shadow on the top of this bottom sheet.
+ // The stroke is very light as the sheet moves towards the bottom of the screen
+ // due to how Android's light source, used for shadow calculation, works.
strokeColor = ColorStateList.valueOf(
- ContextCompat.getColor(requireContext(), R.color.colorBlackAlpha005)
+ ContextCompat.getColor(requireContext(), R.color.shadow_emphasis_color)
)
strokeWidth = 2F
}
@@ -245,6 +248,10 @@ class ContextualFragment : BaseFragment() {
}
companion object {
+
+ private const val DEF_STYLE_ATTR = R.attr.styleBottomSheetStandard
+ private const val DEF_STYLE_RES = R.style.Widget_Waylan_BottomSheet_Standard
+
fun getPeekHeight(context: Context, insets: WindowInsetsCompat): Int {
return SearchFragment.getPeekHeight(context, insets) +
context.resources.getDimensionPixelSize(
diff --git a/app/src/main/java/space/narrate/waylan/android/ui/search/SearchFragment.kt b/app/src/main/java/space/narrate/waylan/android/ui/search/SearchFragment.kt
index a376503..5dbccf6 100644
--- a/app/src/main/java/space/narrate/waylan/android/ui/search/SearchFragment.kt
+++ b/app/src/main/java/space/narrate/waylan/android/ui/search/SearchFragment.kt
@@ -115,16 +115,19 @@ class SearchFragment : BaseFragment(), SearchItemAdapter.SearchItemListener, Tex
val materialShapeDrawable = MaterialShapeDrawable(
requireContext(),
null,
- R.attr.styleBottomSheetStandard,
- R.style.Widget_Words_BottomSheet_Standard
+ DEF_STYLE_ATTR,
+ DEF_STYLE_RES
).apply {
initializeElevationOverlay(requireContext())
elevation = collapsedContainer.elevation
fillColor = ColorStateList.valueOf(
requireContext().getColorFromAttr(R.attr.colorSurface)
)
+ // Add a stroke to emphasize the shadow on the top of this bottom sheet.
+ // The stroke is very light as the sheet moves towards the bottom of the screen
+ // due to how Android's light source, used for shadow calculation, works.
strokeColor = ColorStateList.valueOf(
- ContextCompat.getColor(requireContext(), R.color.colorBlackAlpha005)
+ ContextCompat.getColor(requireContext(), R.color.shadow_emphasis_color)
)
strokeWidth = 3F
}
@@ -568,6 +571,9 @@ class SearchFragment : BaseFragment(), SearchItemAdapter.SearchItemListener, Tex
companion object {
+ private const val DEF_STYLE_ATTR = R.attr.styleBottomSheetStandard
+ private const val DEF_STYLE_RES = R.style.Widget_Waylan_BottomSheet_Standard
+
private fun getBottomInset(context: Context, insets: WindowInsetsCompat): Int {
return insets.systemWindowInsetBottom +
context.resources.getDimensionPixelSize(R.dimen.keyline_2)
diff --git a/app/src/main/java/space/narrate/waylan/android/util/ViewExtensions.kt b/app/src/main/java/space/narrate/waylan/android/util/ViewExtensions.kt
index 514ec8e..ad95f5a 100644
--- a/app/src/main/java/space/narrate/waylan/android/util/ViewExtensions.kt
+++ b/app/src/main/java/space/narrate/waylan/android/util/ViewExtensions.kt
@@ -13,6 +13,7 @@ import space.narrate.waylan.android.data.disk.wordset.Synonym
import space.narrate.waylan.android.ui.MainViewModel
import space.narrate.waylan.core.ui.widget.ElasticAppBarBehavior
import space.narrate.waylan.core.util.setUpWithElasticBehavior
+import space.narrate.waylan.core.util.toChip
fun AppBarLayout.setUpWithElasticBehavior(
currentDestination: String,
@@ -48,36 +49,7 @@ fun Synonym.toChip(
chipGroup: ChipGroup?,
onClick: ((synonym: Synonym) -> Unit)? = null
): Chip {
- val chip: Chip = LayoutInflater.from(context).inflate(
- R.layout.details_chip_layout,
- chipGroup,
- false
- ) as Chip
- chip.text = this.synonym
- chip.setOnClickListener {
- if (onClick != null) onClick(this)
+ return synonym.toChip(context, chipGroup) {
+ if (onClick != null && it == synonym) onClick(this)
}
- return chip
}
-
-fun String.toRelatedChip(
- context: Context,
- chipGroup: ChipGroup?,
- onClick: ((word: String) -> Unit)? = null
-): Chip {
- val chip: Chip = LayoutInflater.from(context).inflate(
- R.layout.details_related_chip_layout,
- chipGroup,
- false
- ) as Chip
- val underlinedString = SpannableString(this)
- underlinedString.setSpan(UnderlineSpan(),0,this.length,0)
- chip.text = underlinedString
- chip.setOnClickListener {
- if (onClick != null) onClick(this)
- }
- return chip
-}
-
-
-
diff --git a/app/src/main/res/drawable-hdpi/ic_round_close_24px.xml b/app/src/main/res/drawable-hdpi/ic_round_close_24px.xml
index f9711a4..6ceb4df 100644
--- a/app/src/main/res/drawable-hdpi/ic_round_close_24px.xml
+++ b/app/src/main/res/drawable-hdpi/ic_round_close_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnSurfaceLowEmphasis">
+ android:tint="@color/material_on_surface_disabled">
diff --git a/app/src/main/res/drawable/circle.xml b/app/src/main/res/drawable/circle_area.xml
similarity index 74%
rename from app/src/main/res/drawable/circle.xml
rename to app/src/main/res/drawable/circle_area.xml
index 341b1da..d156de3 100644
--- a/app/src/main/res/drawable/circle.xml
+++ b/app/src/main/res/drawable/circle_area.xml
@@ -1,4 +1,4 @@
-
+
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
deleted file mode 100644
index 0d025f9..0000000
--- a/app/src/main/res/drawable/ic_launcher_background.xml
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/drawable/ic_round_favorite_24px.xml b/app/src/main/res/drawable/ic_round_favorite_24px.xml
index e10fdb8..a9ecf04 100644
--- a/app/src/main/res/drawable/ic_round_favorite_24px.xml
+++ b/app/src/main/res/drawable/ic_round_favorite_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnSurface">
+ android:tint="?attr/colorOnSurface">
diff --git a/app/src/main/res/drawable/ic_round_favorite_border_24px.xml b/app/src/main/res/drawable/ic_round_favorite_border_24px.xml
index af0d2fd..25c80f0 100644
--- a/app/src/main/res/drawable/ic_round_favorite_border_24px.xml
+++ b/app/src/main/res/drawable/ic_round_favorite_border_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnSurfaceHighEmphasis">
+ android:tint="@color/material_on_surface_emphasis_high_type">
diff --git a/app/src/main/res/drawable/ic_round_filter_list_24px.xml b/app/src/main/res/drawable/ic_round_filter_list_24px.xml
index 21bd9ff..71e2c22 100644
--- a/app/src/main/res/drawable/ic_round_filter_list_24px.xml
+++ b/app/src/main/res/drawable/ic_round_filter_list_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnSurfaceHighEmphasis">
+ android:tint="@color/material_on_surface_emphasis_high_type">
diff --git a/app/src/main/res/drawable/ic_round_mic_24px.xml b/app/src/main/res/drawable/ic_round_mic_24px.xml
index 45fc8ae..c3f477f 100644
--- a/app/src/main/res/drawable/ic_round_mic_24px.xml
+++ b/app/src/main/res/drawable/ic_round_mic_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnBackgroundHighEmphasis">
+ android:tint="@color/material_on_background_emphasis_high_type">
diff --git a/app/src/main/res/drawable/ic_round_orientation_lock_24px.xml b/app/src/main/res/drawable/ic_round_orientation_lock_24px.xml
index cd83ba9..f81f65a 100644
--- a/app/src/main/res/drawable/ic_round_orientation_lock_24px.xml
+++ b/app/src/main/res/drawable/ic_round_orientation_lock_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnSurfaceHighEmphasis">
+ android:tint="@color/material_on_surface_emphasis_high_type">
diff --git a/app/src/main/res/drawable/ic_round_radio_checked_24px.xml b/app/src/main/res/drawable/ic_round_radio_checked_24px.xml
index 81b3122..16e65a3 100644
--- a/app/src/main/res/drawable/ic_round_radio_checked_24px.xml
+++ b/app/src/main/res/drawable/ic_round_radio_checked_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnBackgroundHighEmphasis">
+ android:tint="@color/material_on_background_emphasis_high_type">
diff --git a/app/src/main/res/drawable/ic_round_recent_outlined_24px.xml b/app/src/main/res/drawable/ic_round_recent_outlined_24px.xml
index 9d543ff..806e9d0 100644
--- a/app/src/main/res/drawable/ic_round_recent_outlined_24px.xml
+++ b/app/src/main/res/drawable/ic_round_recent_outlined_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnBackgroundHighEmphasis">
+ android:tint="@color/material_on_background_emphasis_high_type">
diff --git a/app/src/main/res/drawable/ic_round_search_outlined_24px.xml b/app/src/main/res/drawable/ic_round_search_outlined_24px.xml
index 13deb88..f61e2a1 100644
--- a/app/src/main/res/drawable/ic_round_search_outlined_24px.xml
+++ b/app/src/main/res/drawable/ic_round_search_outlined_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnBackgroundHighEmphasis">
+ android:tint="@color/material_on_background_emphasis_high_type">
diff --git a/app/src/main/res/drawable/ic_round_share_24px.xml b/app/src/main/res/drawable/ic_round_share_24px.xml
index 2febcdd..7b2dcdc 100644
--- a/app/src/main/res/drawable/ic_round_share_24px.xml
+++ b/app/src/main/res/drawable/ic_round_share_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnBackgroundHighEmphasis">
+ android:tint="@color/material_on_background_emphasis_high_type">
diff --git a/app/src/main/res/drawable/ic_round_smart_outlined_24px.xml b/app/src/main/res/drawable/ic_round_smart_outlined_24px.xml
index 0576288..aea6f30 100644
--- a/app/src/main/res/drawable/ic_round_smart_outlined_24px.xml
+++ b/app/src/main/res/drawable/ic_round_smart_outlined_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnBackgroundHighEmphasis">
+ android:tint="@color/material_on_background_emphasis_high_type">
diff --git a/app/src/main/res/drawable/permission_pane_background.xml b/app/src/main/res/drawable/permission_pane_area.xml
similarity index 79%
rename from app/src/main/res/drawable/permission_pane_background.xml
rename to app/src/main/res/drawable/permission_pane_area.xml
index c2d0835..32fd60b 100644
--- a/app/src/main/res/drawable/permission_pane_background.xml
+++ b/app/src/main/res/drawable/permission_pane_area.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/search_input_background.xml b/app/src/main/res/drawable/search_input_area.xml
similarity index 79%
rename from app/src/main/res/drawable/search_input_background.xml
rename to app/src/main/res/drawable/search_input_area.xml
index 47e61be..e21e954 100644
--- a/app/src/main/res/drawable/search_input_background.xml
+++ b/app/src/main/res/drawable/search_input_area.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/app/src/main/res/drawable/text_input_background.xml b/app/src/main/res/drawable/text_input_background.xml
index d159088..4c79405 100644
--- a/app/src/main/res/drawable/text_input_background.xml
+++ b/app/src/main/res/drawable/text_input_background.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/app/src/main/res/layout/activity_auth.xml b/app/src/main/res/layout/activity_auth.xml
index bb03bdf..d7d009b 100644
--- a/app/src/main/res/layout/activity_auth.xml
+++ b/app/src/main/res/layout/activity_auth.xml
@@ -9,7 +9,7 @@
android:layout_height="match_parent"
tools:context=".ui.auth.AuthActivity">
-
@@ -56,7 +56,7 @@
android:paddingBottom="@dimen/keyline_3"
android:orientation="vertical">
-
-
-
-
-
-
-
+ android:background="@color/scrim"/>
+ android:textColor="@color/material_on_background_emphasis_medium"
+ app:chipBackgroundColor="@color/area"
+ android:backgroundTint="@color/area" />
diff --git a/app/src/main/res/layout/fragment_contextual.xml b/app/src/main/res/layout/fragment_contextual.xml
index 194ef86..ac62b0f 100644
--- a/app/src/main/res/layout/fragment_contextual.xml
+++ b/app/src/main/res/layout/fragment_contextual.xml
@@ -49,7 +49,7 @@
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
- android:background="@drawable/circle"
+ android:background="@drawable/circle_area"
android:foreground="?selectableItemBackground"
android:padding="@dimen/keyline_2"
android:scaleType="centerInside"
diff --git a/app/src/main/res/layout/fragment_details.xml b/app/src/main/res/layout/fragment_details.xml
index bd6ea02..ac4527a 100644
--- a/app/src/main/res/layout/fragment_details.xml
+++ b/app/src/main/res/layout/fragment_details.xml
@@ -1,10 +1,9 @@
-
+ android:layout_width="match_parent">
-
+
diff --git a/app/src/main/res/layout/fragment_developer_settings.xml b/app/src/main/res/layout/fragment_developer_settings.xml
index 3f26727..a65cd90 100644
--- a/app/src/main/res/layout/fragment_developer_settings.xml
+++ b/app/src/main/res/layout/fragment_developer_settings.xml
@@ -1,11 +1,10 @@
-
+ android:layout_width="match_parent">
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_list.xml b/app/src/main/res/layout/fragment_list.xml
index 9197ecc..2184a18 100644
--- a/app/src/main/res/layout/fragment_list.xml
+++ b/app/src/main/res/layout/fragment_list.xml
@@ -1,12 +1,11 @@
-
+ android:layout_width="match_parent">
-
+
diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml
index 0e8d26c..8bde3a5 100644
--- a/app/src/main/res/layout/fragment_search.xml
+++ b/app/src/main/res/layout/fragment_search.xml
@@ -27,7 +27,7 @@
android:layout_marginStart="@dimen/keyline_2"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
- android:background="@drawable/search_input_background"
+ android:background="@drawable/search_input_area"
android:foregroundGravity="center_vertical"
android:padding="@dimen/keyline_2"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml
index f57ba35..1dc8b31 100644
--- a/app/src/main/res/layout/fragment_settings.xml
+++ b/app/src/main/res/layout/fragment_settings.xml
@@ -1,11 +1,10 @@
-
+ android:layout_width="match_parent">
-
+
diff --git a/app/src/main/res/layout/home_divider_layout.xml b/app/src/main/res/layout/home_divider_layout.xml
index e55c6cc..5e7c150 100644
--- a/app/src/main/res/layout/home_divider_layout.xml
+++ b/app/src/main/res/layout/home_divider_layout.xml
@@ -6,5 +6,5 @@
android:layout_width="72dp"
android:layout_height="2dp"
android:layout_margin="@dimen/keyline_3"
- app:trackColor="?colorOnBackgroundLowEmphasis"
- app:indicatorColor="?colorPrimary" />
+ app:trackColor="@color/material_on_background_disabled"
+ app:indicatorColor="?attr/colorPrimary" />
diff --git a/app/src/main/res/layout/smart_suggestion_item.xml b/app/src/main/res/layout/smart_suggestion_item.xml
index 316e4de..347dd4a 100644
--- a/app/src/main/res/layout/smart_suggestion_item.xml
+++ b/app/src/main/res/layout/smart_suggestion_item.xml
@@ -7,9 +7,8 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="@dimen/keyline_2"
- android:background="?selectableItemBackground"
- >
-
+ android:background="?attr/selectableItemBackground">
+
+ app:rippleColor="?attr/colorRipple" />
diff --git a/app/src/main/res/values/attrs_banner_card_view.xml b/app/src/main/res/values/attrs_banner_card_view.xml
index 17ff252..fc258d3 100644
--- a/app/src/main/res/values/attrs_banner_card_view.xml
+++ b/app/src/main/res/values/attrs_banner_card_view.xml
@@ -6,5 +6,4 @@
-
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 3a41ae9..1909c36 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -1,9 +1,6 @@
-
- 40dp
- 20dp
52dp
diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml
index 2af5055..f219fda 100644
--- a/app/src/main/res/values/ic_launcher_background.xml
+++ b/app/src/main/res/values/ic_launcher_background.xml
@@ -1,4 +1,4 @@
- #F8F5EE
+ @color/colorIvory100
\ 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 5ed9faf..486f378 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -143,4 +143,5 @@
No pronunciations available
No network available
Unable to play clip
+ Merriam-Webster Thesaurus
diff --git a/app/src/test/java/space/narrate/waylan/android/data/repository/UserRepositoryTest.kt b/app/src/test/java/space/narrate/waylan/android/data/repository/UserRepositoryTest.kt
index b2ad08a..3cd6661 100644
--- a/app/src/test/java/space/narrate/waylan/android/data/repository/UserRepositoryTest.kt
+++ b/app/src/test/java/space/narrate/waylan/android/data/repository/UserRepositoryTest.kt
@@ -16,7 +16,7 @@ import space.narrate.waylan.android.data.firestore.users.UserWord
import space.narrate.waylan.android.data.prefs.Preference
import space.narrate.waylan.android.data.prefs.PreferenceStore
import space.narrate.waylan.android.data.prefs.UserPreferenceStore
-import space.narrate.waylan.android.testDatabase
+import space.narrate.waylan.android.util.testDatabase
import space.narrate.waylan.test_common.CoroutinesTestRule
import org.mockito.Mockito.`when` as whenever
@@ -57,7 +57,6 @@ class UserRepositoryTest {
/**
* TODO: This test is flakey and should be fixed or removed.
- *
* Note: This test passes if run individually, but not during a full run of this test class.
*/
@Test
diff --git a/app/src/test/java/space/narrate/waylan/android/data/repository/WordRepositoryTest.kt b/app/src/test/java/space/narrate/waylan/android/data/repository/WordRepositoryTest.kt
index 798a039..6c4506a 100644
--- a/app/src/test/java/space/narrate/waylan/android/data/repository/WordRepositoryTest.kt
+++ b/app/src/test/java/space/narrate/waylan/android/data/repository/WordRepositoryTest.kt
@@ -40,12 +40,10 @@ class WordRepositoryTest {
private lateinit var wordRepository: WordRepository
- @get:Rule
- val coroutinesTestRule = CoroutinesTestRule()
+ @get:Rule val coroutinesTestRule = CoroutinesTestRule()
// Mock Android's getMainLooper()
- @get:Rule
- val instantExecutorRule = InstantTaskExecutorRule()
+ @get:Rule val instantExecutorRule = InstantTaskExecutorRule()
@Before
fun setUp() {
diff --git a/app/src/test/java/space/narrate/waylan/android/ui/dev/DeveloperSettingsViewModelTest.kt b/app/src/test/java/space/narrate/waylan/android/ui/dev/DeveloperSettingsViewModelTest.kt
index c5bd878..1289707 100644
--- a/app/src/test/java/space/narrate/waylan/android/ui/dev/DeveloperSettingsViewModelTest.kt
+++ b/app/src/test/java/space/narrate/waylan/android/ui/dev/DeveloperSettingsViewModelTest.kt
@@ -12,7 +12,7 @@ import org.junit.Test
import org.mockito.ArgumentCaptor
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
-import space.narrate.waylan.android.FirestoreTestData
+import space.narrate.waylan.android.util.FirestoreTestData
import space.narrate.waylan.android.data.Result
import space.narrate.waylan.android.data.firestore.users.PluginState
import space.narrate.waylan.android.data.firestore.users.User
diff --git a/app/src/test/java/space/narrate/waylan/android/ui/home/HomeFragmentTest.kt b/app/src/test/java/space/narrate/waylan/android/ui/home/HomeFragmentTest.kt
index 76e513c..4a68e15 100644
--- a/app/src/test/java/space/narrate/waylan/android/ui/home/HomeFragmentTest.kt
+++ b/app/src/test/java/space/narrate/waylan/android/ui/home/HomeFragmentTest.kt
@@ -145,7 +145,7 @@ class HomeFragmentTest: AutoCloseKoinTest() {
private fun launchFragment(navController: NavController? = null) {
val scenario = launchFragmentInContainer(
- themeResId = R.style.Theme_Words_DayNight
+ themeResId = R.style.Theme_Waylan_DayNight
)
scenario.onFragment {
if (navController != null) {
diff --git a/app/src/test/java/space/narrate/waylan/android/ui/home/HomeViewModelTest.kt b/app/src/test/java/space/narrate/waylan/android/ui/home/HomeViewModelTest.kt
index 6b4dedc..3568cdb 100644
--- a/app/src/test/java/space/narrate/waylan/android/ui/home/HomeViewModelTest.kt
+++ b/app/src/test/java/space/narrate/waylan/android/ui/home/HomeViewModelTest.kt
@@ -7,7 +7,7 @@ import org.junit.Rule
import org.junit.Test
import org.mockito.ArgumentMatchers.any
import org.mockito.Mockito.mock
-import space.narrate.waylan.android.FirestoreTestData
+import space.narrate.waylan.android.util.FirestoreTestData
import space.narrate.waylan.android.R
import space.narrate.waylan.android.data.repository.WordRepository
import space.narrate.waylan.android.ui.list.ListType
diff --git a/app/src/test/java/space/narrate/waylan/android/ui/settings/MwBannerModelTest.kt b/app/src/test/java/space/narrate/waylan/android/ui/settings/MwBannerModelTest.kt
index a377c22..1015a19 100644
--- a/app/src/test/java/space/narrate/waylan/android/ui/settings/MwBannerModelTest.kt
+++ b/app/src/test/java/space/narrate/waylan/android/ui/settings/MwBannerModelTest.kt
@@ -2,7 +2,7 @@ package space.narrate.waylan.android.ui.settings
import com.google.common.truth.Truth.assertThat
import org.junit.Test
-import space.narrate.waylan.android.FirestoreTestData
+import space.narrate.waylan.android.util.FirestoreTestData
import space.narrate.waylan.android.R
class MwBannerModelTest {
diff --git a/app/src/test/java/space/narrate/waylan/android/ui/settings/SettingsFragmentTest.kt b/app/src/test/java/space/narrate/waylan/android/ui/settings/SettingsFragmentTest.kt
index 4d40b84..9e77687 100644
--- a/app/src/test/java/space/narrate/waylan/android/ui/settings/SettingsFragmentTest.kt
+++ b/app/src/test/java/space/narrate/waylan/android/ui/settings/SettingsFragmentTest.kt
@@ -24,7 +24,7 @@ import org.koin.test.AutoCloseKoinTest
import org.mockito.Mockito.mock
import org.robolectric.annotation.LooperMode
import org.robolectric.annotation.TextLayoutMode
-import space.narrate.waylan.android.FirestoreTestData
+import space.narrate.waylan.android.util.FirestoreTestData
import space.narrate.waylan.android.R
import space.narrate.waylan.android.data.prefs.NightMode
import space.narrate.waylan.android.data.prefs.Orientation
@@ -106,7 +106,7 @@ class SettingsFragmentTest: AutoCloseKoinTest() {
private fun launchFragment(navController: NavController? = null) {
val scenario = launchFragmentInContainer(
- themeResId = R.style.Theme_Words_DayNight
+ themeResId = R.style.Theme_Waylan_DayNight
)
scenario.onFragment {
if (navController != null) {
diff --git a/app/src/test/java/space/narrate/waylan/android/ui/settings/SettingsViewModelTest.kt b/app/src/test/java/space/narrate/waylan/android/ui/settings/SettingsViewModelTest.kt
index 65e8fb7..f7bb8c0 100644
--- a/app/src/test/java/space/narrate/waylan/android/ui/settings/SettingsViewModelTest.kt
+++ b/app/src/test/java/space/narrate/waylan/android/ui/settings/SettingsViewModelTest.kt
@@ -9,7 +9,7 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.Mockito.mock
-import space.narrate.waylan.android.FirestoreTestData
+import space.narrate.waylan.android.util.FirestoreTestData
import space.narrate.waylan.android.R
import space.narrate.waylan.android.data.firestore.users.User
import space.narrate.waylan.android.data.repository.UserRepository
diff --git a/app/src/sharedTest/java/space/narrate/waylan/android/FirestoreTestDatabase.kt b/app/src/test/java/space/narrate/waylan/android/util/FirestoreTestDatabase.kt
similarity index 99%
rename from app/src/sharedTest/java/space/narrate/waylan/android/FirestoreTestDatabase.kt
rename to app/src/test/java/space/narrate/waylan/android/util/FirestoreTestDatabase.kt
index 3c492d6..b773f8e 100644
--- a/app/src/sharedTest/java/space/narrate/waylan/android/FirestoreTestDatabase.kt
+++ b/app/src/test/java/space/narrate/waylan/android/util/FirestoreTestDatabase.kt
@@ -1,4 +1,4 @@
-package space.narrate.waylan.android
+package space.narrate.waylan.android.util
import space.narrate.waylan.android.data.firestore.DataOwners
import space.narrate.waylan.android.data.firestore.users.User
diff --git a/build.gradle b/build.gradle
index 51b7600..adea70f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,7 +8,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.6.0-alpha12'
+ classpath 'com.android.tools.build:gradle:3.6.0-beta03'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:${Versions.navigation}"
diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt
index e954562..02c04e8 100644
--- a/buildSrc/src/main/java/Dependencies.kt
+++ b/buildSrc/src/main/java/Dependencies.kt
@@ -33,10 +33,13 @@ object Versions {
const val koin = "2.0.1"
const val kotlin = "1.3.50"
const val lifecycle = "2.1.0"
- const val material = "1.1.0-alpha10"
+ const val material = "1.2.0-alpha02"
const val mockito = "2.27.0"
+ const val moshi = "1.9.1"
+ const val moshiConverter = "2.6.2"
const val navigation = "2.1.0"
const val okhttp3 = "3.10.0"
+ const val okhttp3MockWebServer = "4.2.1"
const val retrofit = "2.4.0"
const val robolectric = "4.3"
const val room = "2.2.0-rc01"
@@ -55,99 +58,107 @@ object Versions {
*/
object Libs {
// AppCompat
- val appCompat = "androidx.appcompat:appcompat:${Versions.appCompat}"
+ const val appCompat = "androidx.appcompat:appcompat:${Versions.appCompat}"
// Arch
- val archCoreTesting = "androidx.arch.core:core-testing:${Versions.lifecycle}"
+ const val archCoreTesting = "androidx.arch.core:core-testing:${Versions.lifecycle}"
// Core
- val coreKtx = "androidx.core:core-ktx:${Versions.androidX}"
+ const val coreKtx = "androidx.core:core-ktx:${Versions.androidX}"
// Constraint
- val constraintLayout = "androidx.constraintlayout:constraintlayout:${Versions.constraintLayout}"
+ const val constraintLayout = "androidx.constraintlayout:constraintlayout:${Versions.constraintLayout}"
// Crashlytics
- val crashlytics = "com.crashlytics.sdk.android:crashlytics:${Versions.crashlytics}"
+ const val crashlytics = "com.crashlytics.sdk.android:crashlytics:${Versions.crashlytics}"
// Espresso
- val espresso = "androidx.test.espresso:espresso-core:${Versions.espresso}"
- val espressoContrib = "androidx.test.espresso:espresso-contrib:${Versions.espresso}"
- val espressoIdlingResource = "androidx.test.espresso:espresso-idling-resource:${Versions.espresso}"
- val espressoIdlingConcurrent = "androidx.test.espresso.idling:idling-concurrent:${Versions.espresso}"
- val espressoIntents = "androidx.test.espresso:espresso-intents:${Versions.espresso}"
+ const val espresso = "androidx.test.espresso:espresso-core:${Versions.espresso}"
+ const val espressoContrib = "androidx.test.espresso:espresso-contrib:${Versions.espresso}"
+ const val espressoIdlingResource = "androidx.test.espresso:espresso-idling-resource:${Versions.espresso}"
+ const val espressoIdlingConcurrent = "androidx.test.espresso.idling:idling-concurrent:${Versions.espresso}"
+ const val espressoIntents = "androidx.test.espresso:espresso-intents:${Versions.espresso}"
// Firebase & Firestore
- val firebase = "com.google.firebase:firebase-core:${Versions.firebaseCore}"
- val firebaseAuth = "com.google.firebase:firebase-auth:${Versions.firebaseAuth}"
- val firebaseFirestore = "com.google.firebase:firebase-firestore:${Versions.firestore}"
+ const val firebase = "com.google.firebase:firebase-core:${Versions.firebaseCore}"
+ const val firebaseAuth = "com.google.firebase:firebase-auth:${Versions.firebaseAuth}"
+ const val firebaseFirestore = "com.google.firebase:firebase-firestore:${Versions.firestore}"
// Fragment
- val fragment = "androidx.fragment:fragment:${Versions.fragment}"
- val fragmentTesting = "androidx.fragment:fragment-testing:${Versions.fragment}"
+ const val fragment = "androidx.fragment:fragment:${Versions.fragment}"
+ const val fragmentTesting = "androidx.fragment:fragment-testing:${Versions.fragment}"
// GSON
- val gson = "com.google.code.gson:gson:${Versions.gson}"
+ const val gson = "com.google.code.gson:gson:${Versions.gson}"
// Hamcrest
- val hamcrest = "org.hamcrest:hamcrest-all:${Versions.hamcrest}"
+ const val hamcrest = "org.hamcrest:hamcrest-all:${Versions.hamcrest}"
// Unit tests
- val junit = "junit:junit:${Versions.junit}"
- val junitKtx = "androidx.test.ext:junit-ktx:${Versions.testExtKotlinRunner}"
+ const val junit = "junit:junit:${Versions.junit}"
+ const val junitKtx = "androidx.test.ext:junit-ktx:${Versions.testExtKotlinRunner}"
// Koin
- val koin = "org.koin:koin-java:${Versions.koin}"
- val koinAndroidViewModel = "org.koin:koin-android-viewmodel:${Versions.koin}"
- val koinTest = "org.koin:koin-test:${Versions.koin}"
+ const val koin = "org.koin:koin-java:${Versions.koin}"
+ const val koinAndroidViewModel = "org.koin:koin-android-viewmodel:${Versions.koin}"
+ const val koinTest = "org.koin:koin-test:${Versions.koin}"
// Kotlin
- val kotlin = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Versions.kotlin}"
- val kotlinCoroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.coroutines}"
- val kotlinCoroutinesAndroid = "org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.coroutines}"
- val kotlinCoroutinesTest = "org.jetbrains.kotlinx:kotlinx-coroutines-test:${Versions.coroutines}"
+ const val kotlin = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Versions.kotlin}"
+ const val kotlinCoroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.coroutines}"
+ const val kotlinCoroutinesAndroid = "org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.coroutines}"
+ const val kotlinCoroutinesTest = "org.jetbrains.kotlinx:kotlinx-coroutines-test:${Versions.coroutines}"
// AndroidX
- val lifecycleExtensions = "androidx.lifecycle:lifecycle-extensions:${Versions.lifecycle}"
- val lifecycleCompiler = "androidx.lifecycle:lifecycle-compiler:${Versions.lifecycle}"
+ const val lifecycleExtensions = "androidx.lifecycle:lifecycle-extensions:${Versions.lifecycle}"
+ const val lifecycleCompiler = "androidx.lifecycle:lifecycle-compiler:${Versions.lifecycle}"
// Material
- val material = "com.google.android.material:material:${Versions.material}"
+ const val material = "com.google.android.material:material:${Versions.material}"
// Mockito
- val mockito = "org.mockito:mockito-core:${Versions.mockito}"
- val mockitoInline = "org.mockito:mockito-inline:${Versions.mockito}"
+ const val mockito = "org.mockito:mockito-core:${Versions.mockito}"
+ const val mockitoInline = "org.mockito:mockito-inline:${Versions.mockito}"
+
+ const val moshiKotlin = "com.squareup.moshi:moshi-kotlin:${Versions.moshi}"
+ const val moshiAdapter = "com.squareup.moshi:moshi-adapters:${Versions.moshi}"
+ const val moshiCodegen = "com.squareup.moshi:moshi-kotlin-codegen:${Versions.moshi}"
// Navigation
- val navigationFragmentKtx = "androidx.navigation:navigation-fragment-ktx:${Versions.navigation}"
- val navigationUiKtx = "androidx.navigation:navigation-ui-ktx:${Versions.navigation}"
+ const val navigationFragmentKtx = "androidx.navigation:navigation-fragment-ktx:${Versions.navigation}"
+ const val navigationUiKtx = "androidx.navigation:navigation-ui-ktx:${Versions.navigation}"
+
+ //OkHttp
+ const val okhttp3MockWebServer = "com.squareup.okhttp3:mockwebserver:${Versions.okhttp3MockWebServer}"
// Google Play Billing
- val playBilling = "com.android.billingclient:billing:${Versions.googlePlayBilling}"
+ const val playBilling = "com.android.billingclient:billing:${Versions.googlePlayBilling}"
// Retrofit
- val retrofit = "com.squareup.retrofit2:retrofit:${Versions.retrofit}"
- val retrofitConverterSimpleXml = "com.squareup.retrofit2:converter-simplexml:${Versions.retrofit}"
- val retrofitLoggingInterceptor = "com.squareup.okhttp3:logging-interceptor:${Versions.okhttp3}"
+ const val retrofit = "com.squareup.retrofit2:retrofit:${Versions.retrofit}"
+ const val retrofitConverterSimpleXml = "com.squareup.retrofit2:converter-simplexml:${Versions.retrofit}"
+ const val retrofitMoshiConverter = "com.squareup.retrofit2:converter-moshi:${Versions.moshiConverter}"
+ const val retrofitLoggingInterceptor = "com.squareup.okhttp3:logging-interceptor:${Versions.okhttp3}"
// Robolectric
- val robolectric = "org.robolectric:robolectric:${Versions.robolectric}"
- val robolectricAnnotations = "org.robolectric:annotations:${Versions.robolectric}"
+ const val robolectric = "org.robolectric:robolectric:${Versions.robolectric}"
+ const val robolectricAnnotations = "org.robolectric:annotations:${Versions.robolectric}"
// Room
- val roomRuntime = "androidx.room:room-runtime:${Versions.room}"
- val roomCompiler = "androidx.room:room-compiler:${Versions.room}"
- val roomTesting = "androidx.room:room-testing:${Versions.room}"
+ const val roomRuntime = "androidx.room:room-runtime:${Versions.room}"
+ const val roomCompiler = "androidx.room:room-compiler:${Versions.room}"
+ const val roomTesting = "androidx.room:room-testing:${Versions.room}"
// ThreeTen BP - Date & Time and GSON adapter
- val threeTenBp = "org.threeten:threetenbp:${Versions.threetenbp}"
- val threeTenBpGsonAdapter = "org.aaronhe:threetenbp-gson-adapter:${Versions.threetenbpGson}"
+ const val threeTenBp = "org.threeten:threetenbp:${Versions.threetenbp}"
+ const val threeTenBpGsonAdapter = "org.aaronhe:threetenbp-gson-adapter:${Versions.threetenbpGson}"
// AndroidX Testing
- val testCore = "androidx.test:core:${Versions.testCore}"
- val testCoreKtx = "androidx.test:core-ktx:${Versions.testCoreKtx}"
- val testRules = "androidx.test:rules:${Versions.testRules}"
+ const val testCore = "androidx.test:core:${Versions.testCore}"
+ const val testCoreKtx = "androidx.test:core-ktx:${Versions.testCoreKtx}"
+ const val testRules = "androidx.test:rules:${Versions.testRules}"
// Google Truth
- val truth = "com.google.truth:truth:${Versions.googleTruth}"
+ const val truth = "com.google.truth:truth:${Versions.googleTruth}"
}
\ No newline at end of file
diff --git a/core/build.gradle b/core/build.gradle
index 177430f..10dc053 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -7,6 +7,7 @@ apply plugin: 'kotlin-kapt'
apply plugin: "androidx.navigation.safeargs.kotlin"
apply from: '../shared_dependencies.gradle'
+apply from: '../test_dependencies.gradle'
android {
compileSdkVersion Versions.compileSdk
diff --git a/core/src/main/java/space/narrate/waylan/core/details/DetailAdapterListener.kt b/core/src/main/java/space/narrate/waylan/core/details/DetailAdapterListener.kt
index 98fa471..36dae98 100644
--- a/core/src/main/java/space/narrate/waylan/core/details/DetailAdapterListener.kt
+++ b/core/src/main/java/space/narrate/waylan/core/details/DetailAdapterListener.kt
@@ -1,11 +1,12 @@
package space.narrate.waylan.core.details
import space.narrate.waylan.core.merriamwebster.MerriamWebsterCardListener
+import space.narrate.waylan.core.merriamwebster_thesaurus.MerriamWebsterThesaurusCardListener
/**
* An interface which the details screen uses to delegate user actions back to each
* DetailDataItem's owning module.
*/
-interface DetailAdapterListener : MerriamWebsterCardListener {
+interface DetailAdapterListener : MerriamWebsterCardListener, MerriamWebsterThesaurusCardListener {
fun onSynonymChipClicked(synonym: String)
}
\ No newline at end of file
diff --git a/core/src/main/java/space/narrate/waylan/core/details/DetailItemType.kt b/core/src/main/java/space/narrate/waylan/core/details/DetailItemType.kt
index fb63ecc..8527642 100644
--- a/core/src/main/java/space/narrate/waylan/core/details/DetailItemType.kt
+++ b/core/src/main/java/space/narrate/waylan/core/details/DetailItemType.kt
@@ -6,5 +6,9 @@ package space.narrate.waylan.core.details
* [order] is the order in which each item should be displayed vertically.
*/
enum class DetailItemType(val order: Int) {
- TITLE(1), MERRIAM_WEBSTER(2), WORDSET(3), EXAMPLE(4)
+ TITLE(1),
+ MERRIAM_WEBSTER(2),
+ MERRIAM_WEBSTER_THESAURUS(3),
+ WORDSET(4),
+ EXAMPLE(5)
}
\ No newline at end of file
diff --git a/core/src/main/java/space/narrate/waylan/core/merriamwebster/MerriamWebsterCardListener.kt b/core/src/main/java/space/narrate/waylan/core/merriamwebster/MerriamWebsterCardListener.kt
index 761b0c9..d2adc27 100644
--- a/core/src/main/java/space/narrate/waylan/core/merriamwebster/MerriamWebsterCardListener.kt
+++ b/core/src/main/java/space/narrate/waylan/core/merriamwebster/MerriamWebsterCardListener.kt
@@ -1,5 +1,9 @@
package space.narrate.waylan.core.merriamwebster
+/**
+ * An interface which allows clients which display a MerriamWebsterCardView to listen
+ * to events which happen on that view when the client does not depend on :merriamwebster.
+ */
interface MerriamWebsterCardListener {
fun onMwRelatedWordClicked(word: String)
fun onMwSuggestionWordClicked(word: String)
diff --git a/core/src/main/java/space/narrate/waylan/core/merriamwebster_thesaurus/MerriamWebsterThesaurusCardListener.kt b/core/src/main/java/space/narrate/waylan/core/merriamwebster_thesaurus/MerriamWebsterThesaurusCardListener.kt
new file mode 100644
index 0000000..4d21e20
--- /dev/null
+++ b/core/src/main/java/space/narrate/waylan/core/merriamwebster_thesaurus/MerriamWebsterThesaurusCardListener.kt
@@ -0,0 +1,8 @@
+package space.narrate.waylan.core.merriamwebster_thesaurus
+/**
+ * An interface which allows clients which display a MerriamWebsterCardViewThesaurus to listen
+ * to events which happen on that view when the client does not depend on :merriamwebster_thesaurus.
+ */
+interface MerriamWebsterThesaurusCardListener {
+ fun onMwThesaurusChipClicked(word: String)
+}
\ No newline at end of file
diff --git a/core/src/main/java/space/narrate/waylan/core/ui/widget/ProgressUnderlineView.kt b/core/src/main/java/space/narrate/waylan/core/ui/widget/ProgressUnderlineView.kt
index 4182b89..ee8da1e 100644
--- a/core/src/main/java/space/narrate/waylan/core/ui/widget/ProgressUnderlineView.kt
+++ b/core/src/main/java/space/narrate/waylan/core/ui/widget/ProgressUnderlineView.kt
@@ -2,14 +2,22 @@ package space.narrate.waylan.core.ui.widget
import android.animation.ValueAnimator
import android.content.Context
-import android.graphics.*
+import android.content.res.ColorStateList
+import android.content.res.TypedArray
+import android.graphics.Canvas
+import android.graphics.Outline
+import android.graphics.Paint
import android.graphics.Paint.ANTI_ALIAS_FLAG
+import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import android.view.ViewOutlineProvider
+import androidx.annotation.StyleableRes
import androidx.core.graphics.withTranslation
import space.narrate.waylan.core.R
import space.narrate.waylan.core.util.MathUtils
+import space.narrate.waylan.core.util.getColorFromAttr
+import space.narrate.waylan.core.util.getColorStateList
/**
* A View that acts as a simple underline when not showing progress and a linear, indeterminate
@@ -77,11 +85,19 @@ class ProgressUnderlineView @JvmOverloads constructor(
)
trackPaint = Paint(ANTI_ALIAS_FLAG).apply {
- color = a.getColor(R.styleable.ProgressUnderlineView_trackColor, 0)
+ color = a.getColorStateList(
+ context,
+ R.styleable.ProgressUnderlineView_trackColor,
+ R.attr.colorControlNormal
+ ).defaultColor
style = Paint.Style.FILL
}
indicatorPaint = Paint(ANTI_ALIAS_FLAG).apply {
- color = a.getColor(R.styleable.ProgressUnderlineView_indicatorColor, 0)
+ color = a.getColorStateList(
+ context,
+ R.styleable.ProgressUnderlineView_indicatorColor,
+ R.attr.colorPrimary
+ ).defaultColor
style = Paint.Style.FILL
}
@@ -188,7 +204,7 @@ class ProgressUnderlineView @JvmOverloads constructor(
}
companion object {
- private val DEF_STYLE_RES = R.style.Widget_Words_ProgressUnderlineView
+ private val DEF_STYLE_RES = R.style.Widget_Waylan_ProgressUnderlineView
private const val ANIM_DURATION = 2000L
}
}
\ No newline at end of file
diff --git a/app/src/main/java/space/narrate/waylan/android/ui/widget/ScrimmedFrameLayout.kt b/core/src/main/java/space/narrate/waylan/core/ui/widget/ScrimWindowLayout.kt
similarity index 53%
rename from app/src/main/java/space/narrate/waylan/android/ui/widget/ScrimmedFrameLayout.kt
rename to core/src/main/java/space/narrate/waylan/core/ui/widget/ScrimWindowLayout.kt
index a36b57e..f9955c7 100644
--- a/app/src/main/java/space/narrate/waylan/android/ui/widget/ScrimmedFrameLayout.kt
+++ b/core/src/main/java/space/narrate/waylan/core/ui/widget/ScrimWindowLayout.kt
@@ -1,32 +1,39 @@
-package space.narrate.waylan.android.ui.widget
+package space.narrate.waylan.core.ui.widget
import android.content.Context
+import android.content.res.ColorStateList
import android.util.AttributeSet
import android.view.Gravity
import android.view.View
import android.view.WindowInsets
import android.widget.FrameLayout
+import androidx.core.content.res.use
import androidx.core.view.children
import com.google.android.material.appbar.AppBarLayout
-import space.narrate.waylan.core.util.getColorFromAttr
+import space.narrate.waylan.core.R
+import space.narrate.waylan.core.util.getColorStateList
import space.narrate.waylan.core.util.invisible
import space.narrate.waylan.core.util.visible
/**
- * A FrameLayout which adds a status bar scrim to the top of the screen.
+ * A FrameLayout which adds a status bar scrim to the top of the screen and a background color
+ * to a layout.
+ *
+ * This is helpful when dragging to dismiss a layout. This can be used as the root layout and
+ * be excluded from the views being "dragged", causing a scrim to show below the content,
+ * helping show the top of the content is separating from the window.
*
* If the layout has a collapsing AppBarLayout, the status bar scrim will be invisible if the
* ABL is fully expanded and turn visible when the ABL begins to scroll.
*/
-class ScrimmedFrameLayout @JvmOverloads constructor(
+class ScrimWindowLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
- defStyleAttr: Int = 0,
- defStyleRes: Int = 0
+ defStyleAttr: Int = DEF_STYLE_ATTR,
+ defStyleRes: Int = DEF_STYLE_RES
) : FrameLayout(context, attrs, defStyleAttr, defStyleRes) {
private val statusBarScrim = View(context).apply {
- setBackgroundColor(context.getColorFromAttr(android.R.attr.colorBackground))
layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
0
@@ -36,6 +43,27 @@ class ScrimmedFrameLayout @JvmOverloads constructor(
}
init {
+ getContext().theme.obtainStyledAttributes(
+ attrs,
+ R.styleable.ScrimWindowLayout,
+ defStyleAttr,
+ defStyleRes
+ ).use {
+ val backgroundTint = it.getColorStateList(
+ context,
+ R.styleable.ScrimWindowLayout_backgroundTint,
+ android.R.attr.colorBackground
+ )
+
+ val statusBarTint = it.getColorStateList(
+ context,
+ R.styleable.ScrimWindowLayout_statusBarScrimTint,
+ android.R.attr.colorBackground
+ )
+
+ setBackgroundColor(backgroundTint.defaultColor)
+ statusBarScrim.setBackgroundColor(statusBarTint.defaultColor)
+ }
clipToPadding = false
clipChildren = false
}
@@ -63,4 +91,9 @@ class ScrimmedFrameLayout @JvmOverloads constructor(
return null
}
+
+ companion object {
+ private val DEF_STYLE_ATTR = R.attr.styleScrimWindow
+ private val DEF_STYLE_RES = R.style.Widget_Waylan_ScrimWindow
+ }
}
\ No newline at end of file
diff --git a/core/src/main/java/space/narrate/waylan/core/util/SnackbarExtensions.kt b/core/src/main/java/space/narrate/waylan/core/util/SnackbarExtensions.kt
index 33c78b1..e82be21 100644
--- a/core/src/main/java/space/narrate/waylan/core/util/SnackbarExtensions.kt
+++ b/core/src/main/java/space/narrate/waylan/core/util/SnackbarExtensions.kt
@@ -72,8 +72,8 @@ private fun Snackbar.config(
context.resources.getDimension(R.dimen.plane_03)
)
DrawableCompat.setTint(background, backgroundTint)
- val textAppearance = R.style.TextAppearance_Words_Body1
- val buttonTextAppearance = R.style.TextAppearance_Words_Button
+ val textAppearance = R.style.TextAppearance_Waylan_Body1
+ val buttonTextAppearance = R.style.TextAppearance_Waylan_Button
val textColor = when (type) {
SnackbarType.ERROR -> context.getColorFromAttr(R.attr.colorOnError)
SnackbarType.INFORMATIVE -> context.getColorFromAttr(R.attr.colorOnSurface)
diff --git a/core/src/main/java/space/narrate/waylan/core/util/TypedArrayExtensions.kt b/core/src/main/java/space/narrate/waylan/core/util/TypedArrayExtensions.kt
new file mode 100644
index 0000000..39c6b78
--- /dev/null
+++ b/core/src/main/java/space/narrate/waylan/core/util/TypedArrayExtensions.kt
@@ -0,0 +1,19 @@
+package space.narrate.waylan.core.util
+
+import android.content.Context
+import android.content.res.ColorStateList
+import android.content.res.TypedArray
+import androidx.annotation.AttrRes
+import androidx.annotation.StyleableRes
+
+/**
+ * Get the [ColorStateList] from the given [index]. If the index is null, return a ColorStateList
+ * of [defColor].
+ */
+fun TypedArray.getColorStateList(
+ context: Context,
+ @StyleableRes index: Int,
+ @AttrRes defColor: Int
+): ColorStateList {
+ return getColorStateList(index) ?: ColorStateList.valueOf(context.getColorFromAttr(defColor))
+}
\ No newline at end of file
diff --git a/core/src/main/java/space/narrate/waylan/core/util/ViewExtensions.kt b/core/src/main/java/space/narrate/waylan/core/util/ViewExtensions.kt
index d8b4001..700b195 100644
--- a/core/src/main/java/space/narrate/waylan/core/util/ViewExtensions.kt
+++ b/core/src/main/java/space/narrate/waylan/core/util/ViewExtensions.kt
@@ -4,16 +4,19 @@ import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
+import android.content.Context
+import android.view.LayoutInflater
import android.view.View
-import android.view.ViewGroup
import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator
import android.widget.ImageView
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import com.google.android.material.appbar.AppBarLayout
+import com.google.android.material.chip.Chip
+import com.google.android.material.chip.ChipGroup
+import space.narrate.waylan.core.R
import space.narrate.waylan.core.ui.widget.ElasticAppBarBehavior
-import java.lang.IllegalArgumentException
fun View.gone() {
if (visibility != View.GONE) visibility = View.GONE
@@ -27,6 +30,9 @@ fun View.visible() {
if (visibility != View.VISIBLE) visibility = View.VISIBLE
}
+val View.inflater: LayoutInflater
+ get() = LayoutInflater.from(context)
+
fun ImageView.swapImageResource(imgRes: Int) {
// Check if the drawable being set is the same as what is already present
val currantDrawableState = drawable.constantState
@@ -67,3 +73,21 @@ fun AppBarLayout.setUpWithElasticBehavior(
}
+fun String.toChip(
+ context: Context,
+ chipGroup: ChipGroup?,
+ onClick: ((value: String) -> Unit)? = null
+): Chip {
+ val chip: Chip = LayoutInflater.from(context).inflate(
+ R.layout.chip_layout,
+ chipGroup,
+ false
+ ) as Chip
+ chip.text = this
+ chip.setOnClickListener {
+ if (onClick != null) onClick(this)
+ }
+ return chip
+}
+
+
diff --git a/core/src/main/res/color/area.xml b/core/src/main/res/color/area.xml
new file mode 100644
index 0000000..1cda894
--- /dev/null
+++ b/core/src/main/res/color/area.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/core/src/main/res/color/divider.xml b/core/src/main/res/color/divider.xml
new file mode 100644
index 0000000..0c1513c
--- /dev/null
+++ b/core/src/main/res/color/divider.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/core/src/main/res/color/hairline.xml b/core/src/main/res/color/hairline.xml
new file mode 100644
index 0000000..d9236c1
--- /dev/null
+++ b/core/src/main/res/color/hairline.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/core/src/main/res/color/on_error_emphasis_disabled.xml b/core/src/main/res/color/on_error_emphasis_disabled.xml
new file mode 100644
index 0000000..d77f533
--- /dev/null
+++ b/core/src/main/res/color/on_error_emphasis_disabled.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/core/src/main/res/color/on_error_emphasis_high_type.xml b/core/src/main/res/color/on_error_emphasis_high_type.xml
new file mode 100644
index 0000000..6d85650
--- /dev/null
+++ b/core/src/main/res/color/on_error_emphasis_high_type.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/core/src/main/res/color/on_error_emphasis_medium.xml b/core/src/main/res/color/on_error_emphasis_medium.xml
new file mode 100644
index 0000000..bf07ce9
--- /dev/null
+++ b/core/src/main/res/color/on_error_emphasis_medium.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/core/src/main/res/color/scrim.xml b/core/src/main/res/color/scrim.xml
new file mode 100644
index 0000000..06c7478
--- /dev/null
+++ b/core/src/main/res/color/scrim.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/core/src/main/res/drawable/ic_round_arrow_down_24px.xml b/core/src/main/res/drawable/ic_round_arrow_down_24px.xml
index c03c11f..16bf201 100644
--- a/core/src/main/res/drawable/ic_round_arrow_down_24px.xml
+++ b/core/src/main/res/drawable/ic_round_arrow_down_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnBackgroundHighEmphasis">
+ android:tint="@color/material_on_background_emphasis_high_type">
diff --git a/core/src/main/res/drawable/ic_round_check_circle_24px.xml b/core/src/main/res/drawable/ic_round_check_circle_24px.xml
index dff2a48..e571bba 100644
--- a/core/src/main/res/drawable/ic_round_check_circle_24px.xml
+++ b/core/src/main/res/drawable/ic_round_check_circle_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnBackgroundHighEmphasis">
+ android:tint="@color/material_on_background_emphasis_high_type">
diff --git a/core/src/main/res/drawable/ic_round_check_circle_outline_24px.xml b/core/src/main/res/drawable/ic_round_check_circle_outline_24px.xml
index abafc3c..ad21671 100644
--- a/core/src/main/res/drawable/ic_round_check_circle_outline_24px.xml
+++ b/core/src/main/res/drawable/ic_round_check_circle_outline_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnBackgroundHighEmphasis">
+ android:tint="@color/material_on_background_emphasis_high_type">
diff --git a/core/src/main/res/drawable/list_item_divider.xml b/core/src/main/res/drawable/list_item_divider.xml
index 4f9bd80..837f342 100644
--- a/core/src/main/res/drawable/list_item_divider.xml
+++ b/core/src/main/res/drawable/list_item_divider.xml
@@ -2,6 +2,6 @@
-
+
diff --git a/core/src/main/res/drawable/window_background_translucent.xml b/core/src/main/res/drawable/window_background_translucent.xml
index 8316b50..5abce1d 100644
--- a/core/src/main/res/drawable/window_background_translucent.xml
+++ b/core/src/main/res/drawable/window_background_translucent.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/app/src/main/res/layout/details_chip_layout.xml b/core/src/main/res/layout/chip_layout.xml
similarity index 100%
rename from app/src/main/res/layout/details_chip_layout.xml
rename to core/src/main/res/layout/chip_layout.xml
diff --git a/core/src/main/res/values-night/color.xml b/core/src/main/res/values-night/color.xml
deleted file mode 100644
index df682e9..0000000
--- a/core/src/main/res/values-night/color.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
- @color/colorPink100
-
- @color/colorGray900
- @color/colorGray900
- @color/colorMauve300
- @color/colorPink900
-
- @color/colorWhiteAlpha005
- @color/colorWhiteAlpha005
- @color/colorMauveDarkAlpha022
-
- @color/colorGray900
-
- @color/colorWhiteAlpha087
- @color/colorWhiteAlpha087
- @color/colorWhiteAlpha060
- @color/colorWhiteAlpha038
-
- @color/colorMauve300
-
- @color/colorWhiteAlpha087
- @color/colorWhiteAlpha087
- @color/colorWhiteAlpha060
- @color/colorWhiteAlpha038
-
- @color/colorBlackAlpha087
- @color/colorBlackAlpha087
- @color/colorBlackAlpha060
- @color/colorBlackAlpha038
-
- @color/colorPink100
-
- @color/colorGray500
- @color/colorBlackAlpha025
- @color/colorWhiteAlpha005
- @color/colorWhiteAlpha025
-
-
\ No newline at end of file
diff --git a/core/src/main/res/values-night/themes.xml b/core/src/main/res/values-night/themes.xml
index 271ec21..6e06251 100644
--- a/core/src/main/res/values-night/themes.xml
+++ b/core/src/main/res/values-night/themes.xml
@@ -1,8 +1,35 @@
-
+
+
+
-
-
-
-
-
-
-
+
+
+
+
-
+
+
+
diff --git a/core/src/main/res/values/themes.xml b/core/src/main/res/values/themes.xml
index 93077f8..bd8e5e1 100644
--- a/core/src/main/res/values/themes.xml
+++ b/core/src/main/res/values/themes.xml
@@ -1,61 +1,54 @@
-
+
-
-
-
-
-
-
-
-
-
-
diff --git a/core/src/test/java/space/narrate/waylan/core/ExampleUnitTest.kt b/core/src/test/java/space/narrate/waylan/core/MathUtilsTest.kt
similarity index 100%
rename from core/src/test/java/space/narrate/waylan/core/ExampleUnitTest.kt
rename to core/src/test/java/space/narrate/waylan/core/MathUtilsTest.kt
diff --git a/merriamwebster/build.gradle b/merriamwebster/build.gradle
index cd0e77b..8938e36 100644
--- a/merriamwebster/build.gradle
+++ b/merriamwebster/build.gradle
@@ -21,7 +21,7 @@ android {
}
}
- // Merriam Webster Key - hidden from VCS
+ // Merriam Webster key - hidden from VCS
def keyProperties = new Properties()
keyProperties.load(rootProject.file("keys.properties").newDataInputStream())
def mwApiKey = keyProperties.getProperty("merriamWebster.key", "")
@@ -59,13 +59,4 @@ dependencies {
// TODO: Deprecated in 1.1.0-alpha01 and should be replaced with LiveData
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
-
- // Room
- implementation Libs.roomRuntime
- kapt Libs.roomCompiler
-
- // Retrofit
- implementation Libs.retrofit
- implementation Libs.retrofitConverterSimpleXml
- implementation Libs.retrofitLoggingInterceptor
}
diff --git a/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/data/remote/MerriamWebsterStore.kt b/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/data/remote/MerriamWebsterStore.kt
index f7a34ee..1b865b7 100644
--- a/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/data/remote/MerriamWebsterStore.kt
+++ b/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/data/remote/MerriamWebsterStore.kt
@@ -78,14 +78,14 @@ class MerriamWebsterStore(
* data.
*/
private fun getMerriamWebsterApiWordCallback(word: String) = object : Callback {
- override fun onFailure(call: Call?, t: Throwable?) {
+ override fun onFailure(call: Call, t: Throwable) {
// TODO: Handle failure.
- t?.printStackTrace()
+ t.printStackTrace()
}
- override fun onResponse(call: Call?, response: Response?) {
+ override fun onResponse(call: Call, response: Response) {
//Save to db
- response?.body()?.let { entryList ->
+ response.body()?.let { entryList ->
launch {
diff --git a/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/di/MerriamWebsterModuleProviderFactory.kt b/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/di/MerriamWebsterModuleProviderFactory.kt
index 2c612e5..31d58cd 100644
--- a/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/di/MerriamWebsterModuleProviderFactory.kt
+++ b/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/di/MerriamWebsterModuleProviderFactory.kt
@@ -30,11 +30,9 @@ class MerriamWebsterModuleProviderFactory : DetailProviderFactory {
}
}
- override fun getDetailDataProvider(): DetailDataProvider {
- return getKoin().get()
- }
+ override fun getDetailDataProvider(): DetailDataProvider =
+ getKoin().get()
- override fun getDetailItemProvider(): DetailItemProvider {
- return getKoin().get()
- }
+ override fun getDetailItemProvider(): DetailItemProvider =
+ getKoin().get()
}
\ No newline at end of file
diff --git a/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterDetailDataProvider.kt b/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterDetailDataProvider.kt
index c08096e..0ee931e 100644
--- a/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterDetailDataProvider.kt
+++ b/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterDetailDataProvider.kt
@@ -8,8 +8,8 @@ import space.narrate.waylan.core.details.DetailItemModel
import space.narrate.waylan.merriamwebster.data.MerriamWebsterRepository
/**
- * A data provider which knows how to fetch a [MerriamWebsterModel] to be displayed by the
- * details screen.
+ * A [DetailDataProvider] which knows how to fetch a [MerriamWebsterModel] to be displayed by
+ * the details screen.
*
* TODO: Moved user permission pane check from DetailsViewModel to here.
*/
diff --git a/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterDetailItemProvider.kt b/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterDetailItemProvider.kt
index 97e63b6..af92be6 100644
--- a/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterDetailItemProvider.kt
+++ b/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterDetailItemProvider.kt
@@ -10,8 +10,8 @@ import space.narrate.waylan.core.util.AdapterUtils
import space.narrate.waylan.merriamwebster.R
/**
- * An item provider which knows how to create a ViewHolder for the [DetailItemType.MERRIAM_WEBSTER]
- * item type
+ * A [DetailItemProvider] which knows how to create a ViewHolder for the
+ * [DetailItemType.MERRIAM_WEBSTER] item type
*/
class MerriamWebsterDetailItemProvider : DetailItemProvider {
diff --git a/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterItemBinder.kt b/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterItemBinder.kt
index 422a343..35392e1 100644
--- a/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterItemBinder.kt
+++ b/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterItemBinder.kt
@@ -4,10 +4,10 @@ import android.view.View
import androidx.appcompat.widget.AppCompatTextView
import com.google.android.material.button.MaterialButton
import com.google.android.material.chip.ChipGroup
+import space.narrate.waylan.core.util.fromHtml
import space.narrate.waylan.merriamwebster.R
+import space.narrate.waylan.merriamwebster.util.toRelatedChip
import space.narrate.waylan.android.R as appR
-import space.narrate.waylan.android.util.toRelatedChip
-import space.narrate.waylan.core.util.fromHtml
/**
* A sealed class which holds object that know how to bind a [MerriamWebsterList] to the view
diff --git a/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterModel.kt b/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterModel.kt
index 8d040ea..29063e0 100644
--- a/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterModel.kt
+++ b/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/ui/MerriamWebsterModel.kt
@@ -7,8 +7,8 @@ import space.narrate.waylan.core.details.DetailItemModel
import space.narrate.waylan.core.details.DetailItemType
/**
- * Merriam-Webster's data item model which is used to construct a DataItemViewHolder that is able
- * to be displayed by the details screen.
+ * Merriam-Webster's [DetailItemModel] which is used to construct a DetailItemViewHolder that
+ * is able to be displayed by the details screen.
*/
class MerriamWebsterModel(
val entries: List,
diff --git a/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/util/ViewExtensions.kt b/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/util/ViewExtensions.kt
new file mode 100644
index 0000000..4780157
--- /dev/null
+++ b/merriamwebster/src/main/java/space/narrate/waylan/merriamwebster/util/ViewExtensions.kt
@@ -0,0 +1,28 @@
+package space.narrate.waylan.merriamwebster.util
+
+import android.content.Context
+import android.text.SpannableString
+import android.text.style.UnderlineSpan
+import android.view.LayoutInflater
+import com.google.android.material.chip.Chip
+import com.google.android.material.chip.ChipGroup
+import space.narrate.waylan.merriamwebster.R
+
+fun String.toRelatedChip(
+ context: Context,
+ chipGroup: ChipGroup?,
+ onClick: ((word: String) -> Unit)? = null
+): Chip {
+ val chip: Chip = LayoutInflater.from(context).inflate(
+ R.layout.merriam_webster_related_chip_layout,
+ chipGroup,
+ false
+ ) as Chip
+ val underlinedString = SpannableString(this)
+ underlinedString.setSpan(UnderlineSpan(),0,this.length,0)
+ chip.text = underlinedString
+ chip.setOnClickListener {
+ if (onClick != null) onClick(this)
+ }
+ return chip
+}
\ No newline at end of file
diff --git a/merriamwebster/src/main/res/drawable/ic_round_play_arrow_24px.xml b/merriamwebster/src/main/res/drawable/ic_round_play_arrow_24px.xml
index 4d3c670..ebfa21d 100644
--- a/merriamwebster/src/main/res/drawable/ic_round_play_arrow_24px.xml
+++ b/merriamwebster/src/main/res/drawable/ic_round_play_arrow_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnBackgroundHighEmphasis">
+ android:tint="@color/material_on_background_emphasis_high_type">
diff --git a/merriamwebster/src/main/res/drawable/ic_round_stop_24px.xml b/merriamwebster/src/main/res/drawable/ic_round_stop_24px.xml
index 49d9695..b8dfde8 100644
--- a/merriamwebster/src/main/res/drawable/ic_round_stop_24px.xml
+++ b/merriamwebster/src/main/res/drawable/ic_round_stop_24px.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?colorOnBackgroundHighEmphasis">
+ android:tint="@color/material_on_background_emphasis_high_type">
diff --git a/merriamwebster/src/main/res/layout/merriam_webster_audio_view_layout.xml b/merriamwebster/src/main/res/layout/merriam_webster_audio_view_layout.xml
index ff4e29d..523f2f4 100644
--- a/merriamwebster/src/main/res/layout/merriam_webster_audio_view_layout.xml
+++ b/merriamwebster/src/main/res/layout/merriam_webster_audio_view_layout.xml
@@ -16,7 +16,7 @@
android:id="@+id/underline"
android:layout_width="@dimen/underline_width"
android:layout_height="@dimen/underline_height"
- app:trackColor="?attr/colorDivider"
+ app:trackColor="@color/divider"
app:indicatorColor="?attr/colorPrimary"
android:layout_marginTop="@dimen/keyline_2"
android:layout_gravity="right" />
diff --git a/merriamwebster/src/main/res/layout/merriam_webster_item_layout.xml b/merriamwebster/src/main/res/layout/merriam_webster_item_layout.xml
index 8a43d0d..ed1e3a1 100644
--- a/merriamwebster/src/main/res/layout/merriam_webster_item_layout.xml
+++ b/merriamwebster/src/main/res/layout/merriam_webster_item_layout.xml
@@ -13,5 +13,5 @@
android:paddingBottom="@dimen/keyline_3"
app:cardElevation="@dimen/plane_01"
app:cardCornerRadius="@dimen/keyline_2"
- app:cardBackgroundColor="?colorSurface"
+ app:cardBackgroundColor="?attr/colorSurface"
android:clipToPadding="false" />
\ No newline at end of file
diff --git a/merriamwebster/src/main/res/layout/merriam_webster_permission_pane_layout.xml b/merriamwebster/src/main/res/layout/merriam_webster_permission_pane_layout.xml
index 16ebdd9..1d11c77 100644
--- a/merriamwebster/src/main/res/layout/merriam_webster_permission_pane_layout.xml
+++ b/merriamwebster/src/main/res/layout/merriam_webster_permission_pane_layout.xml
@@ -14,17 +14,17 @@
android:layout_height="28dp"
android:layout_marginTop="@dimen/keyline_2"
android:layout_marginBottom="@dimen/keyline_1"
- android:background="@drawable/permission_pane_background"/>
+ android:background="@drawable/permission_pane_area"/>
+ android:background="@drawable/permission_pane_area"/>
-
-
+
+
+
+
+
+
+
+
+
diff --git a/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/MerriamWebsterThesaurusRepository.kt b/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/MerriamWebsterThesaurusRepository.kt
new file mode 100644
index 0000000..4efc8bc
--- /dev/null
+++ b/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/MerriamWebsterThesaurusRepository.kt
@@ -0,0 +1,17 @@
+package space.narrate.waylan.merriamwebster_thesaurus.data
+
+import androidx.lifecycle.LiveData
+import space.narrate.waylan.merriamwebster_thesaurus.data.local.ThesaurusEntry
+import space.narrate.waylan.merriamwebster_thesaurus.data.remote.MerriamWebsterThesaurusStore
+
+/**
+ * A repository which is able to retrieve all data needed for UI presentation of
+ * Merriam-Webster thesaurus entries.
+ */
+class MerriamWebsterThesaurusRepository(
+ private val merriamWebsterThesaurusStore: MerriamWebsterThesaurusStore
+) {
+ fun getMerriamWebsterThesaurusWord(word: String): LiveData> {
+ return merriamWebsterThesaurusStore.getWord(word)
+ }
+}
\ No newline at end of file
diff --git a/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/local/ThesaurusEntry.kt b/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/local/ThesaurusEntry.kt
new file mode 100644
index 0000000..00585fb
--- /dev/null
+++ b/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/local/ThesaurusEntry.kt
@@ -0,0 +1,19 @@
+package space.narrate.waylan.merriamwebster_thesaurus.data.local
+
+/**
+ * The local representation of an entry retrieved from the Merriam-Webster thesaurus. This class
+ * should be the only class used when displaying thesaurus data in the UI.
+ */
+data class ThesaurusEntry(
+ val id: String,
+ val word: String,
+ val src: String,
+ val stems: List,
+ val offensive: Boolean,
+ val partOfSpeech: String,
+ val shortDefs: List,
+ val synonymWords: List,
+ val relatedWords: List,
+ val nearWords: List,
+ val antonymWords: List
+)
\ No newline at end of file
diff --git a/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/remote/MerriamWebsterThesaurusService.kt b/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/remote/MerriamWebsterThesaurusService.kt
new file mode 100644
index 0000000..ce3e5ab
--- /dev/null
+++ b/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/remote/MerriamWebsterThesaurusService.kt
@@ -0,0 +1,18 @@
+package space.narrate.waylan.merriamwebster_thesaurus.data.remote
+
+import retrofit2.Call
+import retrofit2.http.GET
+import retrofit2.http.Path
+import retrofit2.http.Query
+
+/**
+ * Merriam-Webster thesaurus [RetrofitService].
+ */
+interface MerriamWebsterThesaurusService {
+ @GET("{word}")
+ fun getWord(
+ @Path("word") word: String,
+ @Query("key") developerKey: String
+ ): Call>
+}
+
diff --git a/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/remote/MerriamWebsterThesaurusStore.kt b/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/remote/MerriamWebsterThesaurusStore.kt
new file mode 100644
index 0000000..0a91d9d
--- /dev/null
+++ b/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/remote/MerriamWebsterThesaurusStore.kt
@@ -0,0 +1,65 @@
+package space.narrate.waylan.merriamwebster_thesaurus.data.remote
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+import space.narrate.waylan.merriamwebster_thesaurus.BuildConfig
+import space.narrate.waylan.merriamwebster_thesaurus.data.local.ThesaurusEntry
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * A data store which is able to retrieve remote Merriam-Webster thesaurus entries and convert
+ * those responses to local objects to be used in Waylan.
+ */
+class MerriamWebsterThesaurusStore(
+ private val merriamWebsterThesaurusService: MerriamWebsterThesaurusService
+) : CoroutineScope {
+
+ override val coroutineContext: CoroutineContext
+ get() = Dispatchers.IO
+
+ fun getWord(word: String): LiveData> {
+ val data = MutableLiveData>()
+ merriamWebsterThesaurusService.getWord(word, DEV_KEY).enqueue(
+ object : Callback> {
+
+ override fun onResponse(
+ call: Call>,
+ response: Response>
+ ) {
+ // TODO: Pull out toLocalObject extension function.
+ data.value = response.body()?.map { entry ->
+ ThesaurusEntry(
+ entry.meta.id,
+ entry.hwi.hw,
+ entry.meta.src,
+ entry.meta.stems,
+ entry.meta.offensive,
+ entry.fl,
+ entry.shortdef,
+ entry.def.entries.map { it.syn_list }.flatten().flatten().map { it.wd },
+ entry.def.entries.map { it.rel_list }.flatten().flatten().map { it.wd },
+ entry.def.entries.map { it.near_list }.flatten().flatten().map { it.wd },
+ entry.def.entries.map { it.ant_list }.flatten().flatten().map { it.wd }
+ )
+ }
+ }
+
+ override fun onFailure(call: Call>, t: Throwable) {
+ // Possibly handle failure
+ t.printStackTrace()
+ }
+ })
+
+
+ return data
+ }
+
+ companion object {
+ private const val DEV_KEY = BuildConfig.MERRIAM_WEBSTER_THESAURUS_KEY
+ }
+}
\ No newline at end of file
diff --git a/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/remote/RemoteThesaurusEntry.kt b/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/remote/RemoteThesaurusEntry.kt
new file mode 100644
index 0000000..2e38d0a
--- /dev/null
+++ b/merriamwebster_thesaurus/src/main/java/space/narrate/waylan/merriamwebster_thesaurus/data/remote/RemoteThesaurusEntry.kt
@@ -0,0 +1,91 @@
+package space.narrate.waylan.merriamwebster_thesaurus.data.remote
+
+import com.squareup.moshi.FromJson
+import com.squareup.moshi.Moshi
+import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
+
+/**
+ * The remote representation of a response from the Merriam-Webster thesaurus API.
+ */
+data class RemoteThesaurusEntry(
+ // Metadata about an entry
+ val meta: Meta,
+ // Headword information
+ val hwi: Hwi,
+ // Functional label (such as 'noun' or 'adjective')
+ val fl: String,
+ val def: Def,
+ val shortdef: List
+)
+
+/**
+ * Metadata about an entry.
+ */
+data class Meta(
+ // Unique entry identifier
+ val id: String,
+ val uuid: String,
+ // Source data set for the entry
+ val src: String,
+ // The section the entry belongs to in the dictionary (ie. 'alpha', 'biog', 'geog').
+ val section: String,
+ val stems: List,
+ val syns: List>,
+ val ants: List>,
+ val offensive: Boolean
+)
+
+/**
+ * Headword Information. The word being defined in a dictionary entry.
+ */
+data class Hwi(
+ // The word being defined
+ val hw: String
+ // Other fields are available but not included here.
+)
+
+data class Def(
+ val entries: List = emptyList()
+)
+
+data class Entry(
+ val sn: String = "",
+ val dt: Any = Any(),
+ val syn_list: List> = emptyList(),
+ val rel_list: List> = emptyList(),
+ val near_list: List> = emptyList(),
+ val ant_list: List> = emptyList()
+)
+
+data class Wd(
+ val wd: String,
+ val wvrs: List = emptyList()
+)
+
+data class Wvr(
+ val wv1: String?,
+ val wva: String
+)
+
+class EntryAdapter {
+ // TODO: Find a cleaner way to parse the 'def' section of the response.
+ @FromJson
+ fun fromJson(defObject: Any): Def {
+ return try {
+ val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
+
+ // ArrayList
+ val listOfEntryParents = ((defObject as ArrayList