From b745e8c0df3313a6bb3e8e9fb6f7f6c4d4223f84 Mon Sep 17 00:00:00 2001 From: rusili Date: Mon, 27 May 2019 21:14:20 -0400 Subject: [PATCH 01/10] feature/share added share button to both previewlist and article screens. --- .../com/rusili/superstreet/MainActivity.kt | 14 +++++++++-- .../com/rusili/superstreet/MainNavigator.kt | 3 +++ .../superstreet/article/ui/ArticleActivity.kt | 1 + .../superstreet/common/base/BaseActivity.kt | 24 ++++++++++++++++--- .../favoritelist/ui/FavoriteListFragment.kt | 12 +--------- .../previewlist/ui/PreviewListFragment.kt | 12 +--------- .../previewlist/ui/rv/PreviewListAdapter.kt | 9 +++---- .../previewlist/ui/rv/PreviewViewHolder.kt | 7 +++--- app/src/main/res/layout/activity_article.xml | 9 +++++++ .../res/layout/viewholder_preview_large.xml | 19 +++++++++++++++ .../res/layout/viewholder_preview_small.xml | 19 +++++++++++++++ app/src/main/res/values/styles.xml | 3 +-- 12 files changed, 96 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/com/rusili/superstreet/MainActivity.kt b/app/src/main/java/com/rusili/superstreet/MainActivity.kt index ca755e0..5272b6f 100644 --- a/app/src/main/java/com/rusili/superstreet/MainActivity.kt +++ b/app/src/main/java/com/rusili/superstreet/MainActivity.kt @@ -1,5 +1,6 @@ package com.rusili.superstreet +import android.accounts.NetworkErrorException import android.content.Intent import android.os.Bundle import android.view.View @@ -8,6 +9,7 @@ import androidx.core.view.ViewCompat import androidx.fragment.app.Fragment import com.rusili.superstreet.article.ui.ArticleActivity import com.rusili.superstreet.common.base.BaseActivity +import com.rusili.superstreet.common.extensions.isNetworkConnected import com.rusili.superstreet.common.models.Header import com.squareup.moshi.Moshi import dagger.android.AndroidInjector @@ -18,8 +20,8 @@ import javax.inject.Inject class MainActivity : BaseActivity(), MainNavigator, HasSupportFragmentInjector { @Inject protected lateinit var fragmentInjector: DispatchingAndroidInjector - @Inject protected lateinit var moshi: Moshi + @Inject protected lateinit var moshi: Moshi override fun supportFragmentInjector(): AndroidInjector = fragmentInjector override fun onCreate(savedInstanceState: Bundle?) { @@ -33,6 +35,10 @@ class MainActivity : BaseActivity(), MainNavigator, HasSupportFragmentInjector { view: View, header: Header ) { + if (!isNetworkConnected()) { + showError(NetworkErrorException()) + } + Intent(this, ArticleActivity::class.java).apply { putExtra( ArticleActivity.ARTICLE_HEADER_BUNDLE_KEY, @@ -42,9 +48,13 @@ class MainActivity : BaseActivity(), MainNavigator, HasSupportFragmentInjector { val options = ActivityOptionsCompat.makeSceneTransitionAnimation( this, view, - ViewCompat.getTransitionName(view)!! + ViewCompat.getTransitionName(view).orEmpty() ) startActivity(it, options.toBundle()) } } + + override fun shareLink(link: String) { + internalShareLink(link) + } } diff --git a/app/src/main/java/com/rusili/superstreet/MainNavigator.kt b/app/src/main/java/com/rusili/superstreet/MainNavigator.kt index ad7bc5d..ebd76ff 100644 --- a/app/src/main/java/com/rusili/superstreet/MainNavigator.kt +++ b/app/src/main/java/com/rusili/superstreet/MainNavigator.kt @@ -1,5 +1,6 @@ package com.rusili.superstreet +import android.content.Intent import android.view.View import com.rusili.superstreet.common.models.Header @@ -9,4 +10,6 @@ interface MainNavigator { view: View, header: Header ) + + fun shareLink(link: String) } diff --git a/app/src/main/java/com/rusili/superstreet/article/ui/ArticleActivity.kt b/app/src/main/java/com/rusili/superstreet/article/ui/ArticleActivity.kt index 8a73cbb..8b0380b 100644 --- a/app/src/main/java/com/rusili/superstreet/article/ui/ArticleActivity.kt +++ b/app/src/main/java/com/rusili/superstreet/article/ui/ArticleActivity.kt @@ -75,6 +75,7 @@ class ArticleActivity : BaseActivity() { private fun setupViews(header: Header) { articleHeaderImageView.transitionName = header.headerImage.title articleHeaderTitle.text = header.title.value + articleShare.setOnClickListener { internalShareLink(header.title.href) } Glide.with(this) .load(header.headerImage.getDefaultSizeUrl()) diff --git a/app/src/main/java/com/rusili/superstreet/common/base/BaseActivity.kt b/app/src/main/java/com/rusili/superstreet/common/base/BaseActivity.kt index b63baa3..acc3729 100644 --- a/app/src/main/java/com/rusili/superstreet/common/base/BaseActivity.kt +++ b/app/src/main/java/com/rusili/superstreet/common/base/BaseActivity.kt @@ -1,6 +1,7 @@ package com.rusili.superstreet.common.base import android.accounts.NetworkErrorException +import android.content.Intent import android.content.IntentSender import android.os.Bundle import androidx.appcompat.app.AlertDialog @@ -12,6 +13,10 @@ import io.reactivex.disposables.CompositeDisposable import java.net.SocketTimeoutException import java.net.UnknownHostException +private const val STRING_SHARE_TYPE = "text/plain" +private const val STRING_SHARE_SUBJECT = "Sharing URL" +private const val STRING_SHARE_VIA = "Share via: " + abstract class BaseActivity : AppCompatActivity() { protected val disposable = CompositeDisposable() var container = 0 @@ -32,12 +37,25 @@ abstract class BaseActivity : AppCompatActivity() { super.onStop() } - fun inflateFragment(fragment: BaseFragment) = + protected fun inflateFragment(fragment: BaseFragment) = supportFragmentManager.beginTransaction() .add(container, fragment) .commit() - fun showError(error: Throwable?) { + protected fun internalShareLink(link: String) { + startActivity( + Intent.createChooser( + Intent(Intent.ACTION_SEND).apply { + setType(STRING_SHARE_TYPE) + putExtra(Intent.EXTRA_SUBJECT, STRING_SHARE_SUBJECT) + putExtra(Intent.EXTRA_TEXT, link) + }, + STRING_SHARE_VIA + ) + ) + } + + protected fun showError(error: Throwable?) { when (error) { is IntentSender.SendIntentException -> showErrorDialogToFinish() is NetworkErrorException -> showNetworkError() @@ -47,7 +65,7 @@ abstract class BaseActivity : AppCompatActivity() { } } - fun showSnackbar( + protected fun showSnackbar( message: String, length: Int = 0 ) { diff --git a/app/src/main/java/com/rusili/superstreet/favoritelist/ui/FavoriteListFragment.kt b/app/src/main/java/com/rusili/superstreet/favoritelist/ui/FavoriteListFragment.kt index 59932c5..ba91a65 100644 --- a/app/src/main/java/com/rusili/superstreet/favoritelist/ui/FavoriteListFragment.kt +++ b/app/src/main/java/com/rusili/superstreet/favoritelist/ui/FavoriteListFragment.kt @@ -41,7 +41,7 @@ class FavoriteListFragment : BaseFragment() { } private val adapter: PreviewListAdapter by lazy { - PreviewListAdapter(::onTitleClicked, Glide.with(this), dateHelper).apply { + PreviewListAdapter(navigator, Glide.with(this), dateHelper).apply { setHasStableIds(true) } } @@ -82,14 +82,4 @@ class FavoriteListFragment : BaseFragment() { // adapter.submitList(favoriteList) fragmentListLoadingLayout.fadeAndHide() } - - private fun onTitleClicked( - view: View, - header: Header - ) { - if (view.context.isNetworkConnected()) { - Timber.d("Title: %s Href: %s", header.title.value, header.title.href) - navigator.goToArticle(view, header) - } else showError(NetworkErrorException()) - } } diff --git a/app/src/main/java/com/rusili/superstreet/previewlist/ui/PreviewListFragment.kt b/app/src/main/java/com/rusili/superstreet/previewlist/ui/PreviewListFragment.kt index 10660d7..2d1dd11 100644 --- a/app/src/main/java/com/rusili/superstreet/previewlist/ui/PreviewListFragment.kt +++ b/app/src/main/java/com/rusili/superstreet/previewlist/ui/PreviewListFragment.kt @@ -41,7 +41,7 @@ class PreviewListFragment : BaseFragment() { } private val adapter: PreviewListAdapter by lazy { - PreviewListAdapter(::onTitleClicked, Glide.with(this), dateHelper) + PreviewListAdapter(navigator, Glide.with(this), dateHelper) } companion object { @@ -86,14 +86,4 @@ class PreviewListFragment : BaseFragment() { adapter.submitList(previewList) fragmentListLoadingLayout.fadeAndHide() } - - private fun onTitleClicked( - view: View, - header: Header - ) { - if (view.context.isNetworkConnected()) { - Timber.d("Title: %s Href: %s", header.title.value, header.title.href) - navigator.goToArticle(view, header) - } else showError(NetworkErrorException()) - } } diff --git a/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewListAdapter.kt b/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewListAdapter.kt index c456fcd..92af570 100644 --- a/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewListAdapter.kt +++ b/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewListAdapter.kt @@ -5,6 +5,7 @@ import android.view.View import android.view.ViewGroup import androidx.paging.PagedListAdapter import com.bumptech.glide.RequestManager +import com.rusili.superstreet.MainNavigator import com.rusili.superstreet.R import com.rusili.superstreet.common.models.Header import com.rusili.superstreet.previewlist.DateHelper @@ -12,16 +13,16 @@ import com.rusili.superstreet.previewlist.domain.ArticlePreviewModel import com.rusili.superstreet.previewlist.domain.CardSize class PreviewListAdapter( - private val onClick: (View, Header) -> Unit, + private val navigator: MainNavigator, private val glide: RequestManager, private val dateHelper: DateHelper ) : PagedListAdapter(PreviewDiffCallback()) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PreviewViewHolder = when (viewType) { - CardSize.Large.viewType -> PreviewViewHolder(parent.inflate(R.layout.viewholder_preview_large), onClick, glide, dateHelper) - CardSize.Small.viewType -> PreviewViewHolder(parent.inflate(R.layout.viewholder_preview_small), onClick, glide, dateHelper) - else -> PreviewViewHolder(parent.inflate(R.layout.viewholder_preview_small), onClick, glide, dateHelper) + CardSize.Large.viewType -> PreviewViewHolder(parent.inflate(R.layout.viewholder_preview_large), navigator, glide, dateHelper) + CardSize.Small.viewType -> PreviewViewHolder(parent.inflate(R.layout.viewholder_preview_small), navigator, glide, dateHelper) + else -> PreviewViewHolder(parent.inflate(R.layout.viewholder_preview_small), navigator, glide, dateHelper) } override fun onBindViewHolder(holder: PreviewViewHolder, position: Int) { diff --git a/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt b/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt index d60a346..1370c9c 100644 --- a/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt +++ b/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt @@ -5,9 +5,9 @@ import android.view.animation.AnimationUtils import androidx.core.view.ViewCompat import com.bumptech.glide.RequestManager import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions +import com.rusili.superstreet.MainNavigator import com.rusili.superstreet.R import com.rusili.superstreet.common.base.BaseViewHolder -import com.rusili.superstreet.common.models.Header import com.rusili.superstreet.common.models.header.HeaderImage.Companion.HEADER_IMAGE_HEIGHT import com.rusili.superstreet.common.models.header.HeaderImage.Companion.HEADER_IMAGE_WIDTH import com.rusili.superstreet.previewlist.DateHelper @@ -20,7 +20,7 @@ private val crossFadeTransition = DrawableTransitionOptions.withCrossFade() class PreviewViewHolder( override val containerView: View, - private val onClick: (View, Header) -> Unit, + private val navigator: MainNavigator, private val glide: RequestManager, private val dateHelper: DateHelper ) : BaseViewHolder(containerView), LayoutContainer { @@ -33,7 +33,8 @@ class PreviewViewHolder( setupImage(model) setText(model) - containerView.setOnClickListener { onClick(previewThumbnail, model.header) } + previewBackground.setOnClickListener { navigator.goToArticle(previewThumbnail, model.header) } + previewShare.setOnClickListener { navigator.shareLink(model.header.title.href) } } private fun animate() { diff --git a/app/src/main/res/layout/activity_article.xml b/app/src/main/res/layout/activity_article.xml index fb4fdb2..bfe687d 100644 --- a/app/src/main/res/layout/activity_article.xml +++ b/app/src/main/res/layout/activity_article.xml @@ -45,6 +45,15 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" /> + + + + + + + diff --git a/app/src/main/res/layout/viewholder_preview_small.xml b/app/src/main/res/layout/viewholder_preview_small.xml index 370f342..809770a 100644 --- a/app/src/main/res/layout/viewholder_preview_small.xml +++ b/app/src/main/res/layout/viewholder_preview_small.xml @@ -7,6 +7,15 @@ android:layout_height="wrap_content" android:paddingBottom="4dp"> + + + + + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 0447f32..144d249 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -58,8 +58,7 @@ wrap_content @color/colorTextLight @dimen/preview_viewholder_timestamp_margin_top - @dimen/preview_viewholder_timestamp_margin_horizontal - + @dimen/preview_viewholder_timestamp_margin_horizontal @dimen/preview_viewholder_timestamp_margin_bottom From 2de7abf39856419cbfcff80fdc402cf63e97ce4b Mon Sep 17 00:00:00 2001 From: rusili Date: Mon, 3 Jun 2019 11:21:07 -0400 Subject: [PATCH 02/10] feature/share imported new icons. adding actionsview --- .../common/base/StyleableFrameLayout.kt | 39 +++++++++++++++++++ .../superstreet/common/ui/ActionsView.kt | 24 ++++++++++++ .../superstreet/previewlist/DateHelper.kt | 7 +++- .../previewlist/ui/rv/PreviewViewHolder.kt | 1 - app/src/main/res/drawable/ic_bookmark.xml | 9 +++++ app/src/main/res/drawable/ic_download.xml | 12 ++++++ .../drawable/ic_file_download_white_24dp.xml | 10 ----- app/src/main/res/drawable/ic_share.xml | 12 ++++++ .../main/res/drawable/ic_share_white_24dp.xml | 10 ----- .../main/res/layout-land/activity_image.xml | 5 +-- app/src/main/res/layout/activity_article.xml | 2 +- app/src/main/res/layout/activity_image.xml | 5 +-- app/src/main/res/layout/view_actions.xml | 25 ++++++++++++ .../res/layout/viewholder_preview_large.xml | 5 +-- .../res/layout/viewholder_preview_small.xml | 2 +- 15 files changed, 133 insertions(+), 35 deletions(-) create mode 100644 app/src/main/java/com/rusili/superstreet/common/base/StyleableFrameLayout.kt create mode 100644 app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt create mode 100644 app/src/main/res/drawable/ic_bookmark.xml create mode 100644 app/src/main/res/drawable/ic_download.xml delete mode 100644 app/src/main/res/drawable/ic_file_download_white_24dp.xml create mode 100644 app/src/main/res/drawable/ic_share.xml delete mode 100644 app/src/main/res/drawable/ic_share_white_24dp.xml create mode 100644 app/src/main/res/layout/view_actions.xml diff --git a/app/src/main/java/com/rusili/superstreet/common/base/StyleableFrameLayout.kt b/app/src/main/java/com/rusili/superstreet/common/base/StyleableFrameLayout.kt new file mode 100644 index 0000000..ecfc8c4 --- /dev/null +++ b/app/src/main/java/com/rusili/superstreet/common/base/StyleableFrameLayout.kt @@ -0,0 +1,39 @@ +package com.rusili.superstreet.common.base + +import android.content.Context +import android.content.res.TypedArray +import android.util.AttributeSet +import android.widget.FrameLayout +import androidx.annotation.LayoutRes +import androidx.annotation.StyleableRes +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.content.withStyledAttributes + +abstract class StyleableFrameLayout @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : FrameLayout(context, attrs, defStyleAttr) { + + init { + this.getLayout()?.let { + inflate(context, it, this@StyleableFrameLayout) + } + + context.withStyledAttributes( + attrs, + this.getStyleable(), + defStyleAttr, 0 + ) { + setupViews() + } + } + + @LayoutRes + abstract fun getLayout(): Int? + + abstract fun TypedArray.setupViews() + + @StyleableRes + fun getStyleable(): IntArray = IntArray(0) +} diff --git a/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt b/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt new file mode 100644 index 0000000..8568b0f --- /dev/null +++ b/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt @@ -0,0 +1,24 @@ +package com.rusili.superstreet.common.ui + +import android.content.Context +import android.content.res.TypedArray +import android.util.AttributeSet +import android.widget.ImageView +import com.rusili.superstreet.R +import com.rusili.superstreet.common.base.StyleableFrameLayout + +class ActionsView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : StyleableFrameLayout(context, attrs, defStyleAttr) { + var favoriteAction: (() -> Unit)? = null + var shareAction: (() -> Unit)? = null + + override fun getLayout(): Int? = R.layout.view_actions + + override fun TypedArray.setupViews() { + findViewById(R.id.actionFavorite).setOnClickListener { favoriteAction?.invoke() } + findViewById(R.id.actionShare).setOnClickListener { shareAction?.invoke() } + } +} diff --git a/app/src/main/java/com/rusili/superstreet/previewlist/DateHelper.kt b/app/src/main/java/com/rusili/superstreet/previewlist/DateHelper.kt index 193d33a..82f35eb 100644 --- a/app/src/main/java/com/rusili/superstreet/previewlist/DateHelper.kt +++ b/app/src/main/java/com/rusili/superstreet/previewlist/DateHelper.kt @@ -4,6 +4,9 @@ import androidx.annotation.VisibleForTesting import java.util.Date import java.util.concurrent.TimeUnit +private const val CHAR_S = 's' +private const val STRING_AGO = " ago" + private const val STRING_TODAY = "Today" private const val STRING_YESTERDAY = "Yesterday" @@ -24,9 +27,9 @@ class DateHelper { else -> { var value = it.length.toString() + " " + it.period.name if (it.length > 1) { - value += "s" + value += CHAR_S } - value.toLowerCase() + " ago" + value.toLowerCase() + STRING_AGO } } } diff --git a/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt b/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt index 1370c9c..d516f62 100644 --- a/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt +++ b/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt @@ -34,7 +34,6 @@ class PreviewViewHolder( setText(model) previewBackground.setOnClickListener { navigator.goToArticle(previewThumbnail, model.header) } - previewShare.setOnClickListener { navigator.shareLink(model.header.title.href) } } private fun animate() { diff --git a/app/src/main/res/drawable/ic_bookmark.xml b/app/src/main/res/drawable/ic_bookmark.xml new file mode 100644 index 0000000..bcd12cf --- /dev/null +++ b/app/src/main/res/drawable/ic_bookmark.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_download.xml b/app/src/main/res/drawable/ic_download.xml new file mode 100644 index 0000000..fbfe42f --- /dev/null +++ b/app/src/main/res/drawable/ic_download.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_file_download_white_24dp.xml b/app/src/main/res/drawable/ic_file_download_white_24dp.xml deleted file mode 100644 index 9f98049..0000000 --- a/app/src/main/res/drawable/ic_file_download_white_24dp.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_share.xml b/app/src/main/res/drawable/ic_share.xml new file mode 100644 index 0000000..7330501 --- /dev/null +++ b/app/src/main/res/drawable/ic_share.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_share_white_24dp.xml b/app/src/main/res/drawable/ic_share_white_24dp.xml deleted file mode 100644 index 1447d9b..0000000 --- a/app/src/main/res/drawable/ic_share_white_24dp.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/layout-land/activity_image.xml b/app/src/main/res/layout-land/activity_image.xml index 9add86a..ea074d5 100644 --- a/app/src/main/res/layout-land/activity_image.xml +++ b/app/src/main/res/layout-land/activity_image.xml @@ -37,11 +37,10 @@ android:layout_marginBottom="@dimen/image_icon_margin_horizontal" android:elevation="@dimen/elevation_low" android:foreground="?android:attr/selectableItemBackground" - android:src="@drawable/ic_share_white_24dp" + android:src="@drawable/ic_share" app:layout_constraintBottom_toTopOf="@id/activityImageSaveButton" app:layout_constraintRight_toRightOf="parent" /> - diff --git a/app/src/main/res/layout/activity_article.xml b/app/src/main/res/layout/activity_article.xml index bfe687d..7ba585a 100644 --- a/app/src/main/res/layout/activity_article.xml +++ b/app/src/main/res/layout/activity_article.xml @@ -50,7 +50,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="@dimen/preview_viewholder_title_margin_horizontal" - android:src="@drawable/ic_share_white_24dp" + android:src="@drawable/ic_share" app:layout_constraintBottom_toBottomOf="@id/articleHeaderTitle" app:layout_constraintRight_toRightOf="parent" /> diff --git a/app/src/main/res/layout/activity_image.xml b/app/src/main/res/layout/activity_image.xml index f908427..430dd66 100644 --- a/app/src/main/res/layout/activity_image.xml +++ b/app/src/main/res/layout/activity_image.xml @@ -33,11 +33,10 @@ android:layout_marginBottom="@dimen/snackbar_margin_bottom" android:elevation="@dimen/elevation_low" android:foreground="?android:attr/selectableItemBackground" - android:src="@drawable/ic_share_white_24dp" + android:src="@drawable/ic_share" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toLeftOf="@id/activityImageSaveButton" /> - diff --git a/app/src/main/res/layout/view_actions.xml b/app/src/main/res/layout/view_actions.xml new file mode 100644 index 0000000..9591365 --- /dev/null +++ b/app/src/main/res/layout/view_actions.xml @@ -0,0 +1,25 @@ + + + + + + + + diff --git a/app/src/main/res/layout/viewholder_preview_large.xml b/app/src/main/res/layout/viewholder_preview_large.xml index d3fd0fe..f031c68 100644 --- a/app/src/main/res/layout/viewholder_preview_large.xml +++ b/app/src/main/res/layout/viewholder_preview_large.xml @@ -64,12 +64,9 @@ app:layout_constraintTop_toBottomOf="@id/previewTitle" tools:text="1 week ago" /> - diff --git a/app/src/main/res/layout/viewholder_preview_small.xml b/app/src/main/res/layout/viewholder_preview_small.xml index 809770a..9aea368 100644 --- a/app/src/main/res/layout/viewholder_preview_small.xml +++ b/app/src/main/res/layout/viewholder_preview_small.xml @@ -67,7 +67,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="@dimen/preview_viewholder_title_margin_horizontal" - android:src="@drawable/ic_share_white_24dp" + android:src="@drawable/ic_share" app:layout_constraintBottom_toBottomOf="@id/previewThumbnail" app:layout_constraintRight_toRightOf="parent" /> From d7d15ab2ad594ac358f6e1d57f1a4b219720dd1b Mon Sep 17 00:00:00 2001 From: rusili Date: Thu, 6 Jun 2019 09:34:03 -0400 Subject: [PATCH 03/10] feature/share added favoriteManager. --- .../superstreet/database/FavoriteDaoTest.kt | 5 +--- .../article/domain/ArticleUsecaseImpl.kt | 6 ++--- .../superstreet/common/base/BaseActivity.kt | 17 ------------- .../superstreet/common/ui/ActionsView.kt | 25 +++++++++++++++++-- .../superstreet/database/AppDatabase.kt | 2 +- .../superstreet/database/di/DatabaseModule.kt | 12 ++++++--- .../database/favorites/FavoriteDao.kt | 1 + .../database/favorites/FavoriteManager.kt | 15 +++++++++++ .../database/favorites/FavoriteManagerImpl.kt | 21 ++++++++++++++++ .../favorites/{ => model}/FavoriteEntity.kt | 2 +- .../{ => model}/FavoriteModelMapper.kt | 2 +- .../data/FavoriteListRepositoryImpl.kt | 14 +++-------- .../domain/FavoriteListRepository.kt | 2 +- .../domain/FavoriteListUsecaseImpl.kt | 10 ++++---- .../favoritelist/ui/FavoriteListUsecase.kt | 2 +- .../database/FavoriteModelMapperTest.kt | 2 +- 16 files changed, 87 insertions(+), 51 deletions(-) create mode 100644 app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteManager.kt create mode 100644 app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteManagerImpl.kt rename app/src/main/java/com/rusili/superstreet/database/favorites/{ => model}/FavoriteEntity.kt (89%) rename app/src/main/java/com/rusili/superstreet/database/favorites/{ => model}/FavoriteModelMapper.kt (97%) diff --git a/app/src/androidTest/java/com/rusili/superstreet/database/FavoriteDaoTest.kt b/app/src/androidTest/java/com/rusili/superstreet/database/FavoriteDaoTest.kt index b2cc88b..4066132 100644 --- a/app/src/androidTest/java/com/rusili/superstreet/database/FavoriteDaoTest.kt +++ b/app/src/androidTest/java/com/rusili/superstreet/database/FavoriteDaoTest.kt @@ -12,18 +12,15 @@ import com.rusili.superstreet.common.models.Type import com.rusili.superstreet.common.models.footer.Author import com.rusili.superstreet.common.models.header.HeaderImage import com.rusili.superstreet.common.models.header.Title -import com.rusili.superstreet.database.favorites.FavoriteEntity -import com.rusili.superstreet.database.favorites.FavoriteModelMapper +import com.rusili.superstreet.database.favorites.model.FavoriteModelMapper import com.rusili.superstreet.previewlist.domain.ArticlePreviewModel import com.rusili.superstreet.previewlist.domain.CardSize -import io.reactivex.functions.Predicate import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import java.util.Date -import java.util.concurrent.TimeUnit @RunWith(AndroidJUnit4::class) class FavoriteDaoTest { diff --git a/app/src/main/java/com/rusili/superstreet/article/domain/ArticleUsecaseImpl.kt b/app/src/main/java/com/rusili/superstreet/article/domain/ArticleUsecaseImpl.kt index 9f08c99..10b13cd 100644 --- a/app/src/main/java/com/rusili/superstreet/article/domain/ArticleUsecaseImpl.kt +++ b/app/src/main/java/com/rusili/superstreet/article/domain/ArticleUsecaseImpl.kt @@ -3,7 +3,5 @@ package com.rusili.superstreet.article.domain import com.rusili.superstreet.article.ui.ArticleUsecase import javax.inject.Inject -class ArticleUsecaseImpl @Inject constructor(private val repository: ArticleRepository) : ArticleUsecase { - - override fun getArticle(href: String) = repository.getArticle(href) -} +class ArticleUsecaseImpl @Inject constructor(private val repository: ArticleRepository) : + ArticleRepository by repository diff --git a/app/src/main/java/com/rusili/superstreet/common/base/BaseActivity.kt b/app/src/main/java/com/rusili/superstreet/common/base/BaseActivity.kt index acc3729..ecd4f92 100644 --- a/app/src/main/java/com/rusili/superstreet/common/base/BaseActivity.kt +++ b/app/src/main/java/com/rusili/superstreet/common/base/BaseActivity.kt @@ -13,10 +13,6 @@ import io.reactivex.disposables.CompositeDisposable import java.net.SocketTimeoutException import java.net.UnknownHostException -private const val STRING_SHARE_TYPE = "text/plain" -private const val STRING_SHARE_SUBJECT = "Sharing URL" -private const val STRING_SHARE_VIA = "Share via: " - abstract class BaseActivity : AppCompatActivity() { protected val disposable = CompositeDisposable() var container = 0 @@ -42,19 +38,6 @@ abstract class BaseActivity : AppCompatActivity() { .add(container, fragment) .commit() - protected fun internalShareLink(link: String) { - startActivity( - Intent.createChooser( - Intent(Intent.ACTION_SEND).apply { - setType(STRING_SHARE_TYPE) - putExtra(Intent.EXTRA_SUBJECT, STRING_SHARE_SUBJECT) - putExtra(Intent.EXTRA_TEXT, link) - }, - STRING_SHARE_VIA - ) - ) - } - protected fun showError(error: Throwable?) { when (error) { is IntentSender.SendIntentException -> showErrorDialogToFinish() diff --git a/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt b/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt index 8568b0f..16d28cb 100644 --- a/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt +++ b/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt @@ -1,24 +1,45 @@ package com.rusili.superstreet.common.ui import android.content.Context +import android.content.Intent import android.content.res.TypedArray import android.util.AttributeSet import android.widget.ImageView +import androidx.core.content.ContextCompat.startActivity import com.rusili.superstreet.R import com.rusili.superstreet.common.base.StyleableFrameLayout +private const val STRING_SHARE_TYPE = "text/plain" +private const val STRING_SHARE_SUBJECT = "Sharing URL" +private const val STRING_SHARE_VIA = "Share via: " + class ActionsView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : StyleableFrameLayout(context, attrs, defStyleAttr) { var favoriteAction: (() -> Unit)? = null - var shareAction: (() -> Unit)? = null override fun getLayout(): Int? = R.layout.view_actions override fun TypedArray.setupViews() { findViewById(R.id.actionFavorite).setOnClickListener { favoriteAction?.invoke() } - findViewById(R.id.actionShare).setOnClickListener { shareAction?.invoke() } + } + + fun setShareLink(link: String) { + findViewById(R.id.actionShare).setOnClickListener { shareLink(link) } + } + + private fun shareLink(link: String) { + context.startActivity( + Intent.createChooser( + Intent(Intent.ACTION_SEND).apply { + setType(STRING_SHARE_TYPE) + putExtra(Intent.EXTRA_SUBJECT, STRING_SHARE_SUBJECT) + putExtra(Intent.EXTRA_TEXT, link) + }, + STRING_SHARE_VIA + ) + ) } } diff --git a/app/src/main/java/com/rusili/superstreet/database/AppDatabase.kt b/app/src/main/java/com/rusili/superstreet/database/AppDatabase.kt index 207b7c2..89fc590 100644 --- a/app/src/main/java/com/rusili/superstreet/database/AppDatabase.kt +++ b/app/src/main/java/com/rusili/superstreet/database/AppDatabase.kt @@ -3,7 +3,7 @@ package com.rusili.superstreet.database import androidx.room.Database import androidx.room.RoomDatabase import com.rusili.superstreet.database.favorites.FavoriteDao -import com.rusili.superstreet.database.favorites.FavoriteEntity +import com.rusili.superstreet.database.favorites.model.FavoriteEntity @Database(entities = [FavoriteEntity::class], version = 1) abstract class AppDatabase : RoomDatabase() { diff --git a/app/src/main/java/com/rusili/superstreet/database/di/DatabaseModule.kt b/app/src/main/java/com/rusili/superstreet/database/di/DatabaseModule.kt index fa61993..9ccb857 100644 --- a/app/src/main/java/com/rusili/superstreet/database/di/DatabaseModule.kt +++ b/app/src/main/java/com/rusili/superstreet/database/di/DatabaseModule.kt @@ -4,7 +4,9 @@ import android.content.Context import androidx.room.Room import com.rusili.superstreet.database.AppDatabase import com.rusili.superstreet.database.favorites.FavoriteDao -import com.rusili.superstreet.database.favorites.FavoriteModelMapper +import com.rusili.superstreet.database.favorites.FavoriteManager +import com.rusili.superstreet.database.favorites.FavoriteManagerImpl +import com.rusili.superstreet.database.favorites.model.FavoriteModelMapper import com.rusili.superstreet.di.AppModule import dagger.Module import dagger.Provides @@ -15,13 +17,17 @@ private const val DATABASE_NAME = "SuperstreetDb" class DatabaseModule { @Provides - fun provideFavoriteDao(database: AppDatabase): FavoriteDao = - database.favoriteDao() + fun provideFavoriteManager(dao: FavoriteDao): FavoriteManager = + FavoriteManagerImpl(dao) @Provides fun provideFavoriteModelMapper(): FavoriteModelMapper = FavoriteModelMapper() + @Provides + protected fun provideFavoriteDao(database: AppDatabase): FavoriteDao = + database.favoriteDao() + @Provides protected fun provideRoomDatabase(context: Context): AppDatabase = Room.databaseBuilder( diff --git a/app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteDao.kt b/app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteDao.kt index cbd2f2c..7f88302 100644 --- a/app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteDao.kt +++ b/app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteDao.kt @@ -4,6 +4,7 @@ import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert import androidx.room.Query +import com.rusili.superstreet.database.favorites.model.FavoriteEntity import io.reactivex.Completable import io.reactivex.Single diff --git a/app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteManager.kt b/app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteManager.kt new file mode 100644 index 0000000..a39fd68 --- /dev/null +++ b/app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteManager.kt @@ -0,0 +1,15 @@ +package com.rusili.superstreet.database.favorites + +import com.rusili.superstreet.database.favorites.model.FavoriteEntity +import io.reactivex.Completable +import io.reactivex.Single + +interface FavoriteManager { + + fun toggleFavorite( + entity: FavoriteEntity, + enabled: Boolean + ): Completable + + fun getAllFavorites(): Single> +} diff --git a/app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteManagerImpl.kt b/app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteManagerImpl.kt new file mode 100644 index 0000000..1491827 --- /dev/null +++ b/app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteManagerImpl.kt @@ -0,0 +1,21 @@ +package com.rusili.superstreet.database.favorites + +import com.rusili.superstreet.database.favorites.model.FavoriteEntity +import io.reactivex.Completable +import io.reactivex.Single +import javax.inject.Inject + +class FavoriteManagerImpl @Inject constructor(private val dao: FavoriteDao) : FavoriteManager { + + override fun toggleFavorite( + entity: FavoriteEntity, + enabled: Boolean + ): Completable = + when (enabled) { + true -> dao.removeFavorite(entity) + false -> dao.addFavorite(entity) + } + + override fun getAllFavorites(): Single> = + dao.getAllFavorites() +} diff --git a/app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteEntity.kt b/app/src/main/java/com/rusili/superstreet/database/favorites/model/FavoriteEntity.kt similarity index 89% rename from app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteEntity.kt rename to app/src/main/java/com/rusili/superstreet/database/favorites/model/FavoriteEntity.kt index dd5a54e..8308abf 100644 --- a/app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteEntity.kt +++ b/app/src/main/java/com/rusili/superstreet/database/favorites/model/FavoriteEntity.kt @@ -1,4 +1,4 @@ -package com.rusili.superstreet.database.favorites +package com.rusili.superstreet.database.favorites.model import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteModelMapper.kt b/app/src/main/java/com/rusili/superstreet/database/favorites/model/FavoriteModelMapper.kt similarity index 97% rename from app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteModelMapper.kt rename to app/src/main/java/com/rusili/superstreet/database/favorites/model/FavoriteModelMapper.kt index 07c4267..b551109 100644 --- a/app/src/main/java/com/rusili/superstreet/database/favorites/FavoriteModelMapper.kt +++ b/app/src/main/java/com/rusili/superstreet/database/favorites/model/FavoriteModelMapper.kt @@ -1,4 +1,4 @@ -package com.rusili.superstreet.database.favorites +package com.rusili.superstreet.database.favorites.model import com.rusili.superstreet.common.models.Flag import com.rusili.superstreet.common.models.Footer diff --git a/app/src/main/java/com/rusili/superstreet/favoritelist/data/FavoriteListRepositoryImpl.kt b/app/src/main/java/com/rusili/superstreet/favoritelist/data/FavoriteListRepositoryImpl.kt index 7495cd6..c2b25f0 100644 --- a/app/src/main/java/com/rusili/superstreet/favoritelist/data/FavoriteListRepositoryImpl.kt +++ b/app/src/main/java/com/rusili/superstreet/favoritelist/data/FavoriteListRepositoryImpl.kt @@ -1,18 +1,12 @@ package com.rusili.superstreet.favoritelist.data import com.rusili.superstreet.database.favorites.FavoriteDao -import com.rusili.superstreet.database.favorites.FavoriteEntity +import com.rusili.superstreet.database.favorites.FavoriteManager +import com.rusili.superstreet.database.favorites.model.FavoriteEntity import com.rusili.superstreet.favoritelist.domain.FavoriteListRepository import io.reactivex.Completable import io.reactivex.Single import javax.inject.Inject -class FavoriteListRepositoryImpl @Inject constructor(private val dao: FavoriteDao) : - FavoriteListRepository { - - override fun getAllFavorites(): Single> = - dao.getAllFavorites() - - override fun removeFavorite(entity: FavoriteEntity): Completable = - dao.removeFavorite(entity) -} +class FavoriteListRepositoryImpl @Inject constructor(private val manager: FavoriteManager) : + FavoriteManager by manager diff --git a/app/src/main/java/com/rusili/superstreet/favoritelist/domain/FavoriteListRepository.kt b/app/src/main/java/com/rusili/superstreet/favoritelist/domain/FavoriteListRepository.kt index 505d68f..6955b2f 100644 --- a/app/src/main/java/com/rusili/superstreet/favoritelist/domain/FavoriteListRepository.kt +++ b/app/src/main/java/com/rusili/superstreet/favoritelist/domain/FavoriteListRepository.kt @@ -1,6 +1,6 @@ package com.rusili.superstreet.favoritelist.domain -import com.rusili.superstreet.database.favorites.FavoriteEntity +import com.rusili.superstreet.database.favorites.model.FavoriteEntity import io.reactivex.Completable import io.reactivex.Single diff --git a/app/src/main/java/com/rusili/superstreet/favoritelist/domain/FavoriteListUsecaseImpl.kt b/app/src/main/java/com/rusili/superstreet/favoritelist/domain/FavoriteListUsecaseImpl.kt index 752b09f..868ce56 100644 --- a/app/src/main/java/com/rusili/superstreet/favoritelist/domain/FavoriteListUsecaseImpl.kt +++ b/app/src/main/java/com/rusili/superstreet/favoritelist/domain/FavoriteListUsecaseImpl.kt @@ -1,23 +1,23 @@ package com.rusili.superstreet.favoritelist.domain -import com.rusili.superstreet.database.favorites.FavoriteEntity -import com.rusili.superstreet.database.favorites.FavoriteModelMapper +import com.rusili.superstreet.database.favorites.model.FavoriteEntity +import com.rusili.superstreet.database.favorites.model.FavoriteModelMapper import com.rusili.superstreet.favoritelist.ui.FavoriteListUsecase import com.rusili.superstreet.previewlist.domain.ArticlePreviewModel import io.reactivex.Completable import io.reactivex.Single +import io.reactivex.rxkotlin.flatMapSequence import javax.inject.Inject class FavoriteListUsecaseImpl @Inject constructor( private val repository: FavoriteListRepository, private val mapper: FavoriteModelMapper -) : - FavoriteListUsecase { +) : FavoriteListUsecase { override fun getAllFavorites(): Single> = repository.getAllFavorites() .toObservable() - .flatMapIterable { favorites -> favorites } + .flatMapSequence(Iterable::asSequence) .map { favorite -> mapper.to(favorite) } .toList() diff --git a/app/src/main/java/com/rusili/superstreet/favoritelist/ui/FavoriteListUsecase.kt b/app/src/main/java/com/rusili/superstreet/favoritelist/ui/FavoriteListUsecase.kt index 5d151b3..c03ecef 100644 --- a/app/src/main/java/com/rusili/superstreet/favoritelist/ui/FavoriteListUsecase.kt +++ b/app/src/main/java/com/rusili/superstreet/favoritelist/ui/FavoriteListUsecase.kt @@ -1,6 +1,6 @@ package com.rusili.superstreet.favoritelist.ui -import com.rusili.superstreet.database.favorites.FavoriteEntity +import com.rusili.superstreet.database.favorites.model.FavoriteEntity import com.rusili.superstreet.previewlist.domain.ArticlePreviewModel import io.reactivex.Completable import io.reactivex.Single diff --git a/app/src/test/java/com/rusili/superstreet/database/FavoriteModelMapperTest.kt b/app/src/test/java/com/rusili/superstreet/database/FavoriteModelMapperTest.kt index f472a61..fd60595 100644 --- a/app/src/test/java/com/rusili/superstreet/database/FavoriteModelMapperTest.kt +++ b/app/src/test/java/com/rusili/superstreet/database/FavoriteModelMapperTest.kt @@ -9,7 +9,7 @@ import com.rusili.superstreet.common.models.Type import com.rusili.superstreet.common.models.footer.Author import com.rusili.superstreet.common.models.header.HeaderImage import com.rusili.superstreet.common.models.header.Title -import com.rusili.superstreet.database.favorites.FavoriteModelMapper +import com.rusili.superstreet.database.favorites.model.FavoriteModelMapper import com.rusili.superstreet.previewlist.domain.ArticlePreviewModel import com.rusili.superstreet.previewlist.domain.CardSize import org.amshove.kluent.shouldEqual From d019f74e133cf87dfba67bb38b5facb149767fa3 Mon Sep 17 00:00:00 2001 From: rusili Date: Sat, 8 Jun 2019 16:56:37 -0400 Subject: [PATCH 04/10] feature/share added favoritemanager. --- .../com/rusili/superstreet/MainActivity.kt | 2 +- .../article/domain/ArticleUsecaseImpl.kt | 7 +++- .../superstreet/article/ui/ArticleActivity.kt | 2 +- .../article/ui/rv/ImageGroupViewHolder.kt | 1 - .../article/ui/rv/ImageViewHolder.kt | 1 - .../superstreet/database/di/DatabaseModule.kt | 40 +++++++++++-------- .../data/FavoriteListRepositoryImpl.kt | 9 ++++- .../favoritelist/di/FavoriteListModule.kt | 4 +- 8 files changed, 41 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/rusili/superstreet/MainActivity.kt b/app/src/main/java/com/rusili/superstreet/MainActivity.kt index 5272b6f..e67b8c6 100644 --- a/app/src/main/java/com/rusili/superstreet/MainActivity.kt +++ b/app/src/main/java/com/rusili/superstreet/MainActivity.kt @@ -55,6 +55,6 @@ class MainActivity : BaseActivity(), MainNavigator, HasSupportFragmentInjector { } override fun shareLink(link: String) { - internalShareLink(link) + // TODO } } diff --git a/app/src/main/java/com/rusili/superstreet/article/domain/ArticleUsecaseImpl.kt b/app/src/main/java/com/rusili/superstreet/article/domain/ArticleUsecaseImpl.kt index 10b13cd..3a293ef 100644 --- a/app/src/main/java/com/rusili/superstreet/article/domain/ArticleUsecaseImpl.kt +++ b/app/src/main/java/com/rusili/superstreet/article/domain/ArticleUsecaseImpl.kt @@ -1,7 +1,12 @@ package com.rusili.superstreet.article.domain import com.rusili.superstreet.article.ui.ArticleUsecase +import io.reactivex.Single import javax.inject.Inject class ArticleUsecaseImpl @Inject constructor(private val repository: ArticleRepository) : - ArticleRepository by repository + ArticleUsecase { + + override fun getArticle(href: String): Single = + repository.getArticle(href) +} diff --git a/app/src/main/java/com/rusili/superstreet/article/ui/ArticleActivity.kt b/app/src/main/java/com/rusili/superstreet/article/ui/ArticleActivity.kt index 8b0380b..cfb752d 100644 --- a/app/src/main/java/com/rusili/superstreet/article/ui/ArticleActivity.kt +++ b/app/src/main/java/com/rusili/superstreet/article/ui/ArticleActivity.kt @@ -6,6 +6,7 @@ import android.content.IntentSender import android.os.Bundle import android.view.View import androidx.core.app.ActivityOptionsCompat +import androidx.core.content.ContextCompat.startActivity import androidx.core.view.ViewCompat import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders @@ -75,7 +76,6 @@ class ArticleActivity : BaseActivity() { private fun setupViews(header: Header) { articleHeaderImageView.transitionName = header.headerImage.title articleHeaderTitle.text = header.title.value - articleShare.setOnClickListener { internalShareLink(header.title.href) } Glide.with(this) .load(header.headerImage.getDefaultSizeUrl()) diff --git a/app/src/main/java/com/rusili/superstreet/article/ui/rv/ImageGroupViewHolder.kt b/app/src/main/java/com/rusili/superstreet/article/ui/rv/ImageGroupViewHolder.kt index debf940..8b41fc0 100644 --- a/app/src/main/java/com/rusili/superstreet/article/ui/rv/ImageGroupViewHolder.kt +++ b/app/src/main/java/com/rusili/superstreet/article/ui/rv/ImageGroupViewHolder.kt @@ -39,7 +39,6 @@ class ImageGroupViewHolder( ViewCompat.setTransitionName(view, image.id.toString()) glide.load(image.getGroupSizeUrl()) - .override(IMAGE_GROUP_WIDTH, IMAGE_GROUP_HEIGHT) .into(view) view.setOnClickListener { onClick(it, image, ImageSize.GROUP) } diff --git a/app/src/main/java/com/rusili/superstreet/article/ui/rv/ImageViewHolder.kt b/app/src/main/java/com/rusili/superstreet/article/ui/rv/ImageViewHolder.kt index 2282f50..a4bb421 100644 --- a/app/src/main/java/com/rusili/superstreet/article/ui/rv/ImageViewHolder.kt +++ b/app/src/main/java/com/rusili/superstreet/article/ui/rv/ImageViewHolder.kt @@ -31,7 +31,6 @@ class ImageViewHolder( glide.load(model.getDefaultSizeUrl()) .listener(glideListener) - .override(IMAGE_DEFAULT_WIDTH, IMAGE_DEFAULT_HEIGHT) .into(articleImageView) articleImageView.setOnClickListener { onClick(it, model, ImageSize.DEFAULT) } diff --git a/app/src/main/java/com/rusili/superstreet/database/di/DatabaseModule.kt b/app/src/main/java/com/rusili/superstreet/database/di/DatabaseModule.kt index 9ccb857..514ed8a 100644 --- a/app/src/main/java/com/rusili/superstreet/database/di/DatabaseModule.kt +++ b/app/src/main/java/com/rusili/superstreet/database/di/DatabaseModule.kt @@ -8,31 +8,37 @@ import com.rusili.superstreet.database.favorites.FavoriteManager import com.rusili.superstreet.database.favorites.FavoriteManagerImpl import com.rusili.superstreet.database.favorites.model.FavoriteModelMapper import com.rusili.superstreet.di.AppModule +import dagger.Binds import dagger.Module import dagger.Provides private const val DATABASE_NAME = "SuperstreetDb" @Module(includes = [AppModule::class]) -class DatabaseModule { +abstract class DatabaseModule { - @Provides - fun provideFavoriteManager(dao: FavoriteDao): FavoriteManager = - FavoriteManagerImpl(dao) + @Module + companion object { + @JvmStatic + @Provides + fun provideFavoriteModelMapper(): FavoriteModelMapper = + FavoriteModelMapper() - @Provides - fun provideFavoriteModelMapper(): FavoriteModelMapper = - FavoriteModelMapper() + @JvmStatic + @Provides + protected fun provideFavoriteDao(database: AppDatabase): FavoriteDao = + database.favoriteDao() - @Provides - protected fun provideFavoriteDao(database: AppDatabase): FavoriteDao = - database.favoriteDao() + @JvmStatic + @Provides + protected fun provideRoomDatabase(context: Context): AppDatabase = + Room.databaseBuilder( + context, + AppDatabase::class.java, + DATABASE_NAME + ).build() + } - @Provides - protected fun provideRoomDatabase(context: Context): AppDatabase = - Room.databaseBuilder( - context, - AppDatabase::class.java, - DATABASE_NAME - ).build() + @Binds + abstract fun provideFavoriteManager(manager: FavoriteManagerImpl): FavoriteManager } diff --git a/app/src/main/java/com/rusili/superstreet/favoritelist/data/FavoriteListRepositoryImpl.kt b/app/src/main/java/com/rusili/superstreet/favoritelist/data/FavoriteListRepositoryImpl.kt index c2b25f0..85069e2 100644 --- a/app/src/main/java/com/rusili/superstreet/favoritelist/data/FavoriteListRepositoryImpl.kt +++ b/app/src/main/java/com/rusili/superstreet/favoritelist/data/FavoriteListRepositoryImpl.kt @@ -8,5 +8,10 @@ import io.reactivex.Completable import io.reactivex.Single import javax.inject.Inject -class FavoriteListRepositoryImpl @Inject constructor(private val manager: FavoriteManager) : - FavoriteManager by manager +class FavoriteListRepositoryImpl @Inject constructor(private val manager: FavoriteManager) : FavoriteListRepository { + override fun getAllFavorites(): Single> = + manager.getAllFavorites() + + override fun removeFavorite(entity: FavoriteEntity): Completable = + manager.toggleFavorite(entity, false) +} diff --git a/app/src/main/java/com/rusili/superstreet/favoritelist/di/FavoriteListModule.kt b/app/src/main/java/com/rusili/superstreet/favoritelist/di/FavoriteListModule.kt index dc1dc10..63b17e7 100644 --- a/app/src/main/java/com/rusili/superstreet/favoritelist/di/FavoriteListModule.kt +++ b/app/src/main/java/com/rusili/superstreet/favoritelist/di/FavoriteListModule.kt @@ -1,5 +1,7 @@ package com.rusili.superstreet.favoritelist.di +import com.rusili.superstreet.database.di.DatabaseModule +import com.rusili.superstreet.di.AppModule import com.rusili.superstreet.favoritelist.data.FavoriteListRepositoryImpl import com.rusili.superstreet.favoritelist.domain.FavoriteListRepository import com.rusili.superstreet.favoritelist.domain.FavoriteListUsecaseImpl @@ -9,7 +11,7 @@ import dagger.Binds import dagger.Module import dagger.Provides -@Module +@Module(includes = [DatabaseModule::class]) abstract class FavoriteListModule() { @Module From e7aa3bf489a5b93e38f698305f37b77b922a894f Mon Sep 17 00:00:00 2001 From: rusili Date: Sun, 9 Jun 2019 09:56:32 -0400 Subject: [PATCH 05/10] feature/share working foreground circle ripple --- .../superstreet/common/ui/ActionsView.kt | 6 ++ .../common/ui/ShapedRippleImageButton.kt | 56 +++++++++++++++++++ .../viewholder_preview_large.xml | 7 +++ .../viewholder_preview_small.xml | 7 +++ app/src/main/res/layout/activity_article.xml | 7 +-- app/src/main/res/layout/view_actions.xml | 10 ++-- .../res/layout/viewholder_preview_small.xml | 5 +- app/src/main/res/values/dimens.xml | 1 + app/src/main/res/values/styles.xml | 9 ++- 9 files changed, 92 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/com/rusili/superstreet/common/ui/ShapedRippleImageButton.kt diff --git a/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt b/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt index 16d28cb..15b5c22 100644 --- a/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt +++ b/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt @@ -43,3 +43,9 @@ class ActionsView @JvmOverloads constructor( ) } } + +enum class ActionsViewSize { + SMALL, + MEDIUM, + LARGE +} diff --git a/app/src/main/java/com/rusili/superstreet/common/ui/ShapedRippleImageButton.kt b/app/src/main/java/com/rusili/superstreet/common/ui/ShapedRippleImageButton.kt new file mode 100644 index 0000000..9bd3c3c --- /dev/null +++ b/app/src/main/java/com/rusili/superstreet/common/ui/ShapedRippleImageButton.kt @@ -0,0 +1,56 @@ +package com.rusili.superstreet.common.ui + +import android.content.Context +import android.content.res.ColorStateList +import android.graphics.drawable.Drawable +import android.graphics.drawable.RippleDrawable +import android.graphics.drawable.ShapeDrawable +import android.graphics.drawable.shapes.OvalShape +import android.graphics.drawable.shapes.Shape +import android.os.Build +import android.util.AttributeSet +import android.widget.ImageButton +import androidx.annotation.ColorInt +import com.rusili.superstreet.R + +class ShapedRippleImageButton @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ImageButton(context, attrs, defStyleAttr) { + + init { + val buttonShape = OvalShape() + + @ColorInt val fillColor = resources.getColor(android.R.color.transparent) + @ColorInt val maskColor = resources.getColor(R.color.black_30_1000) + + background?.let { + setBackgroundRippleShape(it, buttonShape) + } ?: setForegroundRippleShape(buttonShape, fillColor, maskColor) + } + + private fun setBackgroundRippleShape( + background: Drawable, + buttonShape: Shape + ) { + (background as RippleDrawable).apply { + (getDrawable(0) as ShapeDrawable).apply { shape = buttonShape } + (getDrawable(1) as ShapeDrawable).apply { shape = buttonShape } + } + } + + private fun setForegroundRippleShape( + buttonShape: Shape, + fillColor: Int, + maskColor: Int + ) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + foreground = RippleDrawable( + ColorStateList.valueOf(maskColor), + ShapeDrawable(buttonShape).apply { paint.color = fillColor }, + ShapeDrawable(buttonShape).apply { paint.color = maskColor } + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout-sw600dp/viewholder_preview_large.xml b/app/src/main/res/layout-sw600dp/viewholder_preview_large.xml index 555d150..9cf89ec 100644 --- a/app/src/main/res/layout-sw600dp/viewholder_preview_large.xml +++ b/app/src/main/res/layout-sw600dp/viewholder_preview_large.xml @@ -53,4 +53,11 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/previewTitle" tools:text="1 week ago" /> + + + diff --git a/app/src/main/res/layout-sw600dp/viewholder_preview_small.xml b/app/src/main/res/layout-sw600dp/viewholder_preview_small.xml index 774fd19..1a2ba86 100644 --- a/app/src/main/res/layout-sw600dp/viewholder_preview_small.xml +++ b/app/src/main/res/layout-sw600dp/viewholder_preview_small.xml @@ -51,4 +51,11 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/previewTitle" tools:text="1 week ago" /> + + + diff --git a/app/src/main/res/layout/activity_article.xml b/app/src/main/res/layout/activity_article.xml index 7ba585a..22c7a03 100644 --- a/app/src/main/res/layout/activity_article.xml +++ b/app/src/main/res/layout/activity_article.xml @@ -45,13 +45,10 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" /> - - - diff --git a/app/src/main/res/layout/viewholder_preview_small.xml b/app/src/main/res/layout/viewholder_preview_small.xml index 9aea368..fdadb6c 100644 --- a/app/src/main/res/layout/viewholder_preview_small.xml +++ b/app/src/main/res/layout/viewholder_preview_small.xml @@ -62,12 +62,9 @@ app:layout_constraintTop_toBottomOf="@id/previewTitle" tools:text="1 week ago" /> - diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 0d6af0a..a93ed4c 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -6,6 +6,7 @@ 64dp 2dp 64dp + 16dp 4dp diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 144d249..0383640 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,5 +1,11 @@ + + + From 6033e58ae2728136592e3d9c6259433cad1f6bbd Mon Sep 17 00:00:00 2001 From: rusili Date: Sun, 9 Jun 2019 10:48:27 -0400 Subject: [PATCH 06/10] improvement/actionsview added logic for ActionsView --- .../superstreet/common/ui/ActionsView.kt | 55 ++++++++++++++++--- .../{base => ui}/StyleableFrameLayout.kt | 8 +-- app/src/main/res/drawable/ic_bookmark.xml | 4 +- app/src/main/res/layout/view_actions.xml | 8 +-- app/src/main/res/values/attrs.xml | 12 ++++ app/src/main/res/values/dimens.xml | 7 ++- app/src/main/res/values/styles.xml | 19 ++++++- 7 files changed, 92 insertions(+), 21 deletions(-) rename app/src/main/java/com/rusili/superstreet/common/{base => ui}/StyleableFrameLayout.kt (82%) create mode 100644 app/src/main/res/values/attrs.xml diff --git a/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt b/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt index 15b5c22..97a3908 100644 --- a/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt +++ b/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt @@ -4,10 +4,10 @@ import android.content.Context import android.content.Intent import android.content.res.TypedArray import android.util.AttributeSet +import android.widget.ImageButton import android.widget.ImageView -import androidx.core.content.ContextCompat.startActivity +import androidx.core.view.size import com.rusili.superstreet.R -import com.rusili.superstreet.common.base.StyleableFrameLayout private const val STRING_SHARE_TYPE = "text/plain" private const val STRING_SHARE_SUBJECT = "Sharing URL" @@ -18,12 +18,48 @@ class ActionsView @JvmOverloads constructor( attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : StyleableFrameLayout(context, attrs, defStyleAttr) { + val allActionViews = setOf(actionFavorite, actionShare) + lateinit var actionFavorite: ImageButton + private set + lateinit var actionShare: ImageButton + private set + var favoriteAction: (() -> Unit)? = null override fun getLayout(): Int? = R.layout.view_actions + override fun getStyleable(): IntArray = R.styleable.ActionsView override fun TypedArray.setupViews() { - findViewById(R.id.actionFavorite).setOnClickListener { favoriteAction?.invoke() } + actionFavorite = findViewById(R.id.actionFavorite) + actionShare = findViewById(R.id.actionShare) + + selectSize() + } + + private fun TypedArray.selectSize() { + val smallDimens = resources.getDimension(R.dimen.action_button_height_small) + val mediumDimens = resources.getDimension(R.dimen.action_button_height_medium) + val largeDimens = resources.getDimension(R.dimen.action_button_height_large) + + getInt(R.styleable.ActionsView_size, -1) + .takeIf { it != -1 } + ?.let(ActionsViewSize.Companion::fromAttr) + ?.let { size -> + when (size) { + ActionsViewSize.SMALL -> applySize(smallDimens) + ActionsViewSize.MEDIUM -> applySize(mediumDimens) + ActionsViewSize.LARGE -> applySize(largeDimens) + } + } + } + + private fun applySize(dimension: Float) { + allActionViews.forEach { view -> + view.layoutParams.apply { + height = dimension.toInt() + width = dimension.toInt() + } + } } fun setShareLink(link: String) { @@ -44,8 +80,13 @@ class ActionsView @JvmOverloads constructor( } } -enum class ActionsViewSize { - SMALL, - MEDIUM, - LARGE +enum class ActionsViewSize(val attr: Int) { + SMALL(0), + MEDIUM(1), + LARGE(2); + + companion object { + fun fromAttr(input: Int): ActionsViewSize = + values().first { it.attr == input } + } } diff --git a/app/src/main/java/com/rusili/superstreet/common/base/StyleableFrameLayout.kt b/app/src/main/java/com/rusili/superstreet/common/ui/StyleableFrameLayout.kt similarity index 82% rename from app/src/main/java/com/rusili/superstreet/common/base/StyleableFrameLayout.kt rename to app/src/main/java/com/rusili/superstreet/common/ui/StyleableFrameLayout.kt index ecfc8c4..dbb33f1 100644 --- a/app/src/main/java/com/rusili/superstreet/common/base/StyleableFrameLayout.kt +++ b/app/src/main/java/com/rusili/superstreet/common/ui/StyleableFrameLayout.kt @@ -1,4 +1,4 @@ -package com.rusili.superstreet.common.base +package com.rusili.superstreet.common.ui import android.content.Context import android.content.res.TypedArray @@ -6,7 +6,6 @@ import android.util.AttributeSet import android.widget.FrameLayout import androidx.annotation.LayoutRes import androidx.annotation.StyleableRes -import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.withStyledAttributes abstract class StyleableFrameLayout @JvmOverloads constructor( @@ -23,7 +22,8 @@ abstract class StyleableFrameLayout @JvmOverloads constructor( context.withStyledAttributes( attrs, this.getStyleable(), - defStyleAttr, 0 + defStyleAttr, + 0 ) { setupViews() } @@ -35,5 +35,5 @@ abstract class StyleableFrameLayout @JvmOverloads constructor( abstract fun TypedArray.setupViews() @StyleableRes - fun getStyleable(): IntArray = IntArray(0) + open fun getStyleable(): IntArray = IntArray(0) } diff --git a/app/src/main/res/drawable/ic_bookmark.xml b/app/src/main/res/drawable/ic_bookmark.xml index bcd12cf..6c8d538 100644 --- a/app/src/main/res/drawable/ic_bookmark.xml +++ b/app/src/main/res/drawable/ic_bookmark.xml @@ -1,6 +1,6 @@ diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml new file mode 100644 index 0000000..bb55421 --- /dev/null +++ b/app/src/main/res/values/attrs.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index a93ed4c..587311d 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -6,7 +6,12 @@ 64dp 2dp 64dp - 16dp + 10dp + 16dp + 20dp + 32dp + 48dp + 64dp 4dp diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 0383640..65182bd 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -3,7 +3,24 @@ + + + + + + From 4713c32c36ffb7528318985d6541ee823a55eb86 Mon Sep 17 00:00:00 2001 From: rusili Date: Sun, 9 Jun 2019 12:10:07 -0400 Subject: [PATCH 07/10] improvement/actionsview working padding and dimension setting --- .../common/extensions/TypedArrayExtensions.kt | 6 ++ .../superstreet/common/ui/ActionsView.kt | 61 ++++++++++++------- .../common/ui/ShapedRippleImageButton.kt | 14 ++++- .../common/ui/StyleableFrameLayout.kt | 4 ++ app/src/main/res/layout/activity_article.xml | 3 +- app/src/main/res/layout/view_actions.xml | 10 ++- .../res/layout/viewholder_preview_large.xml | 3 +- app/src/main/res/values/dimens.xml | 8 +-- app/src/main/res/values/styles.xml | 6 +- 9 files changed, 82 insertions(+), 33 deletions(-) create mode 100644 app/src/main/java/com/rusili/superstreet/common/extensions/TypedArrayExtensions.kt diff --git a/app/src/main/java/com/rusili/superstreet/common/extensions/TypedArrayExtensions.kt b/app/src/main/java/com/rusili/superstreet/common/extensions/TypedArrayExtensions.kt new file mode 100644 index 0000000..8429f16 --- /dev/null +++ b/app/src/main/java/com/rusili/superstreet/common/extensions/TypedArrayExtensions.kt @@ -0,0 +1,6 @@ +package com.rusili.superstreet.common.extensions + +import android.content.res.TypedArray + +fun TypedArray.getDimen(id: Int) = + resources.getDimensionPixelSize(id) diff --git a/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt b/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt index 97a3908..eac3f0f 100644 --- a/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt +++ b/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt @@ -3,11 +3,14 @@ package com.rusili.superstreet.common.ui import android.content.Context import android.content.Intent import android.content.res.TypedArray +import android.icu.lang.UCharacter.GraphemeClusterBreak.L import android.util.AttributeSet import android.widget.ImageButton import android.widget.ImageView -import androidx.core.view.size +import android.widget.LinearLayout +import androidx.core.view.setPadding import com.rusili.superstreet.R +import com.rusili.superstreet.common.extensions.getDimen private const val STRING_SHARE_TYPE = "text/plain" private const val STRING_SHARE_SUBJECT = "Sharing URL" @@ -18,11 +21,12 @@ class ActionsView @JvmOverloads constructor( attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : StyleableFrameLayout(context, attrs, defStyleAttr) { - val allActionViews = setOf(actionFavorite, actionShare) lateinit var actionFavorite: ImageButton private set lateinit var actionShare: ImageButton private set + lateinit var allActionViews: List + private set var favoriteAction: (() -> Unit)? = null @@ -32,32 +36,42 @@ class ActionsView @JvmOverloads constructor( override fun TypedArray.setupViews() { actionFavorite = findViewById(R.id.actionFavorite) actionShare = findViewById(R.id.actionShare) + allActionViews = listOf(actionFavorite, actionShare) selectSize() } private fun TypedArray.selectSize() { - val smallDimens = resources.getDimension(R.dimen.action_button_height_small) - val mediumDimens = resources.getDimension(R.dimen.action_button_height_medium) - val largeDimens = resources.getDimension(R.dimen.action_button_height_large) + val smallStyle = ViewStyle( + length = getDimen(R.dimen.action_button_height_small), + padding = getDimen(R.dimen.action_button_padding_small) + ) + val mediumStyle = ViewStyle( + length = getDimen(R.dimen.action_button_height_medium), + padding = getDimen(R.dimen.action_button_padding_medium) + ) + val largeStyle = ViewStyle( + length = getDimen(R.dimen.action_button_height_large), + padding = getDimen(R.dimen.action_button_padding_large) + ) getInt(R.styleable.ActionsView_size, -1) .takeIf { it != -1 } - ?.let(ActionsViewSize.Companion::fromAttr) + ?.let(ViewSize.Companion::fromAttr) ?.let { size -> when (size) { - ActionsViewSize.SMALL -> applySize(smallDimens) - ActionsViewSize.MEDIUM -> applySize(mediumDimens) - ActionsViewSize.LARGE -> applySize(largeDimens) + ViewSize.SMALL -> applySize(smallStyle) + ViewSize.MEDIUM -> applySize(mediumStyle) + ViewSize.LARGE -> applySize(largeStyle) } } } - private fun applySize(dimension: Float) { + private fun applySize(style: ViewStyle) { allActionViews.forEach { view -> - view.layoutParams.apply { - height = dimension.toInt() - width = dimension.toInt() + view.apply { + layoutParams = LinearLayout.LayoutParams(style.length, style.length) + setPadding(style.padding) } } } @@ -78,15 +92,20 @@ class ActionsView @JvmOverloads constructor( ) ) } -} -enum class ActionsViewSize(val attr: Int) { - SMALL(0), - MEDIUM(1), - LARGE(2); + private enum class ViewSize(val attr: Int) { + SMALL(0), + MEDIUM(1), + LARGE(2); - companion object { - fun fromAttr(input: Int): ActionsViewSize = - values().first { it.attr == input } + companion object { + fun fromAttr(input: Int): ViewSize = + values().first { it.attr == input } + } } + + private data class ViewStyle( + val length: Int, + val padding: Int + ) } diff --git a/app/src/main/java/com/rusili/superstreet/common/ui/ShapedRippleImageButton.kt b/app/src/main/java/com/rusili/superstreet/common/ui/ShapedRippleImageButton.kt index 9bd3c3c..73a4118 100644 --- a/app/src/main/java/com/rusili/superstreet/common/ui/ShapedRippleImageButton.kt +++ b/app/src/main/java/com/rusili/superstreet/common/ui/ShapedRippleImageButton.kt @@ -11,6 +11,7 @@ import android.os.Build import android.util.AttributeSet import android.widget.ImageButton import androidx.annotation.ColorInt +import androidx.core.content.withStyledAttributes import com.rusili.superstreet.R class ShapedRippleImageButton @JvmOverloads constructor( @@ -20,6 +21,17 @@ class ShapedRippleImageButton @JvmOverloads constructor( ) : ImageButton(context, attrs, defStyleAttr) { init { + context.withStyledAttributes( + attrs, + IntArray(0), + defStyleAttr, + 0 + ) { + setupViews() + } + } + + private fun setupViews() { val buttonShape = OvalShape() @ColorInt val fillColor = resources.getColor(android.R.color.transparent) @@ -53,4 +65,4 @@ class ShapedRippleImageButton @JvmOverloads constructor( ) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/rusili/superstreet/common/ui/StyleableFrameLayout.kt b/app/src/main/java/com/rusili/superstreet/common/ui/StyleableFrameLayout.kt index dbb33f1..daf7b44 100644 --- a/app/src/main/java/com/rusili/superstreet/common/ui/StyleableFrameLayout.kt +++ b/app/src/main/java/com/rusili/superstreet/common/ui/StyleableFrameLayout.kt @@ -27,6 +27,8 @@ abstract class StyleableFrameLayout @JvmOverloads constructor( ) { setupViews() } + + post(::postSetup) } @LayoutRes @@ -36,4 +38,6 @@ abstract class StyleableFrameLayout @JvmOverloads constructor( @StyleableRes open fun getStyleable(): IntArray = IntArray(0) + + open fun postSetup() = Unit } diff --git a/app/src/main/res/layout/activity_article.xml b/app/src/main/res/layout/activity_article.xml index 22c7a03..ef8f4eb 100644 --- a/app/src/main/res/layout/activity_article.xml +++ b/app/src/main/res/layout/activity_article.xml @@ -49,7 +49,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="@id/articleHeaderImageView" - app:layout_constraintRight_toRightOf="parent" /> + app:layout_constraintRight_toRightOf="parent" + app:size="small" /> diff --git a/app/src/main/res/layout/viewholder_preview_large.xml b/app/src/main/res/layout/viewholder_preview_large.xml index f031c68..46e8966 100644 --- a/app/src/main/res/layout/viewholder_preview_large.xml +++ b/app/src/main/res/layout/viewholder_preview_large.xml @@ -68,6 +68,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="@id/previewThumbnail" - app:layout_constraintRight_toRightOf="parent" /> + app:layout_constraintRight_toRightOf="parent" + app:size="large" /> diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 587311d..23e4be0 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -6,11 +6,11 @@ 64dp 2dp 64dp - 10dp - 16dp - 20dp + 10dp + 14dp + 20dp 32dp - 48dp + 40dp 64dp diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 65182bd..a130f14 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -8,19 +8,19 @@ From 283d1e91407c7a19e938117dc1fd80d2bf32c91c Mon Sep 17 00:00:00 2001 From: rusili Date: Sat, 15 Jun 2019 11:03:01 -0400 Subject: [PATCH 08/10] improvement/actionsview working share link for previewviewholder --- .../common/extensions/StringExtensions.kt | 2 + .../superstreet/common/ui/ActionsView.kt | 45 ++++++++++++------- .../common/ui/ShapedRippleImageButton.kt | 15 +++++-- .../previewlist/ui/rv/PreviewViewHolder.kt | 16 ++++++- .../res/layout/viewholder_preview_large.xml | 3 +- .../res/layout/viewholder_preview_small.xml | 4 +- app/src/main/res/values/attrs.xml | 5 +++ app/src/main/res/values/dimens.xml | 2 +- 8 files changed, 67 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/rusili/superstreet/common/extensions/StringExtensions.kt b/app/src/main/java/com/rusili/superstreet/common/extensions/StringExtensions.kt index b1541d6..3791f9e 100644 --- a/app/src/main/java/com/rusili/superstreet/common/extensions/StringExtensions.kt +++ b/app/src/main/java/com/rusili/superstreet/common/extensions/StringExtensions.kt @@ -1,4 +1,6 @@ package com.rusili.superstreet.common.extensions +import com.rusili.superstreet.jsoup.api.BASE_HTML + fun String.remove(toRemove: String) = replace(toRemove, "") diff --git a/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt b/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt index eac3f0f..46dded4 100644 --- a/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt +++ b/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt @@ -3,14 +3,15 @@ package com.rusili.superstreet.common.ui import android.content.Context import android.content.Intent import android.content.res.TypedArray -import android.icu.lang.UCharacter.GraphemeClusterBreak.L import android.util.AttributeSet import android.widget.ImageButton import android.widget.ImageView import android.widget.LinearLayout +import android.widget.Toast import androidx.core.view.setPadding import com.rusili.superstreet.R import com.rusili.superstreet.common.extensions.getDimen +import com.rusili.superstreet.jsoup.api.BASE_HTML private const val STRING_SHARE_TYPE = "text/plain" private const val STRING_SHARE_SUBJECT = "Sharing URL" @@ -21,14 +22,9 @@ class ActionsView @JvmOverloads constructor( attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : StyleableFrameLayout(context, attrs, defStyleAttr) { - lateinit var actionFavorite: ImageButton - private set - lateinit var actionShare: ImageButton - private set - lateinit var allActionViews: List - private set - - var favoriteAction: (() -> Unit)? = null + private lateinit var actionFavorite: ImageButton + private lateinit var actionShare: ImageButton + private lateinit var allActionViews: List override fun getLayout(): Int? = R.layout.view_actions override fun getStyleable(): IntArray = R.styleable.ActionsView @@ -38,10 +34,24 @@ class ActionsView @JvmOverloads constructor( actionShare = findViewById(R.id.actionShare) allActionViews = listOf(actionFavorite, actionShare) - selectSize() + setSize() + } + + fun setShareLink(link: String) { + findViewById(R.id.actionShare).setOnClickListener { shareLink(link) } + } + + fun setFavoriteAction() { + findViewById(R.id.actionFavorite).setOnClickListener { + Toast.makeText( + context, + "TEST", + Toast.LENGTH_SHORT + ).show() + } } - private fun TypedArray.selectSize() { + private fun TypedArray.setSize() { val smallStyle = ViewStyle( length = getDimen(R.dimen.action_button_height_small), padding = getDimen(R.dimen.action_button_padding_small) @@ -68,31 +78,32 @@ class ActionsView @JvmOverloads constructor( } private fun applySize(style: ViewStyle) { + val params = LinearLayout.LayoutParams(style.length, style.length) + allActionViews.forEach { view -> view.apply { - layoutParams = LinearLayout.LayoutParams(style.length, style.length) + layoutParams = params setPadding(style.padding) } } } - fun setShareLink(link: String) { - findViewById(R.id.actionShare).setOnClickListener { shareLink(link) } - } - private fun shareLink(link: String) { context.startActivity( Intent.createChooser( Intent(Intent.ACTION_SEND).apply { setType(STRING_SHARE_TYPE) putExtra(Intent.EXTRA_SUBJECT, STRING_SHARE_SUBJECT) - putExtra(Intent.EXTRA_TEXT, link) + putExtra(Intent.EXTRA_TEXT, addDomainToLink(link)) }, STRING_SHARE_VIA ) ) } + private fun addDomainToLink(link: String) = + BASE_HTML.plus(link) + private enum class ViewSize(val attr: Int) { SMALL(0), MEDIUM(1), diff --git a/app/src/main/java/com/rusili/superstreet/common/ui/ShapedRippleImageButton.kt b/app/src/main/java/com/rusili/superstreet/common/ui/ShapedRippleImageButton.kt index 73a4118..70ec255 100644 --- a/app/src/main/java/com/rusili/superstreet/common/ui/ShapedRippleImageButton.kt +++ b/app/src/main/java/com/rusili/superstreet/common/ui/ShapedRippleImageButton.kt @@ -1,7 +1,9 @@ package com.rusili.superstreet.common.ui +import android.annotation.SuppressLint import android.content.Context import android.content.res.ColorStateList +import android.content.res.TypedArray import android.graphics.drawable.Drawable import android.graphics.drawable.RippleDrawable import android.graphics.drawable.ShapeDrawable @@ -11,9 +13,13 @@ import android.os.Build import android.util.AttributeSet import android.widget.ImageButton import androidx.annotation.ColorInt +import androidx.core.content.res.getColorOrThrow import androidx.core.content.withStyledAttributes import com.rusili.superstreet.R +@SuppressLint("ResourceAsColor") +private const @ColorInt val MASK_COLOR_DEFAULT: Int = R.color.black_10_1000 + class ShapedRippleImageButton @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, @@ -23,7 +29,7 @@ class ShapedRippleImageButton @JvmOverloads constructor( init { context.withStyledAttributes( attrs, - IntArray(0), + R.styleable.ShapedRippleImageButton, defStyleAttr, 0 ) { @@ -31,11 +37,14 @@ class ShapedRippleImageButton @JvmOverloads constructor( } } - private fun setupViews() { + private fun TypedArray.setupViews() { val buttonShape = OvalShape() @ColorInt val fillColor = resources.getColor(android.R.color.transparent) - @ColorInt val maskColor = resources.getColor(R.color.black_30_1000) + @ColorInt val maskColor = getColor( + R.styleable.ShapedRippleImageButton_ripple_color, + MASK_COLOR_DEFAULT + ) background?.let { setBackgroundRippleShape(it, buttonShape) diff --git a/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt b/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt index d516f62..54cfc03 100644 --- a/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt +++ b/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt @@ -24,7 +24,6 @@ class PreviewViewHolder( private val glide: RequestManager, private val dateHelper: DateHelper ) : BaseViewHolder(containerView), LayoutContainer { - override fun bind(model: ArticlePreviewModel) { if (adapterPosition > 2) { animate() @@ -32,8 +31,14 @@ class PreviewViewHolder( setupImage(model) setText(model) + setActionsView(model) - previewBackground.setOnClickListener { navigator.goToArticle(previewThumbnail, model.header) } + previewBackground.setOnClickListener { + navigator.goToArticle( + previewThumbnail, + model.header + ) + } } private fun animate() { @@ -45,6 +50,13 @@ class PreviewViewHolder( ) } + fun setActionsView(model: ArticlePreviewModel) { + previewActionsView.apply { + setShareLink(model.header.title.href) + setFavoriteAction() + } + } + private fun setupImage(model: ArticlePreviewModel) { ViewCompat.setTransitionName(previewThumbnail, model.header.headerImage.title) ViewCompat.setTransitionName(previewLayout, model.header.headerImage.getDefaultSizeUrl()) diff --git a/app/src/main/res/layout/viewholder_preview_large.xml b/app/src/main/res/layout/viewholder_preview_large.xml index 46e8966..d800ddd 100644 --- a/app/src/main/res/layout/viewholder_preview_large.xml +++ b/app/src/main/res/layout/viewholder_preview_large.xml @@ -65,10 +65,11 @@ tools:text="1 week ago" /> + app:size="small" /> diff --git a/app/src/main/res/layout/viewholder_preview_small.xml b/app/src/main/res/layout/viewholder_preview_small.xml index fdadb6c..e4537b6 100644 --- a/app/src/main/res/layout/viewholder_preview_small.xml +++ b/app/src/main/res/layout/viewholder_preview_small.xml @@ -63,9 +63,11 @@ tools:text="1 week ago" /> + app:layout_constraintRight_toRightOf="parent" + app:size="small" /> diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index bb55421..d6481b4 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -9,4 +9,9 @@ + + + + + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 23e4be0..22c631f 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -10,7 +10,7 @@ 14dp 20dp 32dp - 40dp + 48dp 64dp From aa8d90883e07e8b9f855795a7eed8e986273569e Mon Sep 17 00:00:00 2001 From: rusili Date: Sat, 15 Jun 2019 12:04:28 -0400 Subject: [PATCH 09/10] improvement/actionsview added back button on imageactivity --- .../superstreet/article/ui/ArticleActivity.kt | 18 ++++++++---- .../article/ui/ArticleViewModel.kt | 2 +- .../article/ui/rv/ArticleAdapter.kt | 4 +++ .../superstreet/common/base/BaseActivity.kt | 2 +- .../common/ui/{ => actions}/ActionsView.kt | 7 +++-- .../common/ui/actions/HasActionsView.kt | 6 ++++ .../rusili/superstreet/image/ImageActivity.kt | 2 ++ .../previewlist/ui/rv/PreviewViewHolder.kt | 28 ++++++++++--------- app/src/main/res/drawable/ic_bookmark.xml | 4 +-- app/src/main/res/drawable/ic_left_arrow.xml | 9 ++++++ .../main/res/layout-land/activity_image.xml | 12 ++++++++ .../viewholder_preview_large.xml | 6 ++-- .../viewholder_preview_small.xml | 6 ++-- app/src/main/res/layout/activity_article.xml | 3 +- app/src/main/res/layout/activity_image.xml | 12 ++++++++ .../res/layout/viewholder_preview_large.xml | 2 +- .../res/layout/viewholder_preview_small.xml | 2 +- 17 files changed, 93 insertions(+), 32 deletions(-) rename app/src/main/java/com/rusili/superstreet/common/ui/{ => actions}/ActionsView.kt (94%) create mode 100644 app/src/main/java/com/rusili/superstreet/common/ui/actions/HasActionsView.kt create mode 100644 app/src/main/res/drawable/ic_left_arrow.xml diff --git a/app/src/main/java/com/rusili/superstreet/article/ui/ArticleActivity.kt b/app/src/main/java/com/rusili/superstreet/article/ui/ArticleActivity.kt index cfb752d..ff47b59 100644 --- a/app/src/main/java/com/rusili/superstreet/article/ui/ArticleActivity.kt +++ b/app/src/main/java/com/rusili/superstreet/article/ui/ArticleActivity.kt @@ -22,6 +22,7 @@ import com.rusili.superstreet.common.models.Header import com.rusili.superstreet.common.models.body.Image import com.rusili.superstreet.common.models.body.ImageSize import com.rusili.superstreet.common.ui.SimpleRequestListener +import com.rusili.superstreet.common.ui.actions.HasActionsView import com.rusili.superstreet.image.ImageActivity import com.rusili.superstreet.image.ImageActivity.Companion.IMAGE_BUNDLE_KEY import com.rusili.superstreet.image.ImageActivity.Companion.IMAGE_SIZE_BUNDLE_KEY @@ -30,18 +31,15 @@ import com.squareup.moshi.Moshi import kotlinx.android.synthetic.main.activity_article.* import javax.inject.Inject -class ArticleActivity : BaseActivity() { +class ArticleActivity : BaseActivity(), HasActionsView { @Inject protected lateinit var viewModelFactory: ArticleViewModelFactory @Inject protected lateinit var moshi: Moshi private val viewModel: ArticleViewModel by lazy { ViewModelProviders.of(this, viewModelFactory).get(ArticleViewModel::class.java) } - private val adapter: ArticleAdapter by lazy { - ArticleAdapter(::onImageClicked, Glide.with(this)).apply { - setHasStableIds(true) - } + ArticleAdapter(::onImageClicked, Glide.with(this)) } companion object { @@ -56,6 +54,7 @@ class ArticleActivity : BaseActivity() { intent?.getStringExtra(ARTICLE_HEADER_BUNDLE_KEY)?.let { json -> moshi.adapter
(Header::class.java).fromJson(json)?.let { header -> setupViews(header) + setActionsView(header.title.href) articleProgressBar.show() viewModel.getArticle(header.title.href) } @@ -73,6 +72,13 @@ class ArticleActivity : BaseActivity() { }) } + override fun setActionsView(link: String) { + articleActionsView.apply { + setFavoriteAction() + setShareLink(link) + } + } + private fun setupViews(header: Header) { articleHeaderImageView.transitionName = header.headerImage.title articleHeaderTitle.text = header.title.value @@ -114,7 +120,7 @@ class ArticleActivity : BaseActivity() { val options = ActivityOptionsCompat.makeSceneTransitionAnimation( this@ArticleActivity, view, - ViewCompat.getTransitionName(view)!! + ViewCompat.getTransitionName(view) ?: "" ) startActivity(this, options.toBundle()) } diff --git a/app/src/main/java/com/rusili/superstreet/article/ui/ArticleViewModel.kt b/app/src/main/java/com/rusili/superstreet/article/ui/ArticleViewModel.kt index 2fda18c..f82c754 100644 --- a/app/src/main/java/com/rusili/superstreet/article/ui/ArticleViewModel.kt +++ b/app/src/main/java/com/rusili/superstreet/article/ui/ArticleViewModel.kt @@ -19,8 +19,8 @@ class ArticleViewModel(private val usecase: ArticleUsecase) : BaseViewModel() { .subscribeBy( onSuccess = { livedata.postValue(LiveDataWrapper(it)) }, onError = { - livedata.postValue(LiveDataWrapper(null, it)) Timber.e(it, "Error getting preview articles.") + livedata.postValue(LiveDataWrapper(null, it)) } )) } diff --git a/app/src/main/java/com/rusili/superstreet/article/ui/rv/ArticleAdapter.kt b/app/src/main/java/com/rusili/superstreet/article/ui/rv/ArticleAdapter.kt index b43c68b..45c9b33 100644 --- a/app/src/main/java/com/rusili/superstreet/article/ui/rv/ArticleAdapter.kt +++ b/app/src/main/java/com/rusili/superstreet/article/ui/rv/ArticleAdapter.kt @@ -18,6 +18,10 @@ class ArticleAdapter( private val glide: RequestManager ) : ListAdapter(ArticleDiffCallback()) { + init { + setHasStableIds(true) + } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder = when (viewType) { ArticleViewType.Paragraph.viewType -> ParagraphViewHolder(parent.inflate(R.layout.viewholder_article_paragraph)) diff --git a/app/src/main/java/com/rusili/superstreet/common/base/BaseActivity.kt b/app/src/main/java/com/rusili/superstreet/common/base/BaseActivity.kt index ecd4f92..bf01507 100644 --- a/app/src/main/java/com/rusili/superstreet/common/base/BaseActivity.kt +++ b/app/src/main/java/com/rusili/superstreet/common/base/BaseActivity.kt @@ -15,7 +15,7 @@ import java.net.UnknownHostException abstract class BaseActivity : AppCompatActivity() { protected val disposable = CompositeDisposable() - var container = 0 + protected var container = 0 override fun onCreate(savedInstanceState: Bundle?) { AndroidInjection.inject(this) diff --git a/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt b/app/src/main/java/com/rusili/superstreet/common/ui/actions/ActionsView.kt similarity index 94% rename from app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt rename to app/src/main/java/com/rusili/superstreet/common/ui/actions/ActionsView.kt index 46dded4..70bb3bf 100644 --- a/app/src/main/java/com/rusili/superstreet/common/ui/ActionsView.kt +++ b/app/src/main/java/com/rusili/superstreet/common/ui/actions/ActionsView.kt @@ -1,4 +1,4 @@ -package com.rusili.superstreet.common.ui +package com.rusili.superstreet.common.ui.actions import android.content.Context import android.content.Intent @@ -11,6 +11,7 @@ import android.widget.Toast import androidx.core.view.setPadding import com.rusili.superstreet.R import com.rusili.superstreet.common.extensions.getDimen +import com.rusili.superstreet.common.ui.StyleableFrameLayout import com.rusili.superstreet.jsoup.api.BASE_HTML private const val STRING_SHARE_TYPE = "text/plain" @@ -93,7 +94,9 @@ class ActionsView @JvmOverloads constructor( Intent.createChooser( Intent(Intent.ACTION_SEND).apply { setType(STRING_SHARE_TYPE) - putExtra(Intent.EXTRA_SUBJECT, STRING_SHARE_SUBJECT) + putExtra(Intent.EXTRA_SUBJECT, + STRING_SHARE_SUBJECT + ) putExtra(Intent.EXTRA_TEXT, addDomainToLink(link)) }, STRING_SHARE_VIA diff --git a/app/src/main/java/com/rusili/superstreet/common/ui/actions/HasActionsView.kt b/app/src/main/java/com/rusili/superstreet/common/ui/actions/HasActionsView.kt new file mode 100644 index 0000000..6364431 --- /dev/null +++ b/app/src/main/java/com/rusili/superstreet/common/ui/actions/HasActionsView.kt @@ -0,0 +1,6 @@ +package com.rusili.superstreet.common.ui.actions + +interface HasActionsView { + + fun setActionsView(link: String) +} diff --git a/app/src/main/java/com/rusili/superstreet/image/ImageActivity.kt b/app/src/main/java/com/rusili/superstreet/image/ImageActivity.kt index a60a4b5..6231ccd 100644 --- a/app/src/main/java/com/rusili/superstreet/image/ImageActivity.kt +++ b/app/src/main/java/com/rusili/superstreet/image/ImageActivity.kt @@ -106,6 +106,8 @@ class ImageActivity : BaseActivity() { } private fun setOnClickListeners(image: Image) { + activityImageBack.setOnClickListener { finish() } + activityImageSaveButton.setOnClickListener { saveImage( image = (activityImagePhotoView as PhotoView).drawable as BitmapDrawable, diff --git a/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt b/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt index 54cfc03..be086f8 100644 --- a/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt +++ b/app/src/main/java/com/rusili/superstreet/previewlist/ui/rv/PreviewViewHolder.kt @@ -10,6 +10,7 @@ import com.rusili.superstreet.R import com.rusili.superstreet.common.base.BaseViewHolder import com.rusili.superstreet.common.models.header.HeaderImage.Companion.HEADER_IMAGE_HEIGHT import com.rusili.superstreet.common.models.header.HeaderImage.Companion.HEADER_IMAGE_WIDTH +import com.rusili.superstreet.common.ui.actions.HasActionsView import com.rusili.superstreet.previewlist.DateHelper import com.rusili.superstreet.previewlist.domain.ArticlePreviewModel import kotlinx.android.extensions.LayoutContainer @@ -23,24 +24,32 @@ class PreviewViewHolder( private val navigator: MainNavigator, private val glide: RequestManager, private val dateHelper: DateHelper -) : BaseViewHolder(containerView), LayoutContainer { +) : BaseViewHolder(containerView), LayoutContainer, HasActionsView { + override fun bind(model: ArticlePreviewModel) { if (adapterPosition > 2) { animate() } - setupImage(model) + setImage(model) setText(model) - setActionsView(model) + setActionsView(model.header.title.href) previewBackground.setOnClickListener { navigator.goToArticle( - previewThumbnail, - model.header + view = previewThumbnail, + header = model.header ) } } + override fun setActionsView(link: String) { + previewActionsView.apply { + setShareLink(link) + setFavoriteAction() + } + } + private fun animate() { itemView.startAnimation( AnimationUtils.loadAnimation( @@ -50,14 +59,7 @@ class PreviewViewHolder( ) } - fun setActionsView(model: ArticlePreviewModel) { - previewActionsView.apply { - setShareLink(model.header.title.href) - setFavoriteAction() - } - } - - private fun setupImage(model: ArticlePreviewModel) { + private fun setImage(model: ArticlePreviewModel) { ViewCompat.setTransitionName(previewThumbnail, model.header.headerImage.title) ViewCompat.setTransitionName(previewLayout, model.header.headerImage.getDefaultSizeUrl()) diff --git a/app/src/main/res/drawable/ic_bookmark.xml b/app/src/main/res/drawable/ic_bookmark.xml index 6c8d538..bcd12cf 100644 --- a/app/src/main/res/drawable/ic_bookmark.xml +++ b/app/src/main/res/drawable/ic_bookmark.xml @@ -1,6 +1,6 @@ + + diff --git a/app/src/main/res/layout-land/activity_image.xml b/app/src/main/res/layout-land/activity_image.xml index ea074d5..858451d 100644 --- a/app/src/main/res/layout-land/activity_image.xml +++ b/app/src/main/res/layout-land/activity_image.xml @@ -29,6 +29,18 @@ tools:src="@tools:sample/backgrounds/scenic" /> + + - + app:layout_constraintRight_toRightOf="parent" + app:size="medium" /> diff --git a/app/src/main/res/layout-sw600dp/viewholder_preview_small.xml b/app/src/main/res/layout-sw600dp/viewholder_preview_small.xml index 1a2ba86..e54314c 100644 --- a/app/src/main/res/layout-sw600dp/viewholder_preview_small.xml +++ b/app/src/main/res/layout-sw600dp/viewholder_preview_small.xml @@ -52,10 +52,12 @@ app:layout_constraintTop_toBottomOf="@id/previewTitle" tools:text="1 week ago" /> - + app:layout_constraintRight_toRightOf="parent" + app:size="medium" /> diff --git a/app/src/main/res/layout/activity_article.xml b/app/src/main/res/layout/activity_article.xml index ef8f4eb..c9c65d8 100644 --- a/app/src/main/res/layout/activity_article.xml +++ b/app/src/main/res/layout/activity_article.xml @@ -45,7 +45,8 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" /> - + + - - Date: Tue, 18 Jun 2019 12:38:09 -0400 Subject: [PATCH 10/10] improvement/actionsview moved sharelink function into extension function --- .../common/extensions/ContextExtensions.kt | 22 +++++++++++++++ .../common/ui/actions/ActionsView.kt | 28 ++++--------------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/rusili/superstreet/common/extensions/ContextExtensions.kt b/app/src/main/java/com/rusili/superstreet/common/extensions/ContextExtensions.kt index 471a8d9..e96c301 100644 --- a/app/src/main/java/com/rusili/superstreet/common/extensions/ContextExtensions.kt +++ b/app/src/main/java/com/rusili/superstreet/common/extensions/ContextExtensions.kt @@ -1,9 +1,31 @@ package com.rusili.superstreet.common.extensions import android.content.Context +import android.content.Intent import android.net.ConnectivityManager +import com.rusili.superstreet.jsoup.api.BASE_HTML + +private const val STRING_SHARE_TYPE = "text/plain" +private const val STRING_SHARE_SUBJECT = "Sharing URL" +private const val STRING_SHARE_VIA = "Share via: " fun Context?.isNetworkConnected(): Boolean = this?.let { (it.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo?.isConnected ?: false } ?: false + +fun Context?.shareLink(link: String) { + this?.startActivity( + Intent.createChooser( + Intent(Intent.ACTION_SEND).apply { + setType(STRING_SHARE_TYPE) + putExtra( + Intent.EXTRA_SUBJECT, + STRING_SHARE_SUBJECT + ) + putExtra(Intent.EXTRA_TEXT, BASE_HTML.plus(link)) + }, + STRING_SHARE_VIA + ) + ) +} diff --git a/app/src/main/java/com/rusili/superstreet/common/ui/actions/ActionsView.kt b/app/src/main/java/com/rusili/superstreet/common/ui/actions/ActionsView.kt index 70bb3bf..3d9d676 100644 --- a/app/src/main/java/com/rusili/superstreet/common/ui/actions/ActionsView.kt +++ b/app/src/main/java/com/rusili/superstreet/common/ui/actions/ActionsView.kt @@ -11,13 +11,10 @@ import android.widget.Toast import androidx.core.view.setPadding import com.rusili.superstreet.R import com.rusili.superstreet.common.extensions.getDimen +import com.rusili.superstreet.common.extensions.shareLink import com.rusili.superstreet.common.ui.StyleableFrameLayout import com.rusili.superstreet.jsoup.api.BASE_HTML -private const val STRING_SHARE_TYPE = "text/plain" -private const val STRING_SHARE_SUBJECT = "Sharing URL" -private const val STRING_SHARE_VIA = "Share via: " - class ActionsView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, @@ -31,6 +28,7 @@ class ActionsView @JvmOverloads constructor( override fun getStyleable(): IntArray = R.styleable.ActionsView override fun TypedArray.setupViews() { + actionFavorite = findViewById(R.id.actionFavorite) actionShare = findViewById(R.id.actionShare) allActionViews = listOf(actionFavorite, actionShare) @@ -39,7 +37,9 @@ class ActionsView @JvmOverloads constructor( } fun setShareLink(link: String) { - findViewById(R.id.actionShare).setOnClickListener { shareLink(link) } + findViewById(R.id.actionShare).setOnClickListener { + context.shareLink(link) + } } fun setFavoriteAction() { @@ -89,24 +89,6 @@ class ActionsView @JvmOverloads constructor( } } - private fun shareLink(link: String) { - context.startActivity( - Intent.createChooser( - Intent(Intent.ACTION_SEND).apply { - setType(STRING_SHARE_TYPE) - putExtra(Intent.EXTRA_SUBJECT, - STRING_SHARE_SUBJECT - ) - putExtra(Intent.EXTRA_TEXT, addDomainToLink(link)) - }, - STRING_SHARE_VIA - ) - ) - } - - private fun addDomainToLink(link: String) = - BASE_HTML.plus(link) - private enum class ViewSize(val attr: Int) { SMALL(0), MEDIUM(1),