From 8b97c4201d622c11710331cf783ae6a2ed9e7165 Mon Sep 17 00:00:00 2001 From: Emre Esen Date: Sun, 24 Nov 2024 13:54:05 +0300 Subject: [PATCH 1/5] [FIX][lint fix] --- app/build.gradle.kts | 4 +- app/dependencies.gradle | 7 +- .../java/com/snstudio/hyper/MainActivity.kt | 241 +++++++++++------- .../snstudio/hyper/core/base/BaseDialog.kt | 2 +- .../snstudio/hyper/core/base/BaseViewModel.kt | 13 +- .../hyper/core/extension/Collection.kt | 1 + .../hyper/core/extension/ImageView.kt | 17 +- .../snstudio/hyper/core/extension/String.kt | 42 +++ .../com/snstudio/hyper/core/extension/View.kt | 40 ++- .../snstudio/hyper/data/MediaItemBuilder.kt | 40 ++- .../com/snstudio/hyper/data/model/Media.kt | 1 + .../hyper/feature/home/HighlightsAdapter.kt | 76 ++++++ .../hyper/feature/home/HomeFragment.kt | 158 +++++++++++- .../hyper/feature/home/HomeViewModel.kt | 49 +++- .../feature/home/LastDownloadsAdapter.kt | 115 +++++++++ .../hyper/feature/library/LibraryFragment.kt | 65 +++-- .../hyper/feature/library/LibraryViewModel.kt | 9 - .../hyper/feature/playlist/PlaylistAdapter.kt | 30 ++- .../playlist/PlaylistDetailFragment.kt | 103 +++++--- .../feature/playlist/PlaylistFragment.kt | 62 +++-- .../feature/playlist/PlaylistViewModel.kt | 11 +- .../hyper/feature/search/SearchFragment.kt | 160 ++++++------ .../hyper/feature/search/SearchViewModel.kt | 9 - .../com/snstudio/hyper/service/DownloadJob.kt | 2 +- .../hyper/service/JobCompletedCallback.kt | 6 +- .../snstudio/hyper/shared/MediaItemAdapter.kt | 35 ++- .../snstudio/hyper/shared/MediaViewModel.kt | 67 +++-- .../snstudio/hyper/shared/ProgressLiveData.kt | 7 +- .../com/snstudio/hyper/util/InfoDialog.kt | 11 +- .../hyper/util/ItemTouchHelperCallback.kt | 99 +------ .../com/snstudio/hyper/util/MediaItemType.kt | 2 +- .../java/com/snstudio/hyper/util/Metods.kt | 2 + .../hyper/util/SharedPreferenceManager.kt | 2 - .../com/snstudio/hyper/util/SwipeAction.kt | 6 - app/src/main/res/anim/fade_in.xml | 5 + app/src/main/res/anim/fade_out.xml | 5 + app/src/main/res/anim/slide_in_left.xml | 7 + app/src/main/res/anim/slide_in_right.xml | 7 + app/src/main/res/anim/slide_out_left.xml | 7 + app/src/main/res/anim/slide_out_right.xml | 7 + .../res/color/play_list_button_selector.xml | 5 + app/src/main/res/drawable/bg_add_music.xml | 4 + ...alog_rounded.xml => bg_dialog_rounded.xml} | 0 .../main/res/drawable/bg_playlist_name.xml | 6 + .../{rounded_bg.xml => bg_rounded.xml} | 0 ...nfo_background.xml => bg_rounded_info.xml} | 2 +- .../main/res/drawable/circular_progress.xml | 34 +++ app/src/main/res/drawable/delete_info.gif | Bin 74102 -> 0 bytes app/src/main/res/drawable/download_info.gif | Bin 115492 -> 0 bytes app/src/main/res/drawable/ic_fast_forward.xml | 10 + app/src/main/res/drawable/ic_fast_rewind.xml | 10 + app/src/main/res/drawable/ic_info.xml | 2 +- app/src/main/res/drawable/ic_more.xml | 10 + app/src/main/res/drawable/ic_music_square.xml | 12 - app/src/main/res/drawable/ic_pause.xml | 10 + .../main/res/drawable/ic_placeholder_new.xml | 13 + app/src/main/res/drawable/ic_play.xml | 5 +- app/src/main/res/drawable/ic_play_circle.xml | 10 + app/src/main/res/drawable/ic_play_small.xml | 9 + app/src/main/res/drawable/ic_remove.xml | 10 + app/src/main/res/drawable/ic_shuffle.xml | 10 + app/src/main/res/drawable/ic_skip_next.xml | 10 + app/src/main/res/drawable/ic_skip_prev.xml | 10 + .../player_button_background_ripple.xml | 6 + app/src/main/res/layout/activity_main.xml | 103 ++++---- .../res/layout/custom_player_control_view.xml | 70 +++++ .../custom_player_full_control_view.xml | 150 +++++++++++ app/src/main/res/layout/dialog_info.xml | 43 +++- .../main/res/layout/dialog_music_picker.xml | 2 +- app/src/main/res/layout/fragment_home.xml | 70 ++--- .../res/layout/fragment_playlist_detail.xml | 132 ++++++---- app/src/main/res/layout/item_add_music.xml | 38 +++ app/src/main/res/layout/item_highlights.xml | 48 ++++ app/src/main/res/layout/item_media.xml | 14 +- app/src/main/res/layout/item_media_search.xml | 14 +- app/src/main/res/layout/item_play_list.xml | 25 +- app/src/main/res/layout/layout_music_card.xml | 4 +- .../main/res/layout/layout_play_list_card.xml | 4 +- app/src/main/res/menu/bottom_bar_menu.xml | 19 ++ app/src/main/res/menu/library_menu.xml | 11 + .../main/res/menu/playlist_detail_menu.xml | 7 + app/src/main/res/menu/playlist_menu.xml | 7 + app/src/main/res/menu/search_menu.xml | 11 + app/src/main/res/navigation/navigation.xml | 18 +- app/src/main/res/values-tr/string.xml | 13 +- app/src/main/res/values/colors.xml | 16 +- app/src/main/res/values/strings.xml | 14 +- app/src/main/res/values/styles.xml | 10 + app/src/main/res/values/themes.xml | 2 +- explode/lib/explode.dart | 19 ++ explode/lib/main.dart | 4 + gradle/libs.versions.toml | 6 +- 92 files changed, 1948 insertions(+), 646 deletions(-) create mode 100644 app/src/main/java/com/snstudio/hyper/feature/home/HighlightsAdapter.kt create mode 100644 app/src/main/java/com/snstudio/hyper/feature/home/LastDownloadsAdapter.kt delete mode 100644 app/src/main/java/com/snstudio/hyper/util/SwipeAction.kt create mode 100644 app/src/main/res/anim/fade_in.xml create mode 100644 app/src/main/res/anim/fade_out.xml create mode 100644 app/src/main/res/anim/slide_in_left.xml create mode 100644 app/src/main/res/anim/slide_in_right.xml create mode 100644 app/src/main/res/anim/slide_out_left.xml create mode 100644 app/src/main/res/anim/slide_out_right.xml create mode 100644 app/src/main/res/color/play_list_button_selector.xml create mode 100644 app/src/main/res/drawable/bg_add_music.xml rename app/src/main/res/drawable/{dialog_rounded.xml => bg_dialog_rounded.xml} (100%) create mode 100644 app/src/main/res/drawable/bg_playlist_name.xml rename app/src/main/res/drawable/{rounded_bg.xml => bg_rounded.xml} (100%) rename app/src/main/res/drawable/{rounded_info_background.xml => bg_rounded_info.xml} (81%) create mode 100644 app/src/main/res/drawable/circular_progress.xml delete mode 100644 app/src/main/res/drawable/delete_info.gif delete mode 100644 app/src/main/res/drawable/download_info.gif create mode 100644 app/src/main/res/drawable/ic_fast_forward.xml create mode 100644 app/src/main/res/drawable/ic_fast_rewind.xml create mode 100644 app/src/main/res/drawable/ic_more.xml delete mode 100644 app/src/main/res/drawable/ic_music_square.xml create mode 100644 app/src/main/res/drawable/ic_pause.xml create mode 100644 app/src/main/res/drawable/ic_placeholder_new.xml create mode 100644 app/src/main/res/drawable/ic_play_circle.xml create mode 100644 app/src/main/res/drawable/ic_play_small.xml create mode 100644 app/src/main/res/drawable/ic_remove.xml create mode 100644 app/src/main/res/drawable/ic_shuffle.xml create mode 100644 app/src/main/res/drawable/ic_skip_next.xml create mode 100644 app/src/main/res/drawable/ic_skip_prev.xml create mode 100644 app/src/main/res/drawable/player_button_background_ripple.xml create mode 100644 app/src/main/res/layout/custom_player_control_view.xml create mode 100644 app/src/main/res/layout/custom_player_full_control_view.xml create mode 100644 app/src/main/res/layout/item_add_music.xml create mode 100644 app/src/main/res/layout/item_highlights.xml create mode 100644 app/src/main/res/menu/bottom_bar_menu.xml create mode 100644 app/src/main/res/menu/library_menu.xml create mode 100644 app/src/main/res/menu/playlist_detail_menu.xml create mode 100644 app/src/main/res/menu/playlist_menu.xml create mode 100644 app/src/main/res/menu/search_menu.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3849174..d6f5ad0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -19,8 +19,8 @@ android { applicationId = "com.snstudio.hyper" minSdk = 26 targetSdk = 34 - versionCode = 4 - versionName = "1.0.0-Beta3" + versionCode = 5 + versionName = "1.0.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/dependencies.gradle b/app/dependencies.gradle index f612660..2f919f6 100644 --- a/app/dependencies.gradle +++ b/app/dependencies.gradle @@ -34,7 +34,9 @@ dependencies { // Progress implementation(libs.nested.progress) - implementation(libs.snackprogressbar) + + // BottomBar + implementation(libs.smoothbottombar) // Expo-Media implementation(libs.media3.exoplayer.player) @@ -54,6 +56,9 @@ dependencies { // Toast implementation(libs.toasty) + // Skeleton + implementation libs.skeletonlayout + // Firebase implementation(platform(libs.firebase.bom)) implementation(libs.firebase.analytics) diff --git a/app/src/main/java/com/snstudio/hyper/MainActivity.kt b/app/src/main/java/com/snstudio/hyper/MainActivity.kt index fa922cb..d5c26d6 100644 --- a/app/src/main/java/com/snstudio/hyper/MainActivity.kt +++ b/app/src/main/java/com/snstudio/hyper/MainActivity.kt @@ -1,26 +1,30 @@ package com.snstudio.hyper -import android.animation.ValueAnimator import android.os.Bundle import android.view.View -import android.view.ViewGroup -import android.widget.FrameLayout +import android.view.ViewPropertyAnimator +import android.widget.PopupMenu +import android.widget.ProgressBar import androidx.activity.viewModels import androidx.annotation.OptIn import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.AppCompatImageView +import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen -import androidx.core.view.isVisible import androidx.media3.common.util.UnstableApi +import androidx.navigation.NavController +import androidx.navigation.findNavController +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.textview.MaterialTextView import com.snstudio.hyper.core.extension.click import com.snstudio.hyper.core.extension.gone +import com.snstudio.hyper.core.extension.loadArtwork import com.snstudio.hyper.core.extension.observe -import com.snstudio.hyper.core.extension.startColorAnimation +import com.snstudio.hyper.core.extension.slideDownToggle +import com.snstudio.hyper.core.extension.slideInUp +import com.snstudio.hyper.core.extension.slideOutDown import com.snstudio.hyper.databinding.ActivityMainBinding import com.snstudio.hyper.shared.MediaViewModel -import com.snstudio.hyper.shared.ProgressLiveData -import com.tingyik90.snackprogressbar.SnackProgressBar -import com.tingyik90.snackprogressbar.SnackProgressBarLayout -import com.tingyik90.snackprogressbar.SnackProgressBarManager import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint @@ -31,42 +35,100 @@ class MainActivity : AppCompatActivity() { ActivityMainBinding.inflate(layoutInflater) } - private var animator: ValueAnimator? = null - private var snackParentView: View? = null - - private val snackProgressBarManager by lazy { - SnackProgressBarManager( - binding.root, - lifecycleOwner = this, - ).apply { - setBackgroundColor(R.color.main_color) - setProgressBarColor(R.color.text_color) - setProgressTextColor(R.color.text_color) - setViewToMove(binding.playerView) - useRoundedCornerBackground(true) - setMessageMaxLines(1) - } - } - - private val progressSnackBar by lazy { - SnackProgressBar(SnackProgressBar.TYPE_CIRCULAR, getString(R.string.downloading)) - .setIsIndeterminate(false) - .setProgressMax(100) - .setAllowUserInput(true) - .setShowProgressPercentage(true) - } + private lateinit var navController: NavController + private lateinit var bottomSheetBehavior: BottomSheetBehavior + private var currentAnimation: ViewPropertyAnimator? = null override fun onCreate(savedInstanceState: Bundle?) { installSplashScreen() super.onCreate(savedInstanceState) setContentView(binding.root) - viewModel.createMusicFolder() + createMusicFolder() + initNavController() + setupSmoothBottomMenu() + initNavDestinationListener() observeData() initPlayerMenuButtonsListener() - initSnackDisplayListener() + setupBottomSheet() + } + + override fun onDestroy() { + super.onDestroy() + mediaViewModel.releasePLayer() + } + + private fun createMusicFolder() { + viewModel.createMusicFolder() + } + + private fun setupBottomSheet() { + bottomSheetBehavior = + BottomSheetBehavior.from(binding.playerBottomSheet) + + bottomSheetBehavior.apply { + isHideable = false + peekHeight = 0 + state = BottomSheetBehavior.STATE_COLLAPSED + } + + bottomSheetBehavior.addBottomSheetCallback( + object : + BottomSheetBehavior.BottomSheetCallback() { + @OptIn(UnstableApi::class) + override fun onStateChanged( + bottomSheet: View, + newState: Int, + ) { + currentAnimation?.cancel() + if (newState == BottomSheetBehavior.STATE_EXPANDED) { + currentAnimation = binding.miniPlayerView.slideOutDown() + } else if (newState == BottomSheetBehavior.STATE_COLLAPSED) { + window.navigationBarColor = getColor(R.color.secondary_background_color) + currentAnimation = binding.miniPlayerView.slideInUp() + } + } + + override fun onSlide( + bottomSheet: View, + slideOffset: Float, + ) { + binding.miniPlayerView.alpha = 1 - slideOffset + } + }, + ) + } + + @Deprecated("Deprecated in Java") // Todo + override fun onBackPressed() { + if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) { + bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED + } else { + super.onBackPressed() + } + } + + private fun expandBottomSheet() { with(binding) { - vm = mediaViewModel - lifecycleOwner = this@MainActivity + playerBottomSheet.apply { + visibility = View.VISIBLE + alpha = 0f + } + + playerBottomSheet.animate() + .alpha(1f) + .setDuration(200) + .withStartAction { + bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED + }.start() + + miniPlayerView.animate() + .translationY(-miniPlayerView.height.toFloat()) + .alpha(0f) + .setDuration(200) + .withEndAction { + miniPlayerView.translationY = 0f + miniPlayerView.alpha = 1f + }.start() } } @@ -74,78 +136,69 @@ class MainActivity : AppCompatActivity() { private fun observeData() { with(mediaViewModel) { observe(playerLiveData) { player -> - binding.playerView.player = player - } - observe(playbackStateLiveData) { - // binding.playerMenu.visible() - // moveSnack(380) - } - observe(showPlayerMenuLiveData) { - binding.playerMenu.isVisible = it - moveSnack(380) - } - observe(playerWhenReadyLiveData) { ready -> - if (ready) { - animator = binding.playerMenu.startColorAnimation() + with(binding) { + miniPlayerView.player = player + fullPlayerView.player = player } } - observe(ProgressLiveData.mediaDownloadStateLiveData) { state -> - when (state) { - is ProgressLiveData.DownloadState.Started -> { - snackProgressBarManager.show( - progressSnackBar, - SnackProgressBarManager.LENGTH_INDEFINITE, - ) - progressSnackBar.setMessage(state.message) - snackProgressBarManager.updateTo(progressSnackBar) - } - is ProgressLiveData.DownloadState.InProgress -> { - snackProgressBarManager.setProgress(state.progress) + observe(progressLiveData) { value -> + binding.miniPlayerView.findViewById(R.id.progressCircular).apply { + progress = value + } + } + observe(metaDataLiveData) { metadata -> + with(binding) { + miniPlayerView.apply { + slideDownToggle(true) + findViewById(R.id.image).loadArtwork(metadata) + findViewById(R.id.title).apply { + text = metadata.title + isSelected = true + } } - - is ProgressLiveData.DownloadState.Completed -> { - snackProgressBarManager.dismiss() + fullPlayerView.apply { + findViewById(R.id.title).apply { + text = metadata.title + isSelected = true + } + findViewById(R.id.image).loadArtwork(metadata) } - - is ProgressLiveData.DownloadState.Failed -> {} } } + observe(showPlayerMenuLiveData) { visibility -> + if (visibility) binding.miniPlayerView.show() else binding.miniPlayerView.gone() + } } } - private fun initSnackDisplayListener() { - snackProgressBarManager.setOnDisplayListener( - object : - SnackProgressBarManager.OnDisplayListener { - override fun onLayoutInflated( - snackProgressBarLayout: SnackProgressBarLayout, - overlayLayout: FrameLayout, - snackProgressBar: SnackProgressBar, - onDisplayId: Int, - ) { - snackParentView = snackProgressBarLayout.parent as View - if (binding.playerMenu.isVisible) { - moveSnack(380) - } - } - }, - ) + private fun initNavController() { + navController = findNavController(R.id.baseNavHost) } - private fun moveSnack(bottom: Int) { - val params = snackParentView?.layoutParams as? ViewGroup.MarginLayoutParams - params?.setMargins(0, 0, 0, bottom) - snackParentView?.layoutParams = params + private fun setupSmoothBottomMenu() { + val popupMenu = PopupMenu(this, null) + popupMenu.inflate(R.menu.bottom_bar_menu) + val menu = popupMenu.menu + binding.bottomBar.setupWithNavController(menu, navController) } - private fun initPlayerMenuButtonsListener() { - with(binding) { - btnClose.click { - mediaViewModel.stopPlayer() - playerMenu.gone() - moveSnack(50) + private fun initNavDestinationListener() { + navController.addOnDestinationChangedListener { _, destination, _ -> + when (destination.id) { + R.id.searchFragment, R.id.playlistDetail -> { + binding.bottomBar.slideDownToggle(false) + } + + else -> binding.bottomBar.slideDownToggle(true) } } } + + private fun initPlayerMenuButtonsListener() { + binding.miniPlayerView.click { + window.navigationBarColor = getColor(R.color.background_color) + expandBottomSheet() + } + } } diff --git a/app/src/main/java/com/snstudio/hyper/core/base/BaseDialog.kt b/app/src/main/java/com/snstudio/hyper/core/base/BaseDialog.kt index 74a52ea..dbe3f8e 100644 --- a/app/src/main/java/com/snstudio/hyper/core/base/BaseDialog.kt +++ b/app/src/main/java/com/snstudio/hyper/core/base/BaseDialog.kt @@ -44,7 +44,7 @@ abstract class BaseDialog : DialogFragment() { binding = getViewBinding() isCancelable = setCancelable setStyle(STYLE_NO_TITLE, R.style.DialogTheme_transparent) - dialog?.window?.setBackgroundDrawableResource(R.drawable.dialog_rounded) + dialog?.window?.setBackgroundDrawableResource(R.drawable.bg_dialog_rounded) } override fun onCreateView( diff --git a/app/src/main/java/com/snstudio/hyper/core/base/BaseViewModel.kt b/app/src/main/java/com/snstudio/hyper/core/base/BaseViewModel.kt index d3a906e..e5859c0 100644 --- a/app/src/main/java/com/snstudio/hyper/core/base/BaseViewModel.kt +++ b/app/src/main/java/com/snstudio/hyper/core/base/BaseViewModel.kt @@ -1,18 +1,23 @@ package com.snstudio.hyper.core.base -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.launch open class BaseViewModel(private val methodChannel: MethodChannel) : ViewModel() { - private val _receivedData: MutableLiveData = MutableLiveData() - val receivedData: MutableLiveData = _receivedData + private val _receivedData = MutableSharedFlow() + val receivedData = _receivedData.asSharedFlow() fun receivedData(vararg methodNames: String) { methodChannel.setMethodCallHandler { call, result -> if (methodNames.contains(call.method)) { - _receivedData.value = call + viewModelScope.launch { + _receivedData.emit(call) + } result.success(null) } else { result.notImplemented() diff --git a/app/src/main/java/com/snstudio/hyper/core/extension/Collection.kt b/app/src/main/java/com/snstudio/hyper/core/extension/Collection.kt index a28eb37..2a98162 100644 --- a/app/src/main/java/com/snstudio/hyper/core/extension/Collection.kt +++ b/app/src/main/java/com/snstudio/hyper/core/extension/Collection.kt @@ -43,6 +43,7 @@ fun List>.toMediaList(type: MediaItemType): MutableList< url = hashMap["url"] ?: "", duration = hashMap["duration"]?.toLongOrNull() ?: 0L, thumbnail = hashMap["thumbnail"] ?: "", + thumbnailMax = hashMap["thumbnailMax"] ?: "", publishYear = hashMap["publishYear"], uploadYear = hashMap["uploadYear"], viewCount = hashMap["viewCount"] ?: "", diff --git a/app/src/main/java/com/snstudio/hyper/core/extension/ImageView.kt b/app/src/main/java/com/snstudio/hyper/core/extension/ImageView.kt index 8dff8b5..5d1e705 100644 --- a/app/src/main/java/com/snstudio/hyper/core/extension/ImageView.kt +++ b/app/src/main/java/com/snstudio/hyper/core/extension/ImageView.kt @@ -3,8 +3,11 @@ package com.snstudio.hyper.core.extension import android.graphics.Bitmap import android.widget.ImageView import androidx.databinding.BindingAdapter +import androidx.media3.common.MediaMetadata import com.bumptech.glide.Glide import com.bumptech.glide.load.engine.DiskCacheStrategy +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners import com.snstudio.hyper.R @BindingAdapter("load") @@ -12,12 +15,19 @@ fun ImageView.loadWithGlide(path: Any) { Glide.with(context) .load(path) .centerCrop() - // .fitCenter() .placeholder(R.drawable.layer_placeholder) .error(R.drawable.layer_placeholder) // change err .diskCacheStrategy(DiskCacheStrategy.RESOURCE).into(this) } +fun ImageView.loadWithGlideWithRadius(path: Any) { + Glide.with(context) + .load(path) + .transform(CenterCrop(), RoundedCorners(12)) + .placeholder(R.drawable.ic_placeholder_new) + .error(R.drawable.ic_placeholder_new).into(this) +} + @BindingAdapter("loadBitmap") fun ImageView.loadBitmapWithGlide(path: Bitmap) { Glide.with(context) @@ -35,3 +45,8 @@ fun ImageView.loadGif(image: Int) { .load(image) .into(this) } + +fun ImageView.loadArtwork(data: MediaMetadata) { + data.artworkUri?.let { loadWithGlide(it) } + ?: data.artworkData?.let { loadWithGlide(it) } +} diff --git a/app/src/main/java/com/snstudio/hyper/core/extension/String.kt b/app/src/main/java/com/snstudio/hyper/core/extension/String.kt index 2647e87..de7dc72 100644 --- a/app/src/main/java/com/snstudio/hyper/core/extension/String.kt +++ b/app/src/main/java/com/snstudio/hyper/core/extension/String.kt @@ -4,7 +4,11 @@ import android.content.Context import android.graphics.Bitmap import android.graphics.drawable.Drawable import com.bumptech.glide.Glide +import com.bumptech.glide.load.DataSource +import com.bumptech.glide.load.engine.GlideException +import com.bumptech.glide.request.RequestListener import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.transition.Transition import org.json.JSONException import org.json.JSONObject @@ -46,3 +50,41 @@ fun String?.parseObject(name: String): String? { null } } + +fun String?.isValidImageUrl( + context: Context, + onResult: (Boolean) -> Unit, +) { + if (this == null) { + onResult(false) + return + } + + Glide.with(context) + .load(this) + .listener( + object : RequestListener { + override fun onLoadFailed( + e: GlideException?, + model: Any?, + target: Target, + isFirstResource: Boolean, + ): Boolean { + onResult(false) + return false + } + + override fun onResourceReady( + resource: Drawable, + model: Any, + target: Target?, + dataSource: DataSource, + isFirstResource: Boolean, + ): Boolean { + onResult(true) + return false + } + }, + ) + .preload() +} diff --git a/app/src/main/java/com/snstudio/hyper/core/extension/View.kt b/app/src/main/java/com/snstudio/hyper/core/extension/View.kt index 1023164..e66d316 100644 --- a/app/src/main/java/com/snstudio/hyper/core/extension/View.kt +++ b/app/src/main/java/com/snstudio/hyper/core/extension/View.kt @@ -2,7 +2,12 @@ package com.snstudio.hyper.core.extension import android.animation.ValueAnimator import android.view.View +import android.view.ViewPropertyAnimator +import android.view.animation.AccelerateInterpolator +import android.view.animation.DecelerateInterpolator import androidx.core.content.ContextCompat +import androidx.core.view.isVisible +import androidx.interpolator.view.animation.FastOutSlowInInterpolator import com.snstudio.hyper.R import com.snstudio.hyper.util.SafeClickListener @@ -14,11 +19,44 @@ fun View.gone() { this.visibility = View.GONE } +fun View.slideDownToggle( + show: Boolean, + duration: Long = 300, +) { + if (show) { + if (isVisible) return + visibility = View.VISIBLE + alpha = 0f + translationY = height.toFloat() + } + + animate().translationY(if (show) 0f else height.toFloat()) + .alpha(if (show) 1f else 0f) + .setInterpolator(if (show) DecelerateInterpolator() else AccelerateInterpolator()) + .setDuration(duration) + .withEndAction { + if (!show) { + visibility = View.GONE + translationY = 0f + } + }.start() +} + +fun View.slideOutDown(): ViewPropertyAnimator { + return animate().translationY(height.toFloat()).alpha(0F).setDuration(300) + .setInterpolator(FastOutSlowInInterpolator()) +} + +fun View.slideInUp(): ViewPropertyAnimator { + return animate().translationY(0f).alpha(1f).setDuration(300) + .setInterpolator(FastOutSlowInInterpolator()) +} + fun View.startColorAnimation(): ValueAnimator { val colors = intArrayOf( resources.getColor(R.color.main_color, null), - resources.getColor(R.color.main_color_mid, null), + resources.getColor(R.color.old_main_color_mid, null), resources.getColor(R.color.purple_700, null), resources.getColor(R.color.purple_500, null), ) diff --git a/app/src/main/java/com/snstudio/hyper/data/MediaItemBuilder.kt b/app/src/main/java/com/snstudio/hyper/data/MediaItemBuilder.kt index 83cd4b1..6f35e8a 100644 --- a/app/src/main/java/com/snstudio/hyper/data/MediaItemBuilder.kt +++ b/app/src/main/java/com/snstudio/hyper/data/MediaItemBuilder.kt @@ -1,11 +1,16 @@ package com.snstudio.hyper.data +import android.graphics.Bitmap +import android.net.Uri import androidx.media3.common.MediaItem import androidx.media3.common.MediaMetadata +import java.io.ByteArrayOutputStream class MediaItemBuilder { private var mediaId: String? = null private var mediaTitle: String? = null + private var artworkUri: Uri? = null + private var artworkBitmap: Bitmap? = null fun setMediaId(mediaId: String): MediaItemBuilder { this.mediaId = mediaId @@ -17,13 +22,42 @@ class MediaItemBuilder { return this } + fun setArtWorkUrl(url: String): MediaItemBuilder { + this.artworkUri = Uri.parse(url) + this.artworkBitmap = null + return this + } + + fun setArtWorkBitmap(bitmap: Bitmap?): MediaItemBuilder { + this.artworkBitmap = bitmap + this.artworkUri = null + return this + } + fun build(): MediaItem { val id = requireNotNull(mediaId) { "Media ID must be set" } - val title = requireNotNull(mediaTitle) { "Media title ID must be set" } - val metaData = MediaMetadata.Builder().setTitle(title).build() + val title = requireNotNull(mediaTitle) { "Media title must be set" } + + val metadataBuilder = + MediaMetadata.Builder() + .setTitle(title) + + artworkUri?.let { uri -> + metadataBuilder.setArtworkUri(uri) + } + + artworkBitmap?.let { bitmap -> + val stream = ByteArrayOutputStream() + bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream) + metadataBuilder.setArtworkData( + stream.toByteArray(), + MediaMetadata.PICTURE_TYPE_FRONT_COVER, + ) + } + return MediaItem.Builder() .setMediaId(id) - .setMediaMetadata(metaData) + .setMediaMetadata(metadataBuilder.build()) .build() } } diff --git a/app/src/main/java/com/snstudio/hyper/data/model/Media.kt b/app/src/main/java/com/snstudio/hyper/data/model/Media.kt index c903ac0..c29e3c9 100644 --- a/app/src/main/java/com/snstudio/hyper/data/model/Media.kt +++ b/app/src/main/java/com/snstudio/hyper/data/model/Media.kt @@ -14,6 +14,7 @@ data class Media( val url: String?, val duration: Long?, val thumbnail: String?, + val thumbnailMax: String?, val publishYear: String?, val uploadYear: String?, val viewCount: String?, diff --git a/app/src/main/java/com/snstudio/hyper/feature/home/HighlightsAdapter.kt b/app/src/main/java/com/snstudio/hyper/feature/home/HighlightsAdapter.kt new file mode 100644 index 0000000..d09d7de --- /dev/null +++ b/app/src/main/java/com/snstudio/hyper/feature/home/HighlightsAdapter.kt @@ -0,0 +1,76 @@ +package com.snstudio.hyper.feature.home + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.RecyclerView +import com.snstudio.hyper.core.extension.click +import com.snstudio.hyper.core.extension.loadWithGlideWithRadius +import com.snstudio.hyper.data.model.Media +import com.snstudio.hyper.databinding.ItemHighlightsBinding + +class HighlightsAdapter( + private val onItemCLick: ((Media) -> Unit)? = null, +) : RecyclerView.Adapter() { + private var items: MutableList = mutableListOf() + + fun setItems(newItems: List) { + val diffResult = DiffUtil.calculateDiff(HighlightsDiffCallback(items, newItems)) + items = newItems.toMutableList() + diffResult.dispatchUpdatesTo(this) + } + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int, + ): HighlightsViewHolder = + HighlightsViewHolder( + ItemHighlightsBinding.inflate(LayoutInflater.from(parent.context), parent, false), + ) + + override fun onBindViewHolder( + holder: HighlightsViewHolder, + position: Int, + ) { + holder.bind(items[position]) + holder.itemView.click { + onItemCLick?.invoke(items[position]) + } + } + + override fun getItemCount(): Int = items.size + + inner class HighlightsViewHolder(val binding: ItemHighlightsBinding) : + RecyclerView.ViewHolder(binding.root) { + fun bind(item: Media) { + with(binding) { + val thumb = item.thumbnailMax ?: item.thumbnail + image.loadWithGlideWithRadius(thumb.orEmpty()) + title.text = item.title + } + } + } + + inner class HighlightsDiffCallback( + private val oldList: List, + private val newList: List, + ) : DiffUtil.Callback() { + override fun getOldListSize(): Int = oldList.size + + override fun getNewListSize(): Int = newList.size + + override fun areItemsTheSame( + oldItemPosition: Int, + newItemPosition: Int, + ): Boolean { + return oldList[oldItemPosition].id == newList[newItemPosition].id + } + + override fun areContentsTheSame( + oldItemPosition: Int, + newItemPosition: Int, + ): Boolean { + return oldList[oldItemPosition] == newList[newItemPosition] + } + } +} diff --git a/app/src/main/java/com/snstudio/hyper/feature/home/HomeFragment.kt b/app/src/main/java/com/snstudio/hyper/feature/home/HomeFragment.kt index 346b7d0..3fe1702 100644 --- a/app/src/main/java/com/snstudio/hyper/feature/home/HomeFragment.kt +++ b/app/src/main/java/com/snstudio/hyper/feature/home/HomeFragment.kt @@ -9,14 +9,29 @@ import android.provider.Settings import androidx.activity.result.contract.ActivityResultContracts import androidx.core.app.NotificationManagerCompat import androidx.core.content.ContextCompat +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope +import com.faltenreich.skeletonlayout.Skeleton +import com.faltenreich.skeletonlayout.applySkeleton import com.snstudio.hyper.BuildConfig +import com.snstudio.hyper.R import com.snstudio.hyper.core.base.BaseFragment -import com.snstudio.hyper.core.extension.click +import com.snstudio.hyper.core.extension.isValidImageUrl import com.snstudio.hyper.core.extension.observe import com.snstudio.hyper.core.extension.openUrlInBrowser import com.snstudio.hyper.core.extension.startActivitySafely +import com.snstudio.hyper.core.extension.toMediaList +import com.snstudio.hyper.data.MediaItemBuilder +import com.snstudio.hyper.data.model.Media import com.snstudio.hyper.databinding.FragmentHomeBinding +import com.snstudio.hyper.shared.MediaViewModel +import com.snstudio.hyper.util.DATA_KEY +import com.snstudio.hyper.util.EXCEPTION +import com.snstudio.hyper.util.ErrorDialog +import com.snstudio.hyper.util.MediaItemType +import com.snstudio.hyper.util.RECEIVED import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch @AndroidEntryPoint class HomeFragment : BaseFragment() { @@ -24,6 +39,29 @@ class HomeFragment : BaseFragment() { override fun getViewBinding() = FragmentHomeBinding.inflate(layoutInflater) + private lateinit var mediaViewModel: MediaViewModel + private var skeletonHighlights: Skeleton? = null + private var skeletonDownloads: Skeleton? = null + + private val adapterHighlights by lazy { + HighlightsAdapter( + onItemCLick = { media -> + viewModel.invokeAudioUrl(media) + }, + ) + } + + private val lastDownloadsAdapter by lazy { + LastDownloadsAdapter( + onAddCLick = { + navigate(HomeFragmentDirections.goToSearch()) + }, + onItemCLick = { media, _ -> + playMedia(media) + }, + ) + } + override fun observeData() { observe(viewModel.forceUpdateLiveData) { lastVersion -> lastVersion?.let { @@ -32,6 +70,35 @@ class HomeFragment : BaseFragment() { } } } + viewLifecycleOwner.lifecycleScope.launch { + viewModel.receivedData.collect { call -> + when (call.method) { + RECEIVED.HIGHLIGHTS_RECEIVED.received -> { + call.argument>>(DATA_KEY)?.let { data -> + adapterHighlights.setItems(data.toMediaList(MediaItemType.REMOTE)) + skeletonHighlights?.showOriginal() + } + } + + RECEIVED.AUDIO_URL_RECEIVED.received -> { + call.argument>(DATA_KEY)?.let { data -> + val url = data["url"].orEmpty() + val errorCode = data["errorCode"] + if (!errorCode.isNullOrEmpty()) { + showErrorDialog(errorCode) + mediaViewModel.showPLayerMenu(false) + return@let + } + playMediaWithUrl(url) + } + } + } + } + } + observe(viewModel.localMediaListLiveData) { mediaList -> + lastDownloadsAdapter.addItems(mediaList) + skeletonDownloads?.showOriginal() + } } override fun onResume() { @@ -40,19 +107,21 @@ class HomeFragment : BaseFragment() { } override fun setupViews() { - binding.vm = viewModel - binding.lifecycleOwner = viewLifecycleOwner + with(binding) { + vm = viewModel + lifecycleOwner = viewLifecycleOwner + recyclerHighlights.adapter = adapterHighlights + recyclerDownloads.adapter = lastDownloadsAdapter + } + viewModel.initReceive() + initMediaViewModel() + initSkeletonHighlights() + initSkeletonDownloads() initClickListener() } private fun initClickListener() { with(binding) { - musicCard.root.click { - navigate(HomeFragmentDirections.goToLibrary()) - } - playList.root.click { - navigate(HomeFragmentDirections.goToPlaylist()) - } colorizedBar.setOnIconClickListener { index -> when (index) { 0 -> navigate(HomeFragmentDirections.goToSearch()) @@ -62,6 +131,10 @@ class HomeFragment : BaseFragment() { } } + private fun initMediaViewModel() { + mediaViewModel = ViewModelProvider(requireActivity())[MediaViewModel::class.java] + } + private val notificationPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> if (!isGranted) { @@ -119,9 +192,74 @@ class HomeFragment : BaseFragment() { context?.openUrlInBrowser(BuildConfig.RELEASE_DOWNLOAD.plus(lastVersion)) } else { dialog.dismiss() - activity?.finish() } } dialog.showDialog(childFragmentManager) } + + private fun initSkeletonHighlights() { + if (skeletonHighlights == null) { + binding.recyclerHighlights.applySkeleton(R.layout.item_highlights).apply { + skeletonHighlights = this + maskColor = + ContextCompat.getColor(requireContext(), R.color.secondary_background_color) + shimmerColor = + ContextCompat.getColor(requireContext(), R.color.third_background_color) + showSkeleton() + } + } + } + + private fun initSkeletonDownloads() { + if (skeletonDownloads == null) { + binding.recyclerDownloads.applySkeleton(R.layout.item_highlights).apply { + skeletonDownloads = this + maskColor = + ContextCompat.getColor(requireContext(), R.color.secondary_background_color) + shimmerColor = + ContextCompat.getColor(requireContext(), R.color.third_background_color) + showSkeleton() + } + } + } + + private fun playMedia(media: Media) { + media.localPath?.let { + val item = + MediaItemBuilder().setMediaId(it) + .setArtWorkBitmap(media.bitmap) + .setMediaTitle(media.title) + .build() + with(mediaViewModel) { + showPLayerMenu(true) + playMediaItem(item) + } + } + } + + private fun playMediaWithUrl(url: String) { + with(viewModel) { + currentMedia?.let { media -> + media.thumbnailMax.isValidImageUrl(requireContext()) { isValid -> + val thumb = if (isValid) media.thumbnailMax else media.thumbnail + val item = + MediaItemBuilder().setMediaId(url) + .setArtWorkUrl(thumb.orEmpty()) + .setMediaTitle(media.title) + .build() + mediaViewModel.playMediaItem(item) + } + } + } + } + + private fun showErrorDialog(code: String) { + val errMessage = + if (code == EXCEPTION.YT_EXPLODE_EXCEPTION.code) { + R.string.yt_explode_error + } else { + R.string.unexpected_error + } + ErrorDialog(errMessage = errMessage).showDialog(childFragmentManager) + } } diff --git a/app/src/main/java/com/snstudio/hyper/feature/home/HomeViewModel.kt b/app/src/main/java/com/snstudio/hyper/feature/home/HomeViewModel.kt index 605aef5..3e0e8ee 100644 --- a/app/src/main/java/com/snstudio/hyper/feature/home/HomeViewModel.kt +++ b/app/src/main/java/com/snstudio/hyper/feature/home/HomeViewModel.kt @@ -1,13 +1,16 @@ package com.snstudio.hyper.feature.home -import androidx.databinding.ObservableBoolean import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import com.snstudio.hyper.BuildConfig import com.snstudio.hyper.core.base.BaseViewModel import com.snstudio.hyper.core.extension.parseObject +import com.snstudio.hyper.data.local.repository.MediaRepository +import com.snstudio.hyper.data.model.Media +import com.snstudio.hyper.util.INVOKE import com.snstudio.hyper.util.PrefsTag +import com.snstudio.hyper.util.RECEIVED import com.snstudio.hyper.util.SharedPreferenceManager import dagger.hilt.android.lifecycle.HiltViewModel import io.flutter.plugin.common.MethodChannel @@ -23,29 +26,51 @@ import javax.inject.Inject class HomeViewModel @Inject constructor( - methodChannel: MethodChannel, + private val methodChannel: MethodChannel, private val sharedPreferenceManager: SharedPreferenceManager, + private val localMediaRepository: MediaRepository, ) : BaseViewModel(methodChannel) { + private val localMediaListMLiveData = MutableLiveData>() + val localMediaListLiveData: LiveData> = localMediaListMLiveData + private val forceUpdateMLiveData = MutableLiveData() val forceUpdateLiveData: LiveData = forceUpdateMLiveData var notificationRuntimeRequested: Boolean = false - - val progress = ObservableBoolean(true) + var currentMedia: Media? = null + private set init { + collectLocalMediaData() + getHighlights() checkVersion() } + fun initReceive() { + receivedData(RECEIVED.HIGHLIGHTS_RECEIVED.received, RECEIVED.AUDIO_URL_RECEIVED.received) + } + fun hasNotificationRequestedPermissionBefore() = sharedPreferenceManager.getBoolean(PrefsTag.PERMISSION_NOTIFICATION) fun setNotificationPermissionRequested() = sharedPreferenceManager.putBoolean(PrefsTag.PERMISSION_NOTIFICATION, true) + private fun collectLocalMediaData() = + viewModelScope.launch { + localMediaRepository.localMediaList + .collect { + localMediaListMLiveData.value = it.asReversed().take(6) + } + } + + fun invokeAudioUrl(media: Media) { + currentMedia = media + methodChannel.invokeMethod(INVOKE.AUDIO_URL.invoke, media.id) + } + private fun checkVersion() = viewModelScope.launch { val latestVersion = fetchLatestVersion() forceUpdateMLiveData.postValue(latestVersion) - progress.set(false) } private suspend fun fetchLatestVersion(): String? = @@ -70,6 +95,20 @@ class HomeViewModel } } + private fun getHighlights() { + methodChannel.invokeMethod( + INVOKE.HIGHLIGHTS.invoke, + listOf( + "SiMPOxBOy_4", + "VREnTCTeS4k", + "9TSf2k03HPA", + "TJ8ADu6MfGo", + "OFWBSpsqYM8", + "1X0LU8GTj70", + ), + ) + } + companion object { const val JSON_TAG_NAME = "tag_name" } diff --git a/app/src/main/java/com/snstudio/hyper/feature/home/LastDownloadsAdapter.kt b/app/src/main/java/com/snstudio/hyper/feature/home/LastDownloadsAdapter.kt new file mode 100644 index 0000000..29229d8 --- /dev/null +++ b/app/src/main/java/com/snstudio/hyper/feature/home/LastDownloadsAdapter.kt @@ -0,0 +1,115 @@ +package com.snstudio.hyper.feature.home + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.databinding.ViewDataBinding +import androidx.recyclerview.widget.RecyclerView +import com.snstudio.hyper.BR +import com.snstudio.hyper.R +import com.snstudio.hyper.core.extension.click +import com.snstudio.hyper.core.extension.loadWithGlideWithRadius +import com.snstudio.hyper.data.model.Media +import com.snstudio.hyper.databinding.ItemAddMusicBinding +import com.snstudio.hyper.databinding.ItemHighlightsBinding + +class LastDownloadsAdapter( + private val onItemCLick: ((Media, Int) -> Unit)? = null, + private val onAddCLick: (() -> Unit)? = null, +) : RecyclerView.Adapter() { + private var mediaItems: MutableList = mutableListOf() + + fun addItems(newItems: List) { + mediaItems.clear() + val startPosition = mediaItems.size + 1 + mediaItems.addAll(newItems) + notifyItemRangeInserted(startPosition, newItems.size) + } + + override fun getItemViewType(position: Int): Int { + return if (position == 0) { + R.layout.item_add_music + } else { + R.layout.item_highlights + } + } + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int, + ): AutoCompleteViewHolder { + return AutoCompleteViewHolder.create( + LayoutInflater.from(parent.context), + parent, + viewType, + this@LastDownloadsAdapter, + ) + } + + override fun onBindViewHolder( + holder: AutoCompleteViewHolder, + position: Int, + ) { + if (position == 0) { + holder.bindAddButton() + } else { + holder.bindItem(mediaItems[position - 1]) + } + } + + override fun getItemCount(): Int { + return mediaItems.size + 1 + } + + class AutoCompleteViewHolder( + private val binding: ViewDataBinding, + private val adapter: LastDownloadsAdapter, + ) : RecyclerView.ViewHolder(binding.root) { + fun bindItem(media: Media) { + binding.setVariable(BR.item, media) + binding.executePendingBindings() + + when (binding) { + is ItemHighlightsBinding -> bindHighlights(media) + is ItemAddMusicBinding -> bindAddMusicBinding() + } + } + + fun bindAddButton() { + when (binding) { + is ItemAddMusicBinding -> bindAddMusicBinding() + } + } + + private fun bindHighlights(media: Media) { + (binding as ItemHighlightsBinding).apply { + root.click { adapter.onItemCLick?.invoke(media, absoluteAdapterPosition) } + val thumb = media.thumbnailMax ?: media.thumbnail + image.loadWithGlideWithRadius(thumb.orEmpty()) + binding.title.text = media.title + } + } + + private fun bindAddMusicBinding() { + (binding as ItemAddMusicBinding).apply { + itemView.click { adapter.onAddCLick?.invoke() } + } + } + + companion object { + fun create( + inflater: LayoutInflater, + parent: ViewGroup?, + viewType: Int, + adapter: LastDownloadsAdapter, + ): AutoCompleteViewHolder { + val binding = + DataBindingUtil.inflate(inflater, viewType, parent, false) + return AutoCompleteViewHolder( + binding, + adapter, + ) + } + } + } +} diff --git a/app/src/main/java/com/snstudio/hyper/feature/library/LibraryFragment.kt b/app/src/main/java/com/snstudio/hyper/feature/library/LibraryFragment.kt index 81979fc..219d6f2 100644 --- a/app/src/main/java/com/snstudio/hyper/feature/library/LibraryFragment.kt +++ b/app/src/main/java/com/snstudio/hyper/feature/library/LibraryFragment.kt @@ -1,7 +1,10 @@ package com.snstudio.hyper.feature.library +import android.os.Build +import android.view.ContextThemeWrapper +import android.view.View +import android.widget.PopupMenu import androidx.lifecycle.ViewModelProvider -import androidx.recyclerview.widget.ItemTouchHelper import com.snstudio.hyper.R import com.snstudio.hyper.core.base.BaseFragment import com.snstudio.hyper.core.extension.click @@ -12,7 +15,6 @@ import com.snstudio.hyper.databinding.FragmentLibraryBinding import com.snstudio.hyper.shared.MediaItemAdapter import com.snstudio.hyper.shared.MediaViewModel import com.snstudio.hyper.util.InfoDialog -import com.snstudio.hyper.util.ItemTouchHelperCallback import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint @@ -20,8 +22,10 @@ class LibraryFragment : BaseFragment() private lateinit var mediaViewModel: MediaViewModel private val mediaItemAdapter: MediaItemAdapter by lazy { - MediaItemAdapter(onClick = { media, _ -> + MediaItemAdapter(onItemCLick = { media, _ -> playMedia(media) + }, onMenuClick = { media, view -> + showPopupMenu(media, view) }) } @@ -31,7 +35,6 @@ class LibraryFragment : BaseFragment() override fun setupViews() { initMediaRecycler() - createTouchHelperCallback() initMediaViewModel() initClickListener() with(binding) { @@ -44,7 +47,6 @@ class LibraryFragment : BaseFragment() override fun observeData() { observe(viewModel.localMediaLiveData) { mediaList -> mediaItemAdapter.setItems(mediaList.toMutableList()) - if (mediaList.isNotEmpty()) showInfoDialog() } } @@ -58,24 +60,15 @@ class LibraryFragment : BaseFragment() } } - private fun createTouchHelperCallback() { - val callback = - ItemTouchHelperCallback( - requireContext(), - onSwipedCallback = { pos -> deleteMedia(pos) }, - ) - val itemTouchHelper = ItemTouchHelper(callback) - itemTouchHelper.attachToRecyclerView(binding.recyclerMedia) - } - - private fun deleteMedia(pos: Int) { - viewModel.deleteMedia(mediaItemAdapter.mediaItems[pos]) + private fun deleteMedia(media: Media) { + viewModel.deleteMedia(media) } private fun playMedia(media: Media) { media.localPath?.let { val item = MediaItemBuilder().setMediaId(it) + .setArtWorkBitmap(media.bitmap) .setMediaTitle(media.title) .build() with(mediaViewModel) { @@ -89,13 +82,37 @@ class LibraryFragment : BaseFragment() mediaViewModel = ViewModelProvider(requireActivity())[MediaViewModel::class.java] } - private fun showInfoDialog() { - if (!viewModel.getInfoDialogStatus()) { - InfoDialog( - titleResId = R.string.how_to_delete, - imageResId = R.drawable.delete_info, - ).showDialog(childFragmentManager) - viewModel.setTrueInfoDialogStatus() + private fun showPopupMenu( + media: Media, + view: View, + ) { + val popupMenu = PopupMenu(ContextThemeWrapper(context, R.style.PopupMenuTheme), view) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + popupMenu.setForceShowIcon(true) } + popupMenu.menuInflater.inflate(R.menu.library_menu, popupMenu.menu) + popupMenu.setOnMenuItemClickListener { menuItem -> + when (menuItem.itemId) { + R.id.delete -> { + showInfoDialog(media) + true + } + + R.id.play -> { + playMedia(media) + true + } + + else -> false + } + } + + popupMenu.show() + } + + private fun showInfoDialog(media: Media) { + InfoDialog(titleResId = R.string.selected_item_deleted, onClick = { + deleteMedia(media) + }).showDialog(childFragmentManager) } } diff --git a/app/src/main/java/com/snstudio/hyper/feature/library/LibraryViewModel.kt b/app/src/main/java/com/snstudio/hyper/feature/library/LibraryViewModel.kt index 2642987..d901ff6 100644 --- a/app/src/main/java/com/snstudio/hyper/feature/library/LibraryViewModel.kt +++ b/app/src/main/java/com/snstudio/hyper/feature/library/LibraryViewModel.kt @@ -6,8 +6,6 @@ import androidx.lifecycle.asLiveData import androidx.lifecycle.viewModelScope import com.snstudio.hyper.data.local.repository.MediaRepository import com.snstudio.hyper.data.model.Media -import com.snstudio.hyper.util.PrefsTag -import com.snstudio.hyper.util.SharedPreferenceManager import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import javax.inject.Inject @@ -17,7 +15,6 @@ class LibraryViewModel @Inject constructor( private val localMediaRepository: MediaRepository, - private val sharedPreferenceManager: SharedPreferenceManager, ) : ViewModel() { val localMediaLiveData: LiveData> = localMediaRepository.localMediaList.asLiveData() @@ -26,10 +23,4 @@ class LibraryViewModel viewModelScope.launch { localMediaRepository.delete(media) } - - fun setTrueInfoDialogStatus() { - sharedPreferenceManager.putBoolean(PrefsTag.DELETE_INFO_DIALOG_SHOW, true) - } - - fun getInfoDialogStatus(): Boolean = sharedPreferenceManager.getBoolean(PrefsTag.DELETE_INFO_DIALOG_SHOW) } diff --git a/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistAdapter.kt b/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistAdapter.kt index df81d20..a0a8f60 100644 --- a/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistAdapter.kt +++ b/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistAdapter.kt @@ -1,8 +1,9 @@ package com.snstudio.hyper.feature.playlist import android.content.Context -import android.graphics.PorterDuff +import android.content.res.ColorStateList import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.recyclerview.widget.DiffUtil @@ -15,16 +16,16 @@ import com.snstudio.hyper.databinding.ItemPlayListBinding class PlaylistAdapter( private val context: Context, - private val onClick: ((Playlist) -> Unit)? = null, -) : - RecyclerView.Adapter() { + private val onItemCLick: ((Playlist) -> Unit)? = null, + private val onMenuClick: ((Playlist, View) -> Unit)? = null, +) : RecyclerView.Adapter() { private var items: MutableList = mutableListOf() private val colorList = listOf( R.color.main_color, - R.color.main_color_mid, - R.color.main_color_light, + R.color.old_main_color_mid, + R.color.old_main_color_light, R.color.purple_500, R.color.purple_700, ) @@ -35,8 +36,6 @@ class PlaylistAdapter( diffResult.dispatchUpdatesTo(this) } - fun getItemWithPos(pos: Int): Playlist = items[pos] - override fun onCreateViewHolder( parent: ViewGroup, viewType: Int, @@ -51,7 +50,7 @@ class PlaylistAdapter( ) { holder.bind(items[position]) holder.itemView.click { - onClick?.invoke(items[position]) + onItemCLick?.invoke(items[position]) } } @@ -62,10 +61,15 @@ class PlaylistAdapter( fun bind(item: Playlist) { val randomColorResId = colorList.random() val color = ContextCompat.getColor(context, randomColorResId) - - binding.playlistName.text = item.name - binding.thumbnail.setColorFilter(color, PorterDuff.Mode.SRC_IN) - binding.description.text = item.creationDate.formatAsDate() + with(binding) { + thumbnail.backgroundTintList = ColorStateList.valueOf(color) + thumbnail.text = item.name.first().toString() + playlistName.text = item.name + description.text = item.creationDate.formatAsDate() + menu.click { + onMenuClick?.invoke(item, it) + } + } } } diff --git a/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistDetailFragment.kt b/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistDetailFragment.kt index 924b0cb..c1c2c38 100644 --- a/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistDetailFragment.kt +++ b/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistDetailFragment.kt @@ -1,5 +1,10 @@ package com.snstudio.hyper.feature.playlist +import android.annotation.SuppressLint +import android.os.Build +import android.view.ContextThemeWrapper +import android.view.View +import android.widget.PopupMenu import androidx.lifecycle.ViewModelProvider import androidx.navigation.fragment.navArgs import androidx.recyclerview.widget.ItemTouchHelper @@ -9,6 +14,7 @@ import com.snstudio.hyper.core.extension.click import com.snstudio.hyper.core.extension.infoToast import com.snstudio.hyper.core.extension.observe import com.snstudio.hyper.data.MediaItemBuilder +import com.snstudio.hyper.data.model.Media import com.snstudio.hyper.databinding.FragmentPlaylistDetailBinding import com.snstudio.hyper.feature.picker.MediaPickerDialog import com.snstudio.hyper.shared.MediaItemAdapter @@ -21,9 +27,9 @@ class PlaylistDetailFragment : BaseFragment + MediaItemAdapter(onItemCLick = { _, pos -> setPlayList(pos) - }) + }, onMenuClick = { media, view -> showPopupMenu(media, view) }) } override fun getViewModelClass() = PlaylistViewModel::class.java @@ -43,13 +49,20 @@ class PlaylistDetailFragment : BaseFragment mediaItemAdapter.setItems(mediaList.toMutableList()) + /* + binding.listInfo.text = context?.getString( + R.string.media_list_info, + mediaList.size, + mediaList.sumOf { it.duration ?: 0 }.toDuration() + )*/ } - observe(deleteMediaLiveData) { deletedItemPos -> - mediaItemAdapter.removeItem(deletedItemPos) + observe(deleteMediaLiveData) { deletedItem -> + mediaItemAdapter.removeItem(deletedItem) } } @@ -58,14 +71,22 @@ class PlaylistDetailFragment : BaseFragment - when (index) { - 0 -> showMediaPickerDialog() - else -> return@setOnIconClickListener + with(binding) { + noMusicItem.click { + showMediaPickerDialog() + } + playAll.click { + setPlayList(0) + } + shuffle.click { + setPlayList(0, true) + } + colorizedBar.setOnIconClickListener { index -> + when (index) { + 0 -> showMediaPickerDialog() + else -> return@setOnIconClickListener + } } - } - binding.noMusicItem.click { - showMediaPickerDialog() } } @@ -73,16 +94,25 @@ class PlaylistDetailFragment : BaseFragment - MediaItemBuilder() - .setMediaId(media.localPath.orEmpty()) - .setMediaTitle(media.title) - .build() - } + mediaItemAdapter.mediaItems + .let { items -> + if (shuffle) items.shuffled() else items + } + .map { media -> + MediaItemBuilder() + .setMediaId(media.localPath.orEmpty()) + .setArtWorkBitmap(media.bitmap) + .setMediaTitle(media.title) + .build() + } + mediaViewModel.showPLayerMenu(true) - mediaViewModel.setPlaylist(mediaItems, pos) + mediaViewModel.setPlaylist(mediaItems, if (shuffle) 0 else pos) } private fun showMediaPickerDialog() { @@ -117,10 +147,8 @@ class PlaylistDetailFragment : BaseFragment removeItem(pos) }, onMoveCallback = { from, to -> moveItem(from, to) }, + onMovedCallback = { movedItem() }, ) val itemTouchHelper = ItemTouchHelper(callback) itemTouchHelper.attachToRecyclerView(binding.recyclerMedia) @@ -140,12 +168,29 @@ class PlaylistDetailFragment : BaseFragment= Build.VERSION_CODES.Q) { + popupMenu.setForceShowIcon(true) + } + popupMenu.menuInflater.inflate(R.menu.playlist_detail_menu, popupMenu.menu) + popupMenu.setOnMenuItemClickListener { menuItem -> + when (menuItem.itemId) { + R.id.remove -> { + removeItem(media) + true + } + + else -> false + } + } + popupMenu.show() } } diff --git a/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistFragment.kt b/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistFragment.kt index 926271c..efa50cb 100644 --- a/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistFragment.kt +++ b/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistFragment.kt @@ -1,20 +1,24 @@ package com.snstudio.hyper.feature.playlist -import androidx.recyclerview.widget.ItemTouchHelper +import android.os.Build +import android.view.ContextThemeWrapper +import android.view.View +import android.widget.PopupMenu +import com.snstudio.hyper.R import com.snstudio.hyper.core.base.BaseFragment import com.snstudio.hyper.core.extension.click import com.snstudio.hyper.core.extension.observe import com.snstudio.hyper.data.model.Playlist import com.snstudio.hyper.databinding.FragmentPlaylistBinding -import com.snstudio.hyper.util.ItemTouchHelperCallback +import com.snstudio.hyper.util.InfoDialog import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class PlaylistFragment : BaseFragment() { private val playlistAdapter by lazy { - PlaylistAdapter(requireContext(), onClick = { + PlaylistAdapter(requireContext(), onItemCLick = { navigatePlaylistDetail(it) - }) + }, onMenuClick = { playlist, view -> showPopupMenu(playlist, view) }) } override var useSharedViewModel = true @@ -26,7 +30,6 @@ class PlaylistFragment : BaseFragment - viewModel.deletePlaylist( - playlistAdapter.getItemWithPos( - pos, - ), - ) - }, - ) - val itemTouchHelper = ItemTouchHelper(callback) - itemTouchHelper.attachToRecyclerView(binding.recyclerPlaylist) - } - private fun navigatePlaylistDetail(playlist: Playlist) { val action = PlaylistFragmentDirections.goToPlaylistDetail(playlist.playlistId, playlist.name) navigate(action) } + + private fun showPopupMenu( + playlist: Playlist, + view: View, + ) { + val popupMenu = PopupMenu(ContextThemeWrapper(context, R.style.PopupMenuTheme), view) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + popupMenu.setForceShowIcon(true) + } + popupMenu.menuInflater.inflate(R.menu.playlist_menu, popupMenu.menu) + popupMenu.setOnMenuItemClickListener { menuItem -> + when (menuItem.itemId) { + R.id.delete -> { + showInfoDialog(playlist) + true + } + + else -> false + } + } + + popupMenu.show() + } + + private fun deletePlaylist(playlist: Playlist) { + viewModel.deletePlaylist(playlist) + } + + private fun showInfoDialog(playlist: Playlist) { + InfoDialog(titleResId = R.string.selected_item_deleted, onClick = { + deletePlaylist(playlist) + }).showDialog(childFragmentManager) + } } diff --git a/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistViewModel.kt b/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistViewModel.kt index 8d9cf2d..44ff0a2 100644 --- a/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistViewModel.kt +++ b/app/src/main/java/com/snstudio/hyper/feature/playlist/PlaylistViewModel.kt @@ -31,8 +31,8 @@ class PlaylistViewModel private val playlistWithMediaMLiveData = MutableLiveData>() val playlistWithMediaLiveData: LiveData> = playlistWithMediaMLiveData - private val _deleteMediaLiveData = MutableLiveData() - val deleteMediaLiveData: LiveData = _deleteMediaLiveData + private val _deleteMediaLiveData = MutableLiveData() + val deleteMediaLiveData: LiveData = _deleteMediaLiveData init { getPlayList() @@ -90,11 +90,10 @@ class PlaylistViewModel fun deleteMediaFromPlaylist( playlistId: Long, - mediaId: String, - pos: Int, + media: Media, ) = viewModelScope.launch { - playlistMediaCrossRepository.deleteMediaFromPlaylist(playlistId, mediaId) + playlistMediaCrossRepository.deleteMediaFromPlaylist(playlistId, media.id) }.invokeOnCompletion { throwable -> - if (throwable == null) _deleteMediaLiveData.postValue(pos) + if (throwable == null) _deleteMediaLiveData.postValue(media) } } diff --git a/app/src/main/java/com/snstudio/hyper/feature/search/SearchFragment.kt b/app/src/main/java/com/snstudio/hyper/feature/search/SearchFragment.kt index d297b3a..2cc3f6b 100644 --- a/app/src/main/java/com/snstudio/hyper/feature/search/SearchFragment.kt +++ b/app/src/main/java/com/snstudio/hyper/feature/search/SearchFragment.kt @@ -1,19 +1,21 @@ package com.snstudio.hyper.feature.search -import android.annotation.SuppressLint import android.os.Build import android.util.TypedValue +import android.view.ContextThemeWrapper +import android.view.View import android.widget.EditText +import android.widget.PopupMenu import androidx.appcompat.widget.SearchView import androidx.core.content.ContextCompat import androidx.lifecycle.ViewModelProvider -import androidx.recyclerview.widget.ItemTouchHelper +import androidx.lifecycle.lifecycleScope import com.snstudio.hyper.R import com.snstudio.hyper.core.base.BaseFragment import com.snstudio.hyper.core.extension.addOnScrolledToEnd import com.snstudio.hyper.core.extension.convertToBitmap import com.snstudio.hyper.core.extension.infoToast -import com.snstudio.hyper.core.extension.observe +import com.snstudio.hyper.core.extension.isValidImageUrl import com.snstudio.hyper.core.extension.restoreScrollPosition import com.snstudio.hyper.core.extension.toMediaList import com.snstudio.hyper.core.extension.waningToast @@ -28,12 +30,10 @@ import com.snstudio.hyper.shared.ProgressLiveData import com.snstudio.hyper.util.DATA_KEY import com.snstudio.hyper.util.EXCEPTION import com.snstudio.hyper.util.ErrorDialog -import com.snstudio.hyper.util.InfoDialog -import com.snstudio.hyper.util.ItemTouchHelperCallback import com.snstudio.hyper.util.MediaItemType import com.snstudio.hyper.util.RECEIVED -import com.snstudio.hyper.util.SwipeAction import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch @AndroidEntryPoint class SearchFragment : @@ -42,9 +42,11 @@ class SearchFragment : private lateinit var mediaViewModel: MediaViewModel private val mediaItemAdapter by lazy { - MediaItemAdapter(onClick = { media, _ -> + MediaItemAdapter(onItemCLick = { media, _ -> mediaViewModel.showPLayerMenu(true) viewModel.invokeAudioUrl(media, SearchViewModel.AudioActionType.PLAY) + }, onMenuClick = { media, view -> + showPopupMenu(media, view) }) } @@ -55,7 +57,6 @@ class SearchFragment : override fun setupViews() { initMediaViewModel() initMediaRecycler() - attachItemTouchHelperCallback() initSearch() with(binding) { vm = viewModel @@ -65,42 +66,43 @@ class SearchFragment : override fun observeData() { with(viewModel) { - observe(receivedData) { - when (it.method) { - RECEIVED.SEARCH_RECEIVED.received -> { - it.argument>>(DATA_KEY)?.let { data -> - viewModel.searchProgressObservable.set(false) - viewModel.searchResultIsEmptyObservable.set(data.isEmpty()) - mediaItemAdapter.setItems(data.toMediaList(MediaItemType.SEARCH)) - showInfoDialog() + viewLifecycleOwner.lifecycleScope.launch { + receivedData.collect { + when (it.method) { + RECEIVED.SEARCH_RECEIVED.received -> { + it.argument>>(DATA_KEY)?.let { data -> + viewModel.searchProgressObservable.set(false) + viewModel.searchResultIsEmptyObservable.set(data.isEmpty()) + mediaItemAdapter.setItems(data.toMediaList(MediaItemType.REMOTE)) + } } - } - RECEIVED.AUDIO_URL_RECEIVED.received -> { - it.argument>(DATA_KEY)?.let { data -> - val url = data["url"].orEmpty() - val errorCode = data["errorCode"] - if (!errorCode.isNullOrEmpty()) { - showErrorDialog(errorCode) - mediaViewModel.showPLayerMenu(false) - return@observe - } - when (audioActionType) { - SearchViewModel.AudioActionType.PLAY -> { - playMedia(url) + RECEIVED.AUDIO_URL_RECEIVED.received -> { + it.argument>(DATA_KEY)?.let { data -> + val url = data["url"].orEmpty() + val errorCode = data["errorCode"] + if (!errorCode.isNullOrEmpty()) { + showErrorDialog(errorCode) + mediaViewModel.showPLayerMenu(false) + return@collect } + when (audioActionType) { + SearchViewModel.AudioActionType.PLAY -> { + playMedia(url) + } - SearchViewModel.AudioActionType.DOWNLOAD -> { - startDownloadService(url) + SearchViewModel.AudioActionType.DOWNLOAD -> { + startDownloadService(url) + } } } } - } - RECEIVED.NEXT_RECEIVED.received -> { - it.argument>>(DATA_KEY)?.let { data -> - mediaItemAdapter.addItem(data.toMediaList(MediaItemType.SEARCH)) - binding.recyclerMedia.restoreScrollPosition() + RECEIVED.NEXT_RECEIVED.received -> { + it.argument>>(DATA_KEY)?.let { data -> + mediaItemAdapter.addItem(data.toMediaList(MediaItemType.REMOTE)) + binding.recyclerMedia.restoreScrollPosition() + } } } } @@ -110,23 +112,26 @@ class SearchFragment : override fun onJobStart(id: String) { ProgressLiveData.updateDownloadState( - ProgressLiveData.DownloadState.Started( - viewModel.currentMedia?.title.orEmpty(), - ), + ProgressLiveData.DownloadState.Started(id, viewModel.currentMedia?.title.orEmpty()), ) } - override fun onJobProgress(progress: Int) { + override fun onJobProgress( + media: Media, + progress: Int, + ) { ProgressLiveData.updateDownloadState( ProgressLiveData.DownloadState.InProgress( + media, progress, ), ) } override fun onJobCompleted(media: Media) { - ProgressLiveData.updateDownloadState(ProgressLiveData.DownloadState.Completed) - media.thumbnail?.convertToBitmap(requireContext(), onSuccess = { bitmap -> + ProgressLiveData.updateDownloadState(ProgressLiveData.DownloadState.Completed(media.id)) + val thumb = media.thumbnailMax ?: media.thumbnail + thumb?.convertToBitmap(requireContext(), onSuccess = { bitmap -> val localMedia = media.copy(bitmap = bitmap, type = MediaItemType.LOCAL.key) viewModel.insertMediaJob(localMedia) }, onFailure = {}) @@ -135,11 +140,15 @@ class SearchFragment : private fun playMedia(url: String) { with(viewModel) { currentMedia?.let { media -> - val item = - MediaItemBuilder().setMediaId(url) - .setMediaTitle(media.title) - .build() - mediaViewModel.playMediaItem(item) + media.thumbnailMax.isValidImageUrl(requireContext()) { isValid -> + val thumb = if (isValid) media.thumbnailMax else media.thumbnail + val item = + MediaItemBuilder().setMediaId(url) + .setArtWorkUrl(thumb.orEmpty()) + .setMediaTitle(media.title) + .build() + mediaViewModel.playMediaItem(item) + } } } } @@ -178,33 +187,17 @@ class SearchFragment : with(binding.recyclerMedia) { adapter = mediaItemAdapter itemAnimator = null - // addDivider(requireContext()) addOnScrolledToEnd { viewModel.invokeNext() } } } - @SuppressLint("NotifyDataSetChanged") // Todo - private fun attachItemTouchHelperCallback() { - val callback = - ItemTouchHelperCallback( - requireContext(), - swipeAction = SwipeAction.DOWNLOAD, - onSwipedCallback = { pos -> - mediaItemAdapter.notifyDataSetChanged() - getAudioUrlForDownload(mediaItemAdapter.mediaItems[pos]) - }, - ) - val itemTouchHelper = ItemTouchHelper(callback) - itemTouchHelper.attachToRecyclerView(binding.recyclerMedia) - } - private fun getAudioUrlForDownload(media: Media) { if (viewModel.isMediaSavedLocally(media)) { context?.infoToast(getString(R.string.already_in_lib)) return } - if (JobService.runningJobCount > 0) { + if (JobService.runningJobCount >= 3) { context?.waningToast(getString(R.string.please_wait_download)) return } @@ -227,16 +220,6 @@ class SearchFragment : mediaViewModel = ViewModelProvider(requireActivity())[MediaViewModel::class.java] } - private fun showInfoDialog() { - if (!viewModel.getInfoDialogStatus()) { - InfoDialog( - titleResId = R.string.how_do_download, - imageResId = R.drawable.download_info, - ).showDialog(childFragmentManager) - viewModel.setTrueInfoDialogStatus() - } - } - private fun showErrorDialog(code: String) { val errMessage = if (code == EXCEPTION.YT_EXPLODE_EXCEPTION.code) { @@ -246,4 +229,33 @@ class SearchFragment : } ErrorDialog(errMessage = errMessage).showDialog(childFragmentManager) } + + private fun showPopupMenu( + media: Media, + view: View, + ) { + val popupMenu = PopupMenu(ContextThemeWrapper(context, R.style.PopupMenuTheme), view) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + popupMenu.setForceShowIcon(true) + } + popupMenu.menuInflater.inflate(R.menu.search_menu, popupMenu.menu) + popupMenu.setOnMenuItemClickListener { menuItem -> + when (menuItem.itemId) { + R.id.download -> { + getAudioUrlForDownload(media) + true + } + + R.id.play -> { + mediaViewModel.showPLayerMenu(true) + viewModel.invokeAudioUrl(media, SearchViewModel.AudioActionType.PLAY) + true + } + + else -> false + } + } + + popupMenu.show() + } } diff --git a/app/src/main/java/com/snstudio/hyper/feature/search/SearchViewModel.kt b/app/src/main/java/com/snstudio/hyper/feature/search/SearchViewModel.kt index 81c3427..e9bc942 100644 --- a/app/src/main/java/com/snstudio/hyper/feature/search/SearchViewModel.kt +++ b/app/src/main/java/com/snstudio/hyper/feature/search/SearchViewModel.kt @@ -7,9 +7,7 @@ import com.snstudio.hyper.core.base.BaseViewModel import com.snstudio.hyper.data.local.repository.MediaRepository import com.snstudio.hyper.data.model.Media import com.snstudio.hyper.util.INVOKE -import com.snstudio.hyper.util.PrefsTag import com.snstudio.hyper.util.RECEIVED -import com.snstudio.hyper.util.SharedPreferenceManager import dagger.hilt.android.lifecycle.HiltViewModel import io.flutter.plugin.common.MethodChannel import kotlinx.coroutines.CoroutineScope @@ -24,7 +22,6 @@ class SearchViewModel constructor( private val methodChannel: MethodChannel, private val localMediaRepository: MediaRepository, - private val sharedPreferenceManager: SharedPreferenceManager, ) : BaseViewModel(methodChannel) { private val localMediaListMLiveData = MutableLiveData>() @@ -83,12 +80,6 @@ class SearchViewModel } } - fun setTrueInfoDialogStatus() { - sharedPreferenceManager.putBoolean(PrefsTag.DOWNLOAD_INFO_DIALOG_SHOW, true) - } - - fun getInfoDialogStatus(): Boolean = sharedPreferenceManager.getBoolean(PrefsTag.DOWNLOAD_INFO_DIALOG_SHOW) - fun isMediaSavedLocally(media: Media): Boolean = localMediaListMLiveData.value?.any { media.id == it.id } ?: false enum class AudioActionType { diff --git a/app/src/main/java/com/snstudio/hyper/service/DownloadJob.kt b/app/src/main/java/com/snstudio/hyper/service/DownloadJob.kt index 1c46d53..95fc907 100644 --- a/app/src/main/java/com/snstudio/hyper/service/DownloadJob.kt +++ b/app/src/main/java/com/snstudio/hyper/service/DownloadJob.kt @@ -47,7 +47,7 @@ class DownloadJob( downloadedBytes += bytesRead val progress = ((downloadedBytes.toDouble() / totalBytes) * 100).toInt() postNotification(media.title, progress) - callback.onJobProgress(progress) + callback.onJobProgress(media, progress) } } } diff --git a/app/src/main/java/com/snstudio/hyper/service/JobCompletedCallback.kt b/app/src/main/java/com/snstudio/hyper/service/JobCompletedCallback.kt index c2b6d52..ef55e28 100644 --- a/app/src/main/java/com/snstudio/hyper/service/JobCompletedCallback.kt +++ b/app/src/main/java/com/snstudio/hyper/service/JobCompletedCallback.kt @@ -14,8 +14,12 @@ interface JobCompletedCallback { * Called to report the job's progress. * * @param progress The current progress of the job as a percentage (0-100). + * @param media The media object produced or processed by the job. */ - fun onJobProgress(progress: Int) + fun onJobProgress( + media: Media, + progress: Int, + ) /** * Called when the job is completed. diff --git a/app/src/main/java/com/snstudio/hyper/shared/MediaItemAdapter.kt b/app/src/main/java/com/snstudio/hyper/shared/MediaItemAdapter.kt index a1f0013..6b56e5e 100644 --- a/app/src/main/java/com/snstudio/hyper/shared/MediaItemAdapter.kt +++ b/app/src/main/java/com/snstudio/hyper/shared/MediaItemAdapter.kt @@ -1,6 +1,7 @@ package com.snstudio.hyper.shared import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import androidx.databinding.DataBindingUtil import androidx.databinding.ViewDataBinding @@ -15,7 +16,8 @@ import com.snstudio.hyper.databinding.ItemMediaSearchBinding import com.snstudio.hyper.util.MediaItemType class MediaItemAdapter( - private val onClick: ((Media, Int) -> Unit)? = null, + private val onItemCLick: ((Media, Int) -> Unit)? = null, + private val onMenuClick: ((Media, View) -> Unit)? = null, ) : RecyclerView.Adapter() { var mediaItems: MutableList = mutableListOf() private set @@ -42,24 +44,19 @@ class MediaItemAdapter( notifyItemMoved(fromPosition, toPosition) } - fun removeItem(position: Int) { - mediaItems.removeAt(position) - notifyItemRemoved(position) - } - - fun restoreItem( - item: Media, - position: Int, - ) { // Todo - mediaItems.add(position, item) - notifyItemInserted(position) + fun removeItem(media: Media) { + mediaItems.indexOfFirst { it.id == media.id }.takeIf { it != RecyclerView.NO_POSITION } + ?.let { index -> + mediaItems.removeAt(index) + notifyItemRemoved(index) + } } override fun getItemViewType(position: Int): Int { val item = mediaItems[position] return when (item.type) { MediaItemType.LOCAL.key -> R.layout.item_media - MediaItemType.SEARCH.key -> R.layout.item_media_search + MediaItemType.REMOTE.key -> R.layout.item_media_search else -> throw RuntimeException("invalid object") } } @@ -102,16 +99,16 @@ class MediaItemAdapter( } private fun bindMedia(media: Media) { - val itemBinding = binding as ItemMediaBinding - itemBinding.root.click { - adapter.onClick?.invoke(media, absoluteAdapterPosition) + (binding as ItemMediaBinding).apply { + root.click { adapter.onItemCLick?.invoke(media, absoluteAdapterPosition) } + menu.click { adapter.onMenuClick?.invoke(media, it) } } } private fun bindMediaSearchType(media: Media) { - val itemBinding = binding as ItemMediaSearchBinding - itemBinding.root.click { - adapter.onClick?.invoke(media, absoluteAdapterPosition) + (binding as ItemMediaSearchBinding).apply { + root.click { adapter.onItemCLick?.invoke(media, absoluteAdapterPosition) } + menu.click { adapter.onMenuClick?.invoke(media, it) } } } diff --git a/app/src/main/java/com/snstudio/hyper/shared/MediaViewModel.kt b/app/src/main/java/com/snstudio/hyper/shared/MediaViewModel.kt index 1f07d61..07e69eb 100644 --- a/app/src/main/java/com/snstudio/hyper/shared/MediaViewModel.kt +++ b/app/src/main/java/com/snstudio/hyper/shared/MediaViewModel.kt @@ -6,6 +6,7 @@ import androidx.annotation.OptIn import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.viewModelScope import androidx.media3.common.MediaItem import androidx.media3.common.MediaMetadata import androidx.media3.common.Player @@ -15,6 +16,10 @@ import androidx.media3.session.SessionToken import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.MoreExecutors import com.snstudio.hyper.service.MusicPlayerService +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch class MediaViewModel(application: Application) : AndroidViewModel(application) { private lateinit var player: Player @@ -23,18 +28,17 @@ class MediaViewModel(application: Application) : AndroidViewModel(application) { private val playerMLiveData = MutableLiveData() val playerLiveData: LiveData = playerMLiveData - private val playbackStateMLiveData = MutableLiveData() - val playbackStateLiveData: LiveData = playbackStateMLiveData - private val metaDataMLiveData = MutableLiveData() val metaDataLiveData: LiveData = metaDataMLiveData - private val playerWhenReadyMLiveData = MutableLiveData() - val playerWhenReadyLiveData: LiveData = playerWhenReadyMLiveData - private val showPlayerMenuMLiveData = MutableLiveData() val showPlayerMenuLiveData: LiveData = showPlayerMenuMLiveData + private val progressMLiveData = MutableLiveData() + val progressLiveData: LiveData = progressMLiveData + + private var progressUpdateJob: Job? = null + private val playlist = mutableListOf() init { @@ -67,22 +71,55 @@ class MediaViewModel(application: Application) : AndroidViewModel(application) { playWhenReady: Boolean, reason: Int, ) { - playerWhenReadyMLiveData.postValue(playWhenReady) + if (playWhenReady) { + startProgressUpdate() + } else { + stopProgressUpdate() + } } override fun onPlaybackStateChanged(playbackState: Int) { - /* - if (playbackState == Player.STATE_READY) { - playbackStateMLiveData.postValue(Unit) - }*/ + when (playbackState) { + Player.STATE_READY -> { + startProgressUpdate() + } + + Player.STATE_ENDED, Player.STATE_IDLE -> { + stopProgressUpdate() + } + + else -> return + } } }, ) } - fun getCurrentMediaUrl(): String = player.currentMediaItem?.localConfiguration?.uri.toString() + private fun startProgressUpdate() { + progressUpdateJob?.cancel() + progressUpdateJob = + viewModelScope.launch { + while (isActive) { + updateProgress() + delay(1000) + } + } + } + + private fun stopProgressUpdate() { + progressUpdateJob?.cancel() + progressUpdateJob = null + } + + private fun updateProgress() { + val duration = player.duration + val currentPosition = player.currentPosition - fun getMediaMetaData(): MediaMetadata = player.mediaMetadata + if (duration > 0) { + val progress = ((currentPosition.toFloat() / duration.toFloat()) * 100).toInt() + progressMLiveData.postValue(progress) + } + } fun showPLayerMenu(show: Boolean) { showPlayerMenuMLiveData.postValue(show) @@ -94,8 +131,8 @@ class MediaViewModel(application: Application) : AndroidViewModel(application) { player.play() } - fun stopPlayer() { - player.stop() + fun releasePLayer() { + player.release() } fun setPlaylist( diff --git a/app/src/main/java/com/snstudio/hyper/shared/ProgressLiveData.kt b/app/src/main/java/com/snstudio/hyper/shared/ProgressLiveData.kt index 1283500..51b1a1e 100644 --- a/app/src/main/java/com/snstudio/hyper/shared/ProgressLiveData.kt +++ b/app/src/main/java/com/snstudio/hyper/shared/ProgressLiveData.kt @@ -2,6 +2,7 @@ package com.snstudio.hyper.shared import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import com.snstudio.hyper.data.model.Media object ProgressLiveData { private val mediaDownloadStateMLiveData = MutableLiveData() @@ -12,11 +13,11 @@ object ProgressLiveData { } sealed class DownloadState { - data class Started(val message: String) : DownloadState() + data class Started(val id: String, val message: String) : DownloadState() - data class InProgress(val progress: Int) : DownloadState() + data class InProgress(val media: Media, val progress: Int) : DownloadState() - data object Completed : DownloadState() + data class Completed(val id: String) : DownloadState() data object Failed : DownloadState() } diff --git a/app/src/main/java/com/snstudio/hyper/util/InfoDialog.kt b/app/src/main/java/com/snstudio/hyper/util/InfoDialog.kt index 1692644..a8dc657 100644 --- a/app/src/main/java/com/snstudio/hyper/util/InfoDialog.kt +++ b/app/src/main/java/com/snstudio/hyper/util/InfoDialog.kt @@ -1,15 +1,13 @@ package com.snstudio.hyper.util -import androidx.annotation.DrawableRes import androidx.annotation.StringRes import com.snstudio.hyper.core.base.BaseDialog import com.snstudio.hyper.core.extension.click -import com.snstudio.hyper.core.extension.loadGif import com.snstudio.hyper.databinding.DialogInfoBinding class InfoDialog( @StringRes private val titleResId: Int, - @DrawableRes private val imageResId: Int, + private val onClick: (() -> Unit)? = null, ) : BaseDialog() { override var setCancelable: Boolean = true override val dialogTag: String @@ -20,8 +18,11 @@ class InfoDialog( override fun setupViews() { with(binding) { title.setText(titleResId) - close.click { dismiss() } - image.loadGif(imageResId) + ok.click { + onClick?.invoke() + dismiss() + } + cancel.click { dismiss() } } } } diff --git a/app/src/main/java/com/snstudio/hyper/util/ItemTouchHelperCallback.kt b/app/src/main/java/com/snstudio/hyper/util/ItemTouchHelperCallback.kt index e076463..99dce0c 100644 --- a/app/src/main/java/com/snstudio/hyper/util/ItemTouchHelperCallback.kt +++ b/app/src/main/java/com/snstudio/hyper/util/ItemTouchHelperCallback.kt @@ -1,33 +1,12 @@ package com.snstudio.hyper.util -import android.content.Context -import android.graphics.Canvas -import android.graphics.drawable.ColorDrawable -import android.graphics.drawable.Drawable -import android.view.View -import androidx.core.content.ContextCompat import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView -import com.snstudio.hyper.R -import kotlin.math.abs class ItemTouchHelperCallback( - context: Context, - private val swipeAction: SwipeAction = SwipeAction.DELETE, private val onMoveCallback: ((Int, Int) -> Unit)? = null, private val onMovedCallback: (() -> Unit)? = null, - private val onSwipedCallback: ((Int) -> Unit), ) : ItemTouchHelper.Callback() { - private val deleteIcon: Drawable? = ContextCompat.getDrawable(context, R.drawable.ic_delete) - private val downloadIcon: Drawable? = ContextCompat.getDrawable(context, R.drawable.ic_download) - - private val deleteBackground = - ColorDrawable(ContextCompat.getColor(context, R.color.delete_red)) - private val downloadBackground = - ColorDrawable(ContextCompat.getColor(context, R.color.main_color)) - - private var currentActionState: Int = ItemTouchHelper.ACTION_STATE_IDLE - private var fromPosition: Int = 0 private var toPosition: Int = 0 @@ -35,14 +14,17 @@ class ItemTouchHelperCallback( return onMoveCallback != null } + override fun onSwiped( + viewHolder: RecyclerView.ViewHolder, + direction: Int, + ) {} + override fun clearView( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, ) { super.clearView(recyclerView, viewHolder) - if (currentActionState == ItemTouchHelper.ACTION_STATE_DRAG) { - onMovedCallback?.invoke() - } + onMovedCallback?.invoke() } override fun getMovementFlags( @@ -50,7 +32,7 @@ class ItemTouchHelperCallback( viewHolder: RecyclerView.ViewHolder, ): Int { val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN - val swipeFlags = ItemTouchHelper.LEFT + val swipeFlags = ItemTouchHelper.ACTION_STATE_IDLE return makeMovementFlags(dragFlags, swipeFlags) } @@ -64,71 +46,4 @@ class ItemTouchHelperCallback( onMoveCallback?.invoke(fromPosition, toPosition) return true } - - override fun onSwiped( - viewHolder: RecyclerView.ViewHolder, - direction: Int, - ) { - val position = viewHolder.absoluteAdapterPosition - onSwipedCallback.invoke(position) - } - - override fun onChildDraw( - canvas: Canvas, - recyclerView: RecyclerView, - viewHolder: RecyclerView.ViewHolder, - dX: Float, - dY: Float, - actionState: Int, - isCurrentlyActive: Boolean, - ) { - val itemView = viewHolder.itemView - currentActionState = actionState - if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { - handleSwipe(canvas, itemView, dX) - } - super.onChildDraw(canvas, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) - } - - private fun handleSwipe( - canvas: Canvas, - itemView: View, - dX: Float, - ) { - val icon: Drawable? - val background: ColorDrawable - - when (swipeAction) { - SwipeAction.DELETE -> { - icon = deleteIcon - background = deleteBackground - } - - SwipeAction.DOWNLOAD -> { - icon = downloadIcon - background = downloadBackground - } - } - - icon?.let { - if (dX < 0 && abs(dX) > 150) { - val iconMargin = (itemView.height - it.intrinsicHeight) / 2 - val iconTop = itemView.top + iconMargin - val iconBottom = iconTop + it.intrinsicHeight - val iconLeft = itemView.right - iconMargin - it.intrinsicWidth - val iconRight = itemView.right - iconMargin - - background.setBounds( - itemView.right + dX.toInt(), - itemView.top, - itemView.right, - itemView.bottom, - ) - background.draw(canvas) - - it.setBounds(iconLeft, iconTop, iconRight, iconBottom) - it.draw(canvas) - } - } - } } diff --git a/app/src/main/java/com/snstudio/hyper/util/MediaItemType.kt b/app/src/main/java/com/snstudio/hyper/util/MediaItemType.kt index 3f53ca9..2c809a6 100644 --- a/app/src/main/java/com/snstudio/hyper/util/MediaItemType.kt +++ b/app/src/main/java/com/snstudio/hyper/util/MediaItemType.kt @@ -2,5 +2,5 @@ package com.snstudio.hyper.util enum class MediaItemType(val key: Int) { LOCAL(0), - SEARCH(1), + REMOTE(1), } diff --git a/app/src/main/java/com/snstudio/hyper/util/Metods.kt b/app/src/main/java/com/snstudio/hyper/util/Metods.kt index f144077..014b3bb 100644 --- a/app/src/main/java/com/snstudio/hyper/util/Metods.kt +++ b/app/src/main/java/com/snstudio/hyper/util/Metods.kt @@ -6,12 +6,14 @@ enum class RECEIVED(val received: String) { SEARCH_RECEIVED("receiveSearchData"), NEXT_RECEIVED("receiveNextSearchData"), AUDIO_URL_RECEIVED("receiveAudioUrl"), + HIGHLIGHTS_RECEIVED("receiveHighlightsData"), } enum class INVOKE(val invoke: String) { SEARCH("search"), AUDIO_URL("getAudioUrl"), NEXT("nextPage"), + HIGHLIGHTS("highlights"), } enum class EXCEPTION(val code: String) { diff --git a/app/src/main/java/com/snstudio/hyper/util/SharedPreferenceManager.kt b/app/src/main/java/com/snstudio/hyper/util/SharedPreferenceManager.kt index ac1f6d7..2c261e0 100644 --- a/app/src/main/java/com/snstudio/hyper/util/SharedPreferenceManager.kt +++ b/app/src/main/java/com/snstudio/hyper/util/SharedPreferenceManager.kt @@ -8,8 +8,6 @@ import javax.inject.Singleton enum class PrefsTag(val tag: String) { PERMISSION_NOTIFICATION("PERMISSION_NOTIFICATION"), - DOWNLOAD_INFO_DIALOG_SHOW("DOWNLOAD_INFO_DIALOG_SHOW"), - DELETE_INFO_DIALOG_SHOW("DELETE_INFO_DIALOG_SHOW"), } @Singleton diff --git a/app/src/main/java/com/snstudio/hyper/util/SwipeAction.kt b/app/src/main/java/com/snstudio/hyper/util/SwipeAction.kt deleted file mode 100644 index ee040d7..0000000 --- a/app/src/main/java/com/snstudio/hyper/util/SwipeAction.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.snstudio.hyper.util - -enum class SwipeAction { - DELETE, - DOWNLOAD, -} diff --git a/app/src/main/res/anim/fade_in.xml b/app/src/main/res/anim/fade_in.xml new file mode 100644 index 0000000..14489c9 --- /dev/null +++ b/app/src/main/res/anim/fade_in.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/fade_out.xml b/app/src/main/res/anim/fade_out.xml new file mode 100644 index 0000000..b6a58e7 --- /dev/null +++ b/app/src/main/res/anim/fade_out.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in_left.xml b/app/src/main/res/anim/slide_in_left.xml new file mode 100644 index 0000000..592e241 --- /dev/null +++ b/app/src/main/res/anim/slide_in_left.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in_right.xml b/app/src/main/res/anim/slide_in_right.xml new file mode 100644 index 0000000..7729bdc --- /dev/null +++ b/app/src/main/res/anim/slide_in_right.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_out_left.xml b/app/src/main/res/anim/slide_out_left.xml new file mode 100644 index 0000000..970ab30 --- /dev/null +++ b/app/src/main/res/anim/slide_out_left.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_out_right.xml b/app/src/main/res/anim/slide_out_right.xml new file mode 100644 index 0000000..4344ae8 --- /dev/null +++ b/app/src/main/res/anim/slide_out_right.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/color/play_list_button_selector.xml b/app/src/main/res/color/play_list_button_selector.xml new file mode 100644 index 0000000..adf5951 --- /dev/null +++ b/app/src/main/res/color/play_list_button_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_add_music.xml b/app/src/main/res/drawable/bg_add_music.xml new file mode 100644 index 0000000..3c0cf1b --- /dev/null +++ b/app/src/main/res/drawable/bg_add_music.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/dialog_rounded.xml b/app/src/main/res/drawable/bg_dialog_rounded.xml similarity index 100% rename from app/src/main/res/drawable/dialog_rounded.xml rename to app/src/main/res/drawable/bg_dialog_rounded.xml diff --git a/app/src/main/res/drawable/bg_playlist_name.xml b/app/src/main/res/drawable/bg_playlist_name.xml new file mode 100644 index 0000000..ca4af6f --- /dev/null +++ b/app/src/main/res/drawable/bg_playlist_name.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_bg.xml b/app/src/main/res/drawable/bg_rounded.xml similarity index 100% rename from app/src/main/res/drawable/rounded_bg.xml rename to app/src/main/res/drawable/bg_rounded.xml diff --git a/app/src/main/res/drawable/rounded_info_background.xml b/app/src/main/res/drawable/bg_rounded_info.xml similarity index 81% rename from app/src/main/res/drawable/rounded_info_background.xml rename to app/src/main/res/drawable/bg_rounded_info.xml index 9501263..9ee953c 100644 --- a/app/src/main/res/drawable/rounded_info_background.xml +++ b/app/src/main/res/drawable/bg_rounded_info.xml @@ -1,6 +1,6 @@ - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/delete_info.gif b/app/src/main/res/drawable/delete_info.gif deleted file mode 100644 index 983cedef198ff8c5057420c66f8c01969a2423fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74102 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

-FBRKMM)c=ax;)VN#1w`6v^^8G?~aSaK=# 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 W*`&DH7P{HhZ<~vd01ya3_1^%ksp!c7 diff --git a/app/src/main/res/drawable/download_info.gif b/app/src/main/res/drawable/download_info.gif deleted file mode 100644 index 97dc0cdffa625e603f3b3ea279f5781325e34ec6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 115492 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

n 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 + + diff --git a/app/src/main/res/drawable/ic_fast_rewind.xml b/app/src/main/res/drawable/ic_fast_rewind.xml new file mode 100644 index 0000000..e708147 --- /dev/null +++ b/app/src/main/res/drawable/ic_fast_rewind.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_info.xml b/app/src/main/res/drawable/ic_info.xml index 5c6aa66..6c7b66c 100644 --- a/app/src/main/res/drawable/ic_info.xml +++ b/app/src/main/res/drawable/ic_info.xml @@ -5,6 +5,6 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/app/src/main/res/drawable/ic_more.xml b/app/src/main/res/drawable/ic_more.xml new file mode 100644 index 0000000..6edc754 --- /dev/null +++ b/app/src/main/res/drawable/ic_more.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_music_square.xml b/app/src/main/res/drawable/ic_music_square.xml deleted file mode 100644 index 4775a89..0000000 --- a/app/src/main/res/drawable/ic_music_square.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_pause.xml b/app/src/main/res/drawable/ic_pause.xml new file mode 100644 index 0000000..9bff452 --- /dev/null +++ b/app/src/main/res/drawable/ic_pause.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_placeholder_new.xml b/app/src/main/res/drawable/ic_placeholder_new.xml new file mode 100644 index 0000000..4fe15c7 --- /dev/null +++ b/app/src/main/res/drawable/ic_placeholder_new.xml @@ -0,0 +1,13 @@ + + + + diff --git a/app/src/main/res/drawable/ic_play.xml b/app/src/main/res/drawable/ic_play.xml index 844b3cf..5d4f47a 100644 --- a/app/src/main/res/drawable/ic_play.xml +++ b/app/src/main/res/drawable/ic_play.xml @@ -1,10 +1,9 @@ + android:fillColor="@color/text_color" + android:pathData="M8.286,3.407A1.5,1.5 0,0 0,6 4.684v14.632a1.5,1.5 0,0 0,2.286 1.277l11.888,-7.316a1.5,1.5 0,0 0,0 -2.555L8.286,3.407z" /> diff --git a/app/src/main/res/drawable/ic_play_circle.xml b/app/src/main/res/drawable/ic_play_circle.xml new file mode 100644 index 0000000..5425cc4 --- /dev/null +++ b/app/src/main/res/drawable/ic_play_circle.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_play_small.xml b/app/src/main/res/drawable/ic_play_small.xml new file mode 100644 index 0000000..1941ed6 --- /dev/null +++ b/app/src/main/res/drawable/ic_play_small.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_remove.xml b/app/src/main/res/drawable/ic_remove.xml new file mode 100644 index 0000000..8f5e305 --- /dev/null +++ b/app/src/main/res/drawable/ic_remove.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_shuffle.xml b/app/src/main/res/drawable/ic_shuffle.xml new file mode 100644 index 0000000..d1e544d --- /dev/null +++ b/app/src/main/res/drawable/ic_shuffle.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_skip_next.xml b/app/src/main/res/drawable/ic_skip_next.xml new file mode 100644 index 0000000..f4fea6b --- /dev/null +++ b/app/src/main/res/drawable/ic_skip_next.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_skip_prev.xml b/app/src/main/res/drawable/ic_skip_prev.xml new file mode 100644 index 0000000..147be50 --- /dev/null +++ b/app/src/main/res/drawable/ic_skip_prev.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/player_button_background_ripple.xml b/app/src/main/res/drawable/player_button_background_ripple.xml new file mode 100644 index 0000000..f40baf9 --- /dev/null +++ b/app/src/main/res/drawable/player_button_background_ripple.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 8d959e0..302f23e 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,78 +1,67 @@ + - - - - - - - + android:layout_height="match_parent"> + android:layout_height="match_parent"> - + app:navGraph="@navigation/navigation" + tools:ignore="FragmentTagUsage" /> - + android:visibility="gone" + app:controller_layout_id="@layout/custom_player_control_view" + app:layout_constraintBottom_toTopOf="@+id/bottomBar" + app:show_timeout="-1" /> + + + + + + - + \ No newline at end of file diff --git a/app/src/main/res/layout/custom_player_control_view.xml b/app/src/main/res/layout/custom_player_control_view.xml new file mode 100644 index 0000000..b85637e --- /dev/null +++ b/app/src/main/res/layout/custom_player_control_view.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/custom_player_full_control_view.xml b/app/src/main/res/layout/custom_player_full_control_view.xml new file mode 100644 index 0000000..6f8dd7a --- /dev/null +++ b/app/src/main/res/layout/custom_player_full_control_view.xml @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_info.xml b/app/src/main/res/layout/dialog_info.xml index 98c8c90..bc9de6f 100644 --- a/app/src/main/res/layout/dialog_info.xml +++ b/app/src/main/res/layout/dialog_info.xml @@ -5,9 +5,20 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/secondary_background_color" - android:padding="@dimen/_10sdp"> + android:padding="@dimen/_15sdp"> + + + app:layout_constraintTop_toBottomOf="@+id/image" + tools:text="@string/app_name" /> - + app:layout_constraintTop_toBottomOf="@+id/title" /> \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_music_picker.xml b/app/src/main/res/layout/dialog_music_picker.xml index 5b6f638..174b7b3 100644 --- a/app/src/main/res/layout/dialog_music_picker.xml +++ b/app/src/main/res/layout/dialog_music_picker.xml @@ -10,7 +10,7 @@ android:layout_height="wrap_content" android:layout_marginHorizontal="@dimen/_10sdp" android:layout_marginTop="16dp" - android:background="@drawable/rounded_info_background" + android:background="@drawable/bg_rounded_info" android:drawableStart="@drawable/ic_info" android:drawablePadding="@dimen/_10sdp" android:text="@string/music_already_added_info" diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 1542090..8bc632e 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -16,55 +16,67 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@color/background_color" tools:context=".feature.home.HomeFragment"> + app:titleText="@string/home" /> - - + app:layout_constraintTop_toBottomOf="@+id/highlightsTitle" + tools:listitem="@layout/item_highlights" /> - + + + app:layout_constraintTop_toBottomOf="@+id/downloadTitle" + tools:listitem="@layout/item_highlights" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_playlist_detail.xml b/app/src/main/res/layout/fragment_playlist_detail.xml index 2919589..9bf6801 100644 --- a/app/src/main/res/layout/fragment_playlist_detail.xml +++ b/app/src/main/res/layout/fragment_playlist_detail.xml @@ -1,5 +1,5 @@ - + @@ -8,57 +8,103 @@ - - - + android:fillViewport="true"> - + tools:context=".feature.playlist.PlaylistDetailFragment"> - + + - + + + + + - + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_add_music.xml b/app/src/main/res/layout/item_add_music.xml new file mode 100644 index 0000000..c794679 --- /dev/null +++ b/app/src/main/res/layout/item_add_music.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_highlights.xml b/app/src/main/res/layout/item_highlights.xml new file mode 100644 index 0000000..0746106 --- /dev/null +++ b/app/src/main/res/layout/item_highlights.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_media.xml b/app/src/main/res/layout/item_media.xml index 1b8ff1b..e67adb4 100644 --- a/app/src/main/res/layout/item_media.xml +++ b/app/src/main/res/layout/item_media.xml @@ -36,7 +36,7 @@ android:text="@{item.title}" android:textColor="@color/text_color" android:textSize="@dimen/_14ssp" - app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintEnd_toStartOf="@+id/menu" app:layout_constraintStart_toEndOf="@+id/thumbnail" app:layout_constraintTop_toTopOf="parent" tools:text="@string/app_name" /> @@ -52,10 +52,20 @@ android:text="@{LongKt.toDuration(item.duration)}" android:textColor="@color/secondary_text_color" android:textSize="@dimen/_13ssp" - app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintEnd_toStartOf="@+id/menu" app:layout_constraintStart_toEndOf="@+id/thumbnail" app:layout_constraintTop_toBottomOf="@+id/title" tools:text="@string/app_name" /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_media_search.xml b/app/src/main/res/layout/item_media_search.xml index 03b82e6..53224df 100644 --- a/app/src/main/res/layout/item_media_search.xml +++ b/app/src/main/res/layout/item_media_search.xml @@ -36,7 +36,7 @@ android:text="@{item.title}" android:textColor="@color/text_color" android:textSize="@dimen/_14ssp" - app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintEnd_toStartOf="@+id/menu" app:layout_constraintStart_toEndOf="@+id/thumbnail" app:layout_constraintTop_toTopOf="parent" tools:text="@string/app_name" /> @@ -52,10 +52,20 @@ android:text="@{LongKt.toDuration(item.duration)}" android:textColor="@color/secondary_text_color" android:textSize="@dimen/_13ssp" - app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintEnd_toStartOf="@+id/menu" app:layout_constraintStart_toEndOf="@+id/thumbnail" app:layout_constraintTop_toBottomOf="@+id/title" tools:text="@string/app_name" /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_play_list.xml b/app/src/main/res/layout/item_play_list.xml index 435f76a..fc7e953 100644 --- a/app/src/main/res/layout/item_play_list.xml +++ b/app/src/main/res/layout/item_play_list.xml @@ -6,13 +6,18 @@ android:layout_height="wrap_content" android:padding="@dimen/_10sdp"> - + app:layout_constraintTop_toTopOf="parent" + tools:text="X" /> @@ -40,9 +45,19 @@ android:text="@string/app_name" android:textColor="@color/secondary_text_color" android:textSize="@dimen/_13ssp" - app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintEnd_toStartOf="@+id/menu" app:layout_constraintStart_toEndOf="@+id/thumbnail" app:layout_constraintTop_toBottomOf="@+id/playlistName" tools:text="@string/app_name" /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_music_card.xml b/app/src/main/res/layout/layout_music_card.xml index c03d5fa..6afc834 100644 --- a/app/src/main/res/layout/layout_music_card.xml +++ b/app/src/main/res/layout/layout_music_card.xml @@ -37,7 +37,7 @@ android:layout_height="wrap_content" android:layout_marginStart="@dimen/_20sdp" android:layout_marginTop="@dimen/_20sdp" - android:background="@drawable/rounded_bg" + android:background="@drawable/bg_rounded" android:paddingHorizontal="@dimen/_5sdp" android:paddingVertical="@dimen/_2sdp" android:text="@string/song_library" @@ -56,7 +56,7 @@ android:layout_marginTop="@dimen/_3sdp" android:layout_marginEnd="@dimen/_20sdp" android:layout_marginBottom="@dimen/_20sdp" - android:background="@drawable/rounded_bg" + android:background="@drawable/bg_rounded" android:paddingHorizontal="@dimen/_5sdp" android:paddingVertical="@dimen/_2sdp" android:text="@string/song_desc" diff --git a/app/src/main/res/layout/layout_play_list_card.xml b/app/src/main/res/layout/layout_play_list_card.xml index 6ad0ccf..c8c970f 100644 --- a/app/src/main/res/layout/layout_play_list_card.xml +++ b/app/src/main/res/layout/layout_play_list_card.xml @@ -36,7 +36,7 @@ android:layout_height="wrap_content" android:layout_marginStart="@dimen/_20sdp" android:layout_marginTop="@dimen/_20sdp" - android:background="@drawable/rounded_bg" + android:background="@drawable/bg_rounded" android:paddingHorizontal="@dimen/_5sdp" android:paddingVertical="@dimen/_2sdp" android:text="@string/playlist" @@ -55,7 +55,7 @@ android:layout_marginTop="@dimen/_3sdp" android:layout_marginEnd="@dimen/_20sdp" android:layout_marginBottom="@dimen/_20sdp" - android:background="@drawable/rounded_bg" + android:background="@drawable/bg_rounded" android:paddingHorizontal="@dimen/_5sdp" android:paddingVertical="@dimen/_2sdp" android:text="@string/play_list_desc" diff --git a/app/src/main/res/menu/bottom_bar_menu.xml b/app/src/main/res/menu/bottom_bar_menu.xml new file mode 100644 index 0000000..f55a3bf --- /dev/null +++ b/app/src/main/res/menu/bottom_bar_menu.xml @@ -0,0 +1,19 @@ + +

+ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/library_menu.xml b/app/src/main/res/menu/library_menu.xml new file mode 100644 index 0000000..04d585d --- /dev/null +++ b/app/src/main/res/menu/library_menu.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/playlist_detail_menu.xml b/app/src/main/res/menu/playlist_detail_menu.xml new file mode 100644 index 0000000..6deec0f --- /dev/null +++ b/app/src/main/res/menu/playlist_detail_menu.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/playlist_menu.xml b/app/src/main/res/menu/playlist_menu.xml new file mode 100644 index 0000000..b064379 --- /dev/null +++ b/app/src/main/res/menu/playlist_menu.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/search_menu.xml b/app/src/main/res/menu/search_menu.xml new file mode 100644 index 0000000..76ca210 --- /dev/null +++ b/app/src/main/res/menu/search_menu.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/navigation.xml b/app/src/main/res/navigation/navigation.xml index b974e48..dc34fd5 100644 --- a/app/src/main/res/navigation/navigation.xml +++ b/app/src/main/res/navigation/navigation.xml @@ -13,7 +13,11 @@ + app:destination="@id/searchFragment" + app:enterAnim="@anim/slide_in_right" + app:exitAnim="@anim/slide_out_left" + app:popEnterAnim="@anim/slide_in_left" + app:popExitAnim="@anim/slide_out_right" /> + app:destination="@id/searchFragment" + app:enterAnim="@anim/slide_in_right" + app:exitAnim="@anim/slide_out_left" + app:popEnterAnim="@anim/slide_in_left" + app:popExitAnim="@anim/slide_out_right" /> @@ -50,7 +58,11 @@ + app:destination="@id/playlistDetail" + app:enterAnim="@anim/slide_in_right" + app:exitAnim="@anim/slide_out_left" + app:popEnterAnim="@anim/slide_in_left" + app:popExitAnim="@anim/slide_out_right" /> Çalma Listeleri Yeni Sürüm Mevcut Çalma Listesi Oluştur + Öne Çıkanlar + Son İndirlenler Aranıyor… İndirilen müzikleri dinleyin veya yönetin Çalma listeleri oluşturun ve yönetin Sil + Çıkar Detay Çalma listesi adı Kaydet @@ -22,7 +25,7 @@ Henüz müzik indirmediniz\n Arama ekranına gitmek için buraya dokunun Listeye eklemek için mevcut müzik yok Bu müzik zaten kütüphanenizde mevcut - Lütfen mevcut öğenin indirilmesini bekleyin + Lütfen mevcut öğelerin indirilmesini bekleyin Müzik Ara Hyper indirme servisi Hyper\'ın indirme servisi için bildirim kanalı @@ -34,12 +37,16 @@ Uygulamayı kullanmaya devam etmek için lütfen yeni sürümü indirin İptal İndir + Çal + Tümünü çal + Karıştır Tamam - İndirmek istediğiniz müziği sola kaydırarak indirmeye başlayabilirsiniz - Müziği silmek için sola kaydırın + Seçtiğiniz öğe silinecek devam etmek isityor musunuz ? Henüz bir müzik indirilmemiş Bu liste eklenebilecek tüm müzikleri içeriyor Hata ! Beklenmeyen bir hata oluştu. Daha sonra tekrar deneyin Veriler işlenirken bir hata oluştu. Lütfen uygulamanın en son sürümünü kullandığınızdan emin olun. + %1$d Şarkı - %2$s + Müzik arayın ve indirin \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 1f21030..b2ede94 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,19 +1,21 @@ - #FF000000 - #FF1E1E1E + #FF161B22 + #FF1E272E + #FF1E252C + #FF2C3A47 #FFFFFFFF #FFCCCCCC #808080 - #FF004C99 - #33004C99 - #FF66AAFF - #FF007FFF + #FF2F81F7 + #802F81F7 + #33004C99 + #FF66AAFF + #FF007FFF #33000000 #CCB00020 #FF004C99 - #FFBB86FC #FF6200EE #FF3700B3 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b68d6aa..80f813e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -12,12 +12,15 @@ Playlists New Version Available Create Playlist + Highlights + Recent Downloads Searching… Listen to or manage downloaded songs Create and manage playlists Delete + Remove Detail Playlist name Save @@ -27,7 +30,7 @@ You haven\'t downloaded any music yet\n Tap here to go to the search screen No music available to add to the list This music is already in your library - Please wait for the current item to finish downloading + Please wait for the current items to finish downloading Search music Hyper download service Notification channel for Hyper\'s download service @@ -39,13 +42,16 @@ To continue using the app, please download the new version Cancel Download + Play + Play all + Shuffle OK - You can start downloading the music you want by swiping left - Swipe left to delete music + The selected item will be deleted. Do you want to proceed ? No music has been downloaded yet This list contains all the music that can be added Error ! An unexpected error has occurred. Try again later. An error occurred while processing the data. Please make sure you are using the latest version of the application. - + %1$d Song - %2$s + Search and download music \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index b9b4302..a934493 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -13,4 +13,14 @@ @android:color/transparent + + + + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index f745179..5f0fbb5 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -15,7 +15,7 @@ @color/background_color false false - @color/background_color + @color/secondary_background_color @style/SearchAutoCompleteTextView diff --git a/explode/lib/explode.dart b/explode/lib/explode.dart index 75f6e57..2ce06cf 100644 --- a/explode/lib/explode.dart +++ b/explode/lib/explode.dart @@ -46,6 +46,24 @@ class Explode { return videoList; } + Future getHighlights(List highlights) async { + List> videoList = []; + List> futures = []; + + for (var element in highlights) { + futures.add(_explode.videos.get(element)); + } + + List