diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3777bd3..c633619 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + = Build.VERSION_CODES.S) { + val vibratorManager = + context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager + vibratorManager.defaultVibrator + } else { + @Suppress("DEPRECATION") + context.getSystemService(VIBRATOR_SERVICE) as Vibrator + } + + vibrator.vibrate(VibrationEffect.createOneShot(durationMillis, 30)) +} diff --git a/app/src/main/java/com/easyhz/picly/view/album/AlbumAdapter.kt b/app/src/main/java/com/easyhz/picly/view/album/AlbumAdapter.kt index 5058248..d40185f 100644 --- a/app/src/main/java/com/easyhz/picly/view/album/AlbumAdapter.kt +++ b/app/src/main/java/com/easyhz/picly/view/album/AlbumAdapter.kt @@ -1,6 +1,7 @@ package com.easyhz.picly.view.album import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import android.widget.Filter import android.widget.Filterable @@ -13,6 +14,7 @@ import com.easyhz.picly.domain.model.album.AlbumItem class AlbumAdapter( private val noResult: (Boolean , String) -> Unit, private val onClickLinkButton: (AlbumItem) -> Unit, + private val onLongClick: (AlbumItem, View) -> Unit, private val onClickListener: (AlbumItem) -> Unit, ):RecyclerView.Adapter(), Filterable { var originalList: List = listOf() @@ -46,6 +48,13 @@ class AlbumAdapter( albumCardView.setOnClickListener { onClickListener(currentItem) } + albumCardView.setOnLongClickListener { + fade.apply { + visibility = View.VISIBLE + onLongClick(currentItem, this) + } + true + } linkButton.setOnClickListener { onClickLinkButton(currentItem) } diff --git a/app/src/main/java/com/easyhz/picly/view/album/AlbumFragment.kt b/app/src/main/java/com/easyhz/picly/view/album/AlbumFragment.kt index a63f069..740be5d 100644 --- a/app/src/main/java/com/easyhz/picly/view/album/AlbumFragment.kt +++ b/app/src/main/java/com/easyhz/picly/view/album/AlbumFragment.kt @@ -14,9 +14,13 @@ import androidx.recyclerview.widget.GridLayoutManager import com.easyhz.picly.R import com.easyhz.picly.databinding.FragmentAlbumBinding import com.easyhz.picly.domain.model.album.AlbumItem +import com.easyhz.picly.domain.usecase.album.DeleteAlbumUseCase import com.easyhz.picly.util.BlueSnackBar import com.easyhz.picly.util.PICLY +import com.easyhz.picly.util.haptic +import com.easyhz.picly.util.showAlertDialog import com.easyhz.picly.util.toPICLY +import com.easyhz.picly.view.dialog.LoadingDialog import com.easyhz.picly.view.navigation.NavControllerManager import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.CoroutineScope @@ -31,6 +35,7 @@ class AlbumFragment: Fragment() { private lateinit var albumAdapter: AlbumAdapter private lateinit var viewModel: AlbumViewModel private lateinit var clipboardManager: ClipboardManager + private lateinit var loading: LoadingDialog override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -39,6 +44,8 @@ class AlbumFragment: Fragment() { binding = FragmentAlbumBinding.inflate(layoutInflater) viewModel = ViewModelProvider(requireActivity())[AlbumViewModel::class.java] clipboardManager = requireActivity().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + loading = LoadingDialog(requireActivity()) + return binding.root } @@ -64,7 +71,8 @@ class AlbumFragment: Fragment() { private fun setRecyclerView() { albumAdapter = AlbumAdapter( noResult = { isEmpty, s -> setNoResult(isEmpty, s) }, - onClickLinkButton = { onClickLinkButton(it) } + onClickLinkButton = { onClickLinkButton(it) }, + onLongClick = { albumItem, view -> onLongClick(albumItem, view) } ) { NavControllerManager.navigateMainToDetail(it) } @@ -105,6 +113,28 @@ class AlbumFragment: Fragment() { clipboardManager.setPrimaryClip(clipData) BlueSnackBar.make(binding.root, getString(R.string.link_copy)).show() } + + private fun onLongClick(albumItem: AlbumItem, view: View) { + CoroutineScope(Dispatchers.Main).launch { + haptic(requireContext(), 50) + delay(500) + showAlertDialog( + context = requireContext(), + title= R.string.dialog_delete_title, + message = R.string.dialog_delete_message, + positiveButtonText = R.string.delete, + onContinue = { + loading.show(true) + deleteAlbum(albumItem.documentId) + }, + negativeButtonText = R.string.cancel, + onCancel = { }, + style = R.style.DialogDeleteTheme + ) + view.visibility = View.GONE + } + } + private fun setNoResult(isEmpty: Boolean, s: String) { if (s.isEmpty() && albumAdapter.originalList.isEmpty()) updateNoResultMessage(true, getString(R.string.no_data_text)) else updateNoResultMessage(isEmpty, getString(R.string.no_search_text)) @@ -131,4 +161,18 @@ class AlbumFragment: Fragment() { viewModel.setSwipe(true) } } + + private fun deleteAlbum(id: String) { + CoroutineScope(Dispatchers.Main).launch { + when(val result = viewModel.deleteAlbum(id)) { + is DeleteAlbumUseCase.DeleteAlbumResult.Success -> { viewModel.fetchAlbums() } + is DeleteAlbumUseCase.DeleteAlbumResult.Error -> onFailure(result.errorMessage) + } + loading.show(false) + } + } + + private fun onFailure(message: String) { + BlueSnackBar.make(binding.root, message).show() + } } \ No newline at end of file diff --git a/app/src/main/java/com/easyhz/picly/view/album/AlbumViewModel.kt b/app/src/main/java/com/easyhz/picly/view/album/AlbumViewModel.kt index af102fd..8a87c29 100644 --- a/app/src/main/java/com/easyhz/picly/view/album/AlbumViewModel.kt +++ b/app/src/main/java/com/easyhz/picly/view/album/AlbumViewModel.kt @@ -7,6 +7,7 @@ import androidx.lifecycle.viewModelScope import com.easyhz.picly.data.mapper.toAlbumItem import com.easyhz.picly.domain.model.album.AlbumItem import com.easyhz.picly.domain.usecase.album.AlbumUseCase +import com.easyhz.picly.domain.usecase.album.DeleteAlbumUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.distinctUntilChanged @@ -17,6 +18,7 @@ import javax.inject.Inject class AlbumViewModel @Inject constructor( private val albumUseCase: AlbumUseCase, + private val deleteAlbumUseCase: DeleteAlbumUseCase ):ViewModel() { private val albumsLiveData = MutableLiveData>() val albums : LiveData> @@ -36,6 +38,8 @@ class AlbumViewModel } } + suspend fun deleteAlbum(id: String): DeleteAlbumUseCase.DeleteAlbumResult = deleteAlbumUseCase(id) + fun setSearchText(value: String) { _searchText.value = value } diff --git a/app/src/main/res/drawable/ripple_card_view.xml b/app/src/main/res/drawable/ripple_card_view.xml new file mode 100644 index 0000000..d674fb3 --- /dev/null +++ b/app/src/main/res/drawable/ripple_card_view.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_album.xml b/app/src/main/res/layout/item_album.xml index 9b0ac7d..1e4ad25 100644 --- a/app/src/main/res/layout/item_album.xml +++ b/app/src/main/res/layout/item_album.xml @@ -122,5 +122,12 @@ /> + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index ae66cc2..546a079 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -9,6 +9,7 @@ #FF2C2C35 #FF383843 #B3383843 + #4D383843 #FF62626D #FF83B4F9 #FF1C1C1E