diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b7aa7c3b..9706a771 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -101,7 +101,6 @@ dependencies { implementation(project(":common-ui")) implementation(project(":navigation")) implementation(project(":theme-manager")) - implementation(project(":photo-list-ui")) implementation(project(":feature:curated-photos")) implementation(project(":feature:photo-details")) implementation(project(":feature:wallpaper")) diff --git a/feature/curated-photos/build.gradle b/feature/curated-photos/build.gradle index a329f25e..65a642bb 100644 --- a/feature/curated-photos/build.gradle +++ b/feature/curated-photos/build.gradle @@ -26,7 +26,6 @@ dependencies { implementation project(':common-ui') implementation project(':compose-ui') implementation project(':navigation') - implementation project(':photo-list-ui') implementation project(':photo-usecase') implementation libs.material diff --git a/feature/favorites/build.gradle b/feature/favorites/build.gradle index bbfe6c8d..23884ab7 100644 --- a/feature/favorites/build.gradle +++ b/feature/favorites/build.gradle @@ -26,7 +26,6 @@ dependencies { implementation project(':compose-ui') implementation project(':photo-usecase') implementation project(':navigation') - implementation project(':photo-list-ui') implementation libs.material implementation libs.androidx.fragment diff --git a/feature/search/build.gradle b/feature/search/build.gradle index 5d9f7e71..69a4582f 100644 --- a/feature/search/build.gradle +++ b/feature/search/build.gradle @@ -26,7 +26,6 @@ dependencies { implementation project(':common-ui') implementation project(':compose-ui') implementation project(':navigation') - implementation project(':photo-list-ui') implementation project(':photo-usecase') implementation project(':feature:recommendations') diff --git a/photo-list-ui/.gitignore b/photo-list-ui/.gitignore deleted file mode 100644 index 42afabfd..00000000 --- a/photo-list-ui/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/photo-list-ui/build.gradle b/photo-list-ui/build.gradle deleted file mode 100644 index d7845abb..00000000 --- a/photo-list-ui/build.gradle +++ /dev/null @@ -1,21 +0,0 @@ -plugins { - alias libs.plugins.android.library - alias libs.plugins.kotlin.android -} - -android { - namespace 'com.github.sikv.photo.list.ui' -} - -dependencies { - implementation project(':domain') - implementation project(':common') - implementation project(':common-ui') - implementation project(':data') - implementation project(':navigation') - - implementation libs.material - implementation libs.androidx.recyclerview - implementation libs.androidx.lifecycle.runtime - implementation libs.androidx.paging.runtime -} diff --git a/photo-list-ui/src/main/AndroidManifest.xml b/photo-list-ui/src/main/AndroidManifest.xml deleted file mode 100644 index 8072ee00..00000000 --- a/photo-list-ui/src/main/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/Extensions.kt b/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/Extensions.kt deleted file mode 100644 index f1e4e013..00000000 --- a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/Extensions.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.github.sikv.photo.list.ui - -import android.content.Context -import android.graphics.Color -import android.view.View -import android.view.animation.Animation -import android.view.animation.ScaleAnimation -import androidx.paging.CombinedLoadStates -import androidx.paging.LoadState -import androidx.recyclerview.widget.GridLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.github.sikv.photos.common.ui.LoadingErrorView -import com.google.android.material.color.MaterialColors - -fun RecyclerView.setItemLayoutType(itemLayoutType: PhotoItemLayoutType) { - layoutManager = GridLayoutManager(context, itemLayoutType.spanCount) - - val verticalPadding = context.resources.getDimension(itemLayoutType.recyclerVerticalPadding).toInt() - setPadding(0, verticalPadding, 0, verticalPadding) - - // Invalidate view holders - adapter = adapter -} - -fun View.favoriteAnimation() { - startAnimation(getScaleAnimation(0F, 1.1F, 0F, 1.1F)) -} - -private fun getScaleAnimation(fromX: Float, toX: Float, fromY: Float, toY: Float, duration: Long = 200): ScaleAnimation { - val scaleAnimation = ScaleAnimation(fromX, toX, fromY, toY, - Animation.RELATIVE_TO_SELF, 0.5F, - Animation.RELATIVE_TO_SELF, 0.5F) - - scaleAnimation.duration = duration - - return scaleAnimation -} - -fun LoadingErrorView.updateLoadState(loadState: CombinedLoadStates) { - visibility = when (loadState.refresh) { - is LoadState.NotLoading -> View.GONE - is LoadState.Loading -> View.GONE - is LoadState.Error -> View.VISIBLE - } -} diff --git a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/OnHoldReleaseListener.kt b/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/OnHoldReleaseListener.kt deleted file mode 100644 index 4bdba709..00000000 --- a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/OnHoldReleaseListener.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.github.sikv.photo.list.ui - -import android.annotation.SuppressLint -import android.os.Handler -import android.os.Looper -import android.os.SystemClock -import android.view.MotionEvent -import android.view.View -import java.util.* - -fun View.setOnHoldReleaseListener(listener: OnHoldReleaseListener?) { - setOnTouchListener(listener) -} - -abstract class OnHoldReleaseListener : View.OnTouchListener { - - companion object { - private const val LONG_HOLD_DELAY = 600L - } - - private var actionDownTime: Long = 0 - - private var longHoldTimer: Timer? = null - - @SuppressLint("ClickableViewAccessibility") - override fun onTouch(view: View?, event: MotionEvent?): Boolean { - when (event?.action) { - MotionEvent.ACTION_DOWN -> { - actionDownTime = SystemClock.elapsedRealtime() - - longHoldTimer = Timer() - - longHoldTimer?.schedule(object : TimerTask() { - override fun run() { - Handler(Looper.getMainLooper()).post { - view?.let(::onHold) - - } - } - }, LONG_HOLD_DELAY) - } - - MotionEvent.ACTION_CANCEL -> { - longHoldTimer?.cancel() - } - - MotionEvent.ACTION_UP -> { - longHoldTimer?.cancel() - - if (SystemClock.elapsedRealtime() - actionDownTime > LONG_HOLD_DELAY) { - view?.let(::onRelease) - } - } - } - - return false - } - - abstract fun onHold(view: View) - abstract fun onRelease(view: View) -} diff --git a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/OnPhotoActionListener.kt b/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/OnPhotoActionListener.kt deleted file mode 100644 index 7c4a6e68..00000000 --- a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/OnPhotoActionListener.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.github.sikv.photo.list.ui - -import android.view.View -import com.github.sikv.photos.domain.Photo - -interface OnPhotoActionListener { - - enum class Action { - CLICK, - HOLD, - RELEASE, - PHOTOGRAPHER, - OPTIONS, - FAVORITE, - SHARE, - DOWNLOAD - } - - fun onPhotoAction(action: Action, photo: Photo, view: View) - fun onPhotoActionParentRelease() -} diff --git a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoActionDispatcher.kt b/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoActionDispatcher.kt deleted file mode 100644 index 96db04ed..00000000 --- a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoActionDispatcher.kt +++ /dev/null @@ -1,151 +0,0 @@ -package com.github.sikv.photo.list.ui - -import android.Manifest -import android.app.Activity -import android.os.Build -import android.view.View -import androidx.navigation.fragment.findNavController -import com.github.sikv.photos.common.DownloadService -import com.github.sikv.photos.common.PermissionManager -import com.github.sikv.photos.common.PhotoLoader -import com.github.sikv.photos.common.ui.BaseFragment -import com.github.sikv.photos.common.ui.OptionsBottomSheetDialog -import com.github.sikv.photos.common.ui.copyText -import com.github.sikv.photos.common.ui.openAppSettings -import com.github.sikv.photos.common.ui.openUrl -import com.github.sikv.photos.data.createShareIntent -import com.github.sikv.photos.domain.Photo -import com.github.sikv.photos.navigation.args.PhotoDetailsFragmentArguments -import com.github.sikv.photos.navigation.args.SetWallpaperFragmentArguments -import com.github.sikv.photos.navigation.route.PhotoDetailsRoute -import com.github.sikv.photos.navigation.route.SetWallpaperRoute -import com.google.android.material.dialog.MaterialAlertDialogBuilder - -@Deprecated("Use photo-usecase module") -class PhotoActionDispatcher( - private val fragment: BaseFragment, - private val downloadService: DownloadService, - private val photoLoader: PhotoLoader, - private val photoDetailsRoute: PhotoDetailsRoute, - private val setWallpaperRoute: SetWallpaperRoute, - private val onToggleFavorite: (Photo) -> Unit, - private val onShowMessage: (String) -> Unit -) : OnPhotoActionListener { - - private val permissionManager = PermissionManager(fragment) - - private lateinit var photoPreviewPopup: PhotoPreviewPopup - - private fun getActivity(): Activity { - return fragment.requireActivity() - } - - override fun onPhotoAction(action: OnPhotoActionListener.Action, photo: Photo, view: View) { - when (action) { - OnPhotoActionListener.Action.CLICK -> { - photoDetailsRoute.present(fragment.findNavController(), PhotoDetailsFragmentArguments(photo)) - } - - OnPhotoActionListener.Action.HOLD -> { - if (!this::photoPreviewPopup.isInitialized) { - photoPreviewPopup = PhotoPreviewPopup(getActivity(), photoLoader) - } - photoPreviewPopup.show(view, photo) - } - - OnPhotoActionListener.Action.RELEASE -> { - photoPreviewPopup.dismiss() - } - - OnPhotoActionListener.Action.PHOTOGRAPHER -> { - photo.getPhotoPhotographerUrl()?.let { photographerUrl -> - getActivity().openUrl(photographerUrl) - } ?: run { - getActivity().openUrl(photo.getPhotoShareUrl()) - } - } - - OnPhotoActionListener.Action.OPTIONS -> { - showOptionsDialog(photo) - } - - OnPhotoActionListener.Action.FAVORITE -> { - onToggleFavorite(photo) - } - - OnPhotoActionListener.Action.SHARE -> { - getActivity().startActivity(photo.createShareIntent()) - } - - OnPhotoActionListener.Action.DOWNLOAD -> { - downloadPhoto(photo) - } - } - } - - private fun downloadPhoto(photo: Photo) { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) { - // No need to request WRITE_EXTERNAL_STORAGE permission on Android 11 and higher - downloadPhotoInternal(photo) - } else { - // Request WRITE_EXTERNAL_STORAGE permission on Android 10 and lower - permissionManager.requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) { granted -> - if (granted) { - downloadPhotoInternal(photo) - } else { - MaterialAlertDialogBuilder(getActivity()) - .setTitle(R.string.storage_permission) - .setMessage(R.string.storage_permission_description) - .setPositiveButton(R.string.open_settings) { _, _ -> - getActivity().openAppSettings() - } - .setNegativeButton(R.string.cancel, null) - .create() - .show() - } - } - } - } - - private fun downloadPhotoInternal(photo: Photo) { - downloadService.downloadPhoto( - photoUrl = photo.getPhotoDownloadUrl(), - notificationTitle = "Photos", // TODO Fix string. - notificationDescription = "Downloading photo" // TODO Fix string. - ) - onShowMessage(getActivity().getString(R.string.downloading_photo)) - } - - - override fun onPhotoActionParentRelease() { - if (this::photoPreviewPopup.isInitialized && photoPreviewPopup.isShown()) { - photoPreviewPopup.dismiss() - } - } - - private fun showOptionsDialog(photo: Photo) { - val options = listOf( - getActivity().getString(R.string.set_wallpaper), - getActivity().getString(R.string.copy_link) - ) - - val dialog = OptionsBottomSheetDialog.newInstance(options, null) { index -> - when (index) { - // Set Wallpaper - 0 -> { - setWallpaperRoute.present(fragment.childFragmentManager, SetWallpaperFragmentArguments(photo)) - } - // Copy Link - 1 -> { - val label = getActivity().getString(R.string.photo_link) - val text = photo.getPhotoShareUrl() - - getActivity().copyText(label, text) - onShowMessage(getActivity().getString(R.string.link_copied)) - } - } - } - - dialog.show(fragment.childFragmentManager) - } -} diff --git a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoDiffUtil.kt b/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoDiffUtil.kt deleted file mode 100644 index 2c103368..00000000 --- a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoDiffUtil.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.sikv.photo.list.ui - -import androidx.recyclerview.widget.DiffUtil -import com.github.sikv.photos.domain.Photo - -class PhotoDiffUtil : DiffUtil.ItemCallback() { - override fun areItemsTheSame(oldItem: T, newItem: T): Boolean = - oldItem.getPhotoId() == newItem.getPhotoId() - - override fun areContentsTheSame(oldItem: T, newItem: T): Boolean = - oldItem == newItem -} diff --git a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoItemLayoutType.kt b/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoItemLayoutType.kt deleted file mode 100644 index 3df344da..00000000 --- a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoItemLayoutType.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.github.sikv.photo.list.ui - -import androidx.annotation.DimenRes -import androidx.annotation.LayoutRes -import com.github.sikv.photos.domain.ListLayout - -enum class PhotoItemLayoutType( - @LayoutRes val layout: Int, - @DimenRes val recyclerVerticalPadding: Int, - val spanCount: Int -) { - FULL( - R.layout.item_photo_full, - R.dimen.photoRecyclerVerticalPadding, - ListLayout.LIST.spanCount - ), - - MIN( - R.layout.item_photo_min, - R.dimen.photoGridRecyclerVerticalPadding, - ListLayout.GRID.spanCount - ); - - companion object { - fun findBySpanCount(spanCount: Int): PhotoItemLayoutType { - return if (spanCount == ListLayout.GRID.spanCount) { - MIN - } else { - FULL - } - } - } -} diff --git a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoItemLoadingView.kt b/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoItemLoadingView.kt deleted file mode 100644 index 4c870452..00000000 --- a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoItemLoadingView.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.github.sikv.photo.list.ui - -import android.animation.ObjectAnimator -import android.content.Context -import android.util.AttributeSet -import android.view.LayoutInflater -import android.view.View -import android.widget.ScrollView -import androidx.paging.CombinedLoadStates -import androidx.paging.LoadState -import com.github.sikv.photos.common.ui.R -import com.github.sikv.photos.common.ui.setVisibilityAnimated - -class PhotoItemLoadingView : ScrollView { - - constructor(context: Context) : super(context) - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - - private var animator = ObjectAnimator.ofFloat(this, View.ALPHA, 0.5f, 1f) - .apply { - repeatMode = ObjectAnimator.REVERSE - repeatCount = ObjectAnimator.INFINITE - duration = 950 - } - - init { - val view = LayoutInflater.from(context) - .inflate(R.layout.item_photo_full_loading, this, false) - - addView(view) - - animator.start() - } - - fun updateLoadState(loadState: CombinedLoadStates) { - when (loadState.refresh) { - is LoadState.NotLoading -> setVisibilityAnimated(View.GONE) - is LoadState.Loading -> setVisibilityAnimated(View.VISIBLE) - is LoadState.Error -> setVisibilityAnimated(View.GONE) - } - } -} diff --git a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoPreviewPopup.kt b/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoPreviewPopup.kt deleted file mode 100644 index 676eac40..00000000 --- a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/PhotoPreviewPopup.kt +++ /dev/null @@ -1,103 +0,0 @@ -package com.github.sikv.photo.list.ui - -import android.annotation.SuppressLint -import android.content.Context -import android.content.res.Resources -import android.graphics.Color -import android.graphics.drawable.ColorDrawable -import android.view.* -import android.view.animation.Animation -import android.view.animation.AnimationUtils -import android.widget.ImageView -import android.widget.PopupWindow -import com.github.sikv.photos.common.PhotoLoader -import com.github.sikv.photos.domain.Photo - -@SuppressLint("InflateParams", "ClickableViewAccessibility") -class PhotoPreviewPopup( - private val context: Context, - private val photoLoader: PhotoLoader -) { - - private var popupWindow: PopupWindow? = null - - private var photoPreviewCard: View? = null - private var photoPreviewImage: ImageView? = null - - init { - val layout = LayoutInflater.from(context) - .inflate(R.layout.popup_photo_preview, null, false) - - popupWindow = PopupWindow( - layout, - calculateWidth(), - ViewGroup.LayoutParams.WRAP_CONTENT, - true - ) - - photoPreviewCard = layout.findViewById(R.id.photoPreviewCard) - photoPreviewImage = layout.findViewById(R.id.photoPreviewImage) - - popupWindow?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) - popupWindow?.isOutsideTouchable = false - - popupWindow?.setTouchInterceptor { _, event -> - if (event.action == MotionEvent.ACTION_DOWN) { - dismiss() - true - } else { - false - } - } - } - - fun show(parent: View, photo: Photo) { - photoLoader.load(photo.getPhotoPreviewUrl()) { bitmap -> - photoPreviewImage?.setImageBitmap(bitmap) - - popupWindow?.showAtLocation(parent, Gravity.CENTER, 0, 0) - dimBackground() - - val animation = AnimationUtils.loadAnimation(context, R.anim.zoom_in) - photoPreviewCard?.startAnimation(animation) - } - } - - fun isShown(): Boolean = popupWindow?.isShowing ?: false - - fun dismiss() { - val dismissAnimation = AnimationUtils.loadAnimation(context, R.anim.zoom_out) - - dismissAnimation?.setAnimationListener(object : Animation.AnimationListener { - override fun onAnimationStart(animation: Animation?) {} - - override fun onAnimationRepeat(animation: Animation?) {} - - override fun onAnimationEnd(animation: Animation?) { - photoPreviewImage?.setImageDrawable(null) - - popupWindow?.dismiss() - } - }) - - photoPreviewCard?.startAnimation(dismissAnimation) - } - - private fun dimBackground() { - popupWindow?.let { popup -> - val rootView = popup.contentView.rootView - - val layoutParams = rootView.layoutParams as WindowManager.LayoutParams - layoutParams.flags = layoutParams.flags or WindowManager.LayoutParams.FLAG_DIM_BEHIND - layoutParams.dimAmount = 0.75F - - val windowManager = - popup.contentView.context.getSystemService(Context.WINDOW_SERVICE) as WindowManager - windowManager.updateViewLayout(rootView, layoutParams) - } - } - - private fun calculateWidth(): Int { - return Resources.getSystem().displayMetrics.widthPixels - 150 - } -} diff --git a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/adapter/PhotoPagingAdapter.kt b/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/adapter/PhotoPagingAdapter.kt deleted file mode 100644 index 8f838e5e..00000000 --- a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/adapter/PhotoPagingAdapter.kt +++ /dev/null @@ -1,59 +0,0 @@ -package com.github.sikv.photo.list.ui.adapter - -import android.annotation.SuppressLint -import android.view.LayoutInflater -import android.view.MotionEvent -import android.view.ViewGroup -import androidx.lifecycle.LifecycleCoroutineScope -import androidx.paging.PagingDataAdapter -import androidx.recyclerview.widget.RecyclerView -import com.github.sikv.photo.list.ui.OnPhotoActionListener -import com.github.sikv.photo.list.ui.PhotoDiffUtil -import com.github.sikv.photo.list.ui.PhotoItemLayoutType -import com.github.sikv.photos.common.PhotoLoader -import com.github.sikv.photos.data.repository.FavoritesRepository -import com.github.sikv.photos.domain.Photo - -// TODO: FavoritesRepository SHOULD NOT be used here. -class PhotoPagingAdapter( - private val photoLoader: PhotoLoader, - private val favoritesRepository: FavoritesRepository, - private val lifecycleScope: LifecycleCoroutineScope, - private val listener: OnPhotoActionListener -) : PagingDataAdapter(PhotoDiffUtil()) { - - private var itemLayoutType = PhotoItemLayoutType.FULL - - @SuppressLint("ClickableViewAccessibility") - override fun onAttachedToRecyclerView(recyclerView: RecyclerView) { - super.onAttachedToRecyclerView(recyclerView) - - recyclerView.setOnTouchListener { _, event -> - if (event.action == MotionEvent.ACTION_UP) { - listener.onPhotoActionParentRelease() - } - - return@setOnTouchListener false - } - } - - fun notifyPhotoChanged(photo: Photo?) { - notifyItemChanged(snapshot().indexOf(photo)) - } - - fun setItemLayoutType(itemLayoutType: PhotoItemLayoutType) { - this.itemLayoutType = itemLayoutType - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PhotoViewHolder { - val view = LayoutInflater.from(parent.context).inflate(itemLayoutType.layout, parent, false) - return PhotoViewHolder(view, photoLoader, lifecycleScope) - } - - override fun onBindViewHolder(holder: PhotoViewHolder, position: Int) { - val photo = getItem(position) - val isFavorite = favoritesRepository.isFavorite(photo) - - holder.bind(itemLayoutType, photo, isFavorite, listener) - } -} diff --git a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/adapter/PhotoViewHolder.kt b/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/adapter/PhotoViewHolder.kt deleted file mode 100644 index b39e07e8..00000000 --- a/photo-list-ui/src/main/java/com/github/sikv/photo/list/ui/adapter/PhotoViewHolder.kt +++ /dev/null @@ -1,158 +0,0 @@ -package com.github.sikv.photo.list.ui.adapter - -import android.view.View -import android.widget.ImageButton -import android.widget.ImageView -import android.widget.TextView -import androidx.lifecycle.LifecycleCoroutineScope -import androidx.recyclerview.widget.RecyclerView -import com.github.sikv.photo.list.ui.* -import com.github.sikv.photos.common.PhotoLoader -import com.github.sikv.photos.common.ui.TextPlaceholder -import com.github.sikv.photos.common.ui.getAttributionPlaceholderBackgroundColor -import com.github.sikv.photos.common.ui.getAttributionPlaceholderTextColor -import com.github.sikv.photos.domain.Photo -import kotlinx.coroutines.launch - -class PhotoViewHolder( - itemView: View, - private val photoLoader: PhotoLoader, - private val lifecycleScope: LifecycleCoroutineScope -) : RecyclerView.ViewHolder(itemView) { - - private val photographerNameText = itemView.findViewById(R.id.photographerNameText) - private val sourceText = itemView.findViewById(R.id.sourceText) - private val favoriteButton = itemView.findViewById(R.id.favoriteButton) - private val photoImage = itemView.findViewById(R.id.photoImage) - private val photographerImage = itemView.findViewById(R.id.photographerImage) - private val photographerLayout = itemView.findViewById(R.id.photographerLayout) - private val optionsButton = itemView.findViewById(R.id.optionsButton) - private val shareButton = itemView.findViewById(R.id.shareButton) - private val downloadButton = itemView.findViewById(R.id.downloadButton) - - fun bind( - itemLayoutType: PhotoItemLayoutType, - photo: Photo?, - isFavorite: Boolean, - listener: OnPhotoActionListener - ) { - if (itemLayoutType == PhotoItemLayoutType.MIN) { - bindMin(photo, listener) - return - } - - loadPhotos(photo, lifecycleScope) - - photographerNameText.text = photo?.getPhotoPhotographerName() - sourceText.text = photo?.getPhotoSource()?.title - - favoriteButton.visibility = View.VISIBLE - favoriteButton.setImageResource( - if (isFavorite) R.drawable.ic_favorite_red_24dp else R.drawable.ic_favorite_border_24dp - ) - - photo?.let { - photoImage.setOnClickListener { view -> - listener.onPhotoAction(OnPhotoActionListener.Action.CLICK, photo, view) - } - - photoImage.setOnHoldReleaseListener(object : OnHoldReleaseListener() { - override fun onHold(view: View) { - listener.onPhotoAction(OnPhotoActionListener.Action.HOLD, photo, view) - } - - override fun onRelease(view: View) { - listener.onPhotoAction(OnPhotoActionListener.Action.RELEASE, photo, view) - } - }) - - photographerImage.setOnClickListener { view -> - listener.onPhotoAction(OnPhotoActionListener.Action.PHOTOGRAPHER, photo, view) - } - - photographerLayout.setOnClickListener { view -> - listener.onPhotoAction(OnPhotoActionListener.Action.PHOTOGRAPHER, photo, view) - } - - optionsButton.setOnClickListener { view -> - listener.onPhotoAction(OnPhotoActionListener.Action.OPTIONS, photo, view) - } - - favoriteButton.setOnClickListener { view -> - listener.onPhotoAction(OnPhotoActionListener.Action.FAVORITE, photo, view) - favoriteButton.favoriteAnimation() - } - - shareButton.setOnClickListener { view -> - listener.onPhotoAction(OnPhotoActionListener.Action.SHARE, photo, view) - } - - downloadButton.setOnClickListener { view -> - listener.onPhotoAction(OnPhotoActionListener.Action.DOWNLOAD, photo, view) - } - - } ?: run { - optionsButton.setOnClickListener(null) - photoImage.setOnClickListener(null) - photoImage.setOnHoldReleaseListener(null) - favoriteButton.setOnClickListener(null) - downloadButton.setOnClickListener(null) - } - } - - private fun bindMin(photo: Photo?, listener: OnPhotoActionListener) { - photoImage.setImageDrawable(null) - - photo?.let { - photoLoader.load(it.getPhotoPreviewUrl(), photoImage) - } - - photo?.let { - photoImage.setOnClickListener { view -> - listener.onPhotoAction(OnPhotoActionListener.Action.CLICK, photo, view) - } - - photoImage.setOnHoldReleaseListener(object : OnHoldReleaseListener() { - override fun onHold(view: View) { - listener.onPhotoAction(OnPhotoActionListener.Action.HOLD, photo, view) - } - - override fun onRelease(view: View) { - listener.onPhotoAction(OnPhotoActionListener.Action.RELEASE, photo, view) - } - }) - - } ?: run { - photoImage.setOnClickListener(null) - photoImage.setOnHoldReleaseListener(null) - } - } - - private fun loadPhotos(photo: Photo?, lifecycleScope: LifecycleCoroutineScope) { - photoImage.setImageDrawable(null) - photographerImage.setImageDrawable(null) - - if (photo == null) { - return - } - - photoLoader.load(photo.getPhotoPreviewUrl(), photoImage) - - val textColor = getAttributionPlaceholderTextColor(itemView.context) - val backgroundColor = getAttributionPlaceholderBackgroundColor(itemView.context) - - lifecycleScope.launch { - val placeholder = TextPlaceholder.with(itemView.context) - .textFirstChar(photo.getPhotoPhotographerName()) - .textColor(textColor) - .background(TextPlaceholder.Shape.CIRCLE, backgroundColor) - .build() - - photoLoader.loadWithCircleCrop( - photo.getPhotoPhotographerImageUrl(), - placeholder, - photographerImage - ) - } - } -} diff --git a/photo-list-ui/src/main/res/anim/zoom_in.xml b/photo-list-ui/src/main/res/anim/zoom_in.xml deleted file mode 100644 index 82fbefeb..00000000 --- a/photo-list-ui/src/main/res/anim/zoom_in.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - diff --git a/photo-list-ui/src/main/res/anim/zoom_out.xml b/photo-list-ui/src/main/res/anim/zoom_out.xml deleted file mode 100644 index 8e3c77a7..00000000 --- a/photo-list-ui/src/main/res/anim/zoom_out.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - diff --git a/photo-list-ui/src/main/res/drawable/ic_favorite_border_24dp.xml b/photo-list-ui/src/main/res/drawable/ic_favorite_border_24dp.xml deleted file mode 100644 index 6030e302..00000000 --- a/photo-list-ui/src/main/res/drawable/ic_favorite_border_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/photo-list-ui/src/main/res/drawable/ic_favorite_red_24dp.xml b/photo-list-ui/src/main/res/drawable/ic_favorite_red_24dp.xml deleted file mode 100644 index b629d667..00000000 --- a/photo-list-ui/src/main/res/drawable/ic_favorite_red_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/photo-list-ui/src/main/res/drawable/ic_file_download_24dp.xml b/photo-list-ui/src/main/res/drawable/ic_file_download_24dp.xml deleted file mode 100644 index 3140c274..00000000 --- a/photo-list-ui/src/main/res/drawable/ic_file_download_24dp.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - diff --git a/photo-list-ui/src/main/res/drawable/ic_more_vert_24dp.xml b/photo-list-ui/src/main/res/drawable/ic_more_vert_24dp.xml deleted file mode 100644 index feaf2470..00000000 --- a/photo-list-ui/src/main/res/drawable/ic_more_vert_24dp.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/photo-list-ui/src/main/res/drawable/ic_share_24dp.xml b/photo-list-ui/src/main/res/drawable/ic_share_24dp.xml deleted file mode 100644 index 021bcb5a..00000000 --- a/photo-list-ui/src/main/res/drawable/ic_share_24dp.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - diff --git a/photo-list-ui/src/main/res/layout/item_photo_full.xml b/photo-list-ui/src/main/res/layout/item_photo_full.xml deleted file mode 100644 index 53abab80..00000000 --- a/photo-list-ui/src/main/res/layout/item_photo_full.xml +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/photo-list-ui/src/main/res/layout/item_photo_min.xml b/photo-list-ui/src/main/res/layout/item_photo_min.xml deleted file mode 100644 index fab3a2cf..00000000 --- a/photo-list-ui/src/main/res/layout/item_photo_min.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - diff --git a/photo-list-ui/src/main/res/layout/popup_photo_preview.xml b/photo-list-ui/src/main/res/layout/popup_photo_preview.xml deleted file mode 100644 index c718210d..00000000 --- a/photo-list-ui/src/main/res/layout/popup_photo_preview.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - diff --git a/photo-list-ui/src/main/res/values/dimens.xml b/photo-list-ui/src/main/res/values/dimens.xml deleted file mode 100644 index 5dd03556..00000000 --- a/photo-list-ui/src/main/res/values/dimens.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - 2.5dp - 16dp - diff --git a/photo-list-ui/src/main/res/values/strings.xml b/photo-list-ui/src/main/res/values/strings.xml deleted file mode 100644 index 1f119ec9..00000000 --- a/photo-list-ui/src/main/res/values/strings.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - Photo preview - Photographer photo - Photo options - Photo - Favorite - Share - Download - - Downloading photo… - Storage permission - Storage permission is required to download photos. - Open Settings - Cancel - Set Wallpaper - Copy Link - Photo link - Link copied - diff --git a/settings.gradle.kts b/settings.gradle.kts index 62060be3..31ce6b87 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -33,7 +33,6 @@ include(":common-ui") include(":feature:recommendations") include(":feature:feedback") include(":feature:curated-photos") -include(":photo-list-ui") include(":feature:wallpaper") include(":feature:photo-details") include(":feature:search")