diff --git a/app/build.gradle b/app/build.gradle index 8a7ac3615..6520f57c8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,7 +14,7 @@ android { vectorDrawables.useSupportLibrary = true applicationId "code.name.monkey.retromusic" - versionCode 10556 + versionCode 10557 versionName '5.6.1' buildConfigField("String", "GOOGLE_PLAY_LICENSING_KEY", "\"${getProperty(getProperties('../public.properties'), 'GOOGLE_PLAY_LICENSE_KEY')}\"") @@ -57,6 +57,8 @@ android { abortOnError false } compileOptions { + coreLibraryDesugaringEnabled true + sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } @@ -86,7 +88,6 @@ static def getDate() { new Date().format('MMddyyyyss') } - dependencies { implementation project(':appthemehelper') implementation "androidx.gridlayout:gridlayout:1.0.0" @@ -149,6 +150,8 @@ dependencies { kapt 'com.github.bumptech.glide:compiler:4.12.0' implementation 'com.github.bumptech.glide:okhttp3-integration:4.12.0' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' + implementation 'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:1.0.0' implementation 'com.github.bosphere.android-fadingedgelayout:fadingedgelayout:1.0.0' diff --git a/app/src/debug/res/values/donottranslate.xml b/app/src/debug/res/values/donottranslate.xml index 7d3f0ee62..a67ed0a23 100644 --- a/app/src/debug/res/values/donottranslate.xml +++ b/app/src/debug/res/values/donottranslate.xml @@ -1,5 +1,7 @@ + Retro Music-Debug + true false \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/Constants.kt b/app/src/main/java/code/name/monkey/retromusic/Constants.kt index a8e96d211..3e95ef631 100644 --- a/app/src/main/java/code/name/monkey/retromusic/Constants.kt +++ b/app/src/main/java/code/name/monkey/retromusic/Constants.kt @@ -73,7 +73,7 @@ const val NOW_PLAYING_SCREEN_ID = "now_playing_screen_id" const val CAROUSEL_EFFECT = "carousel_effect" const val COLORED_NOTIFICATION = "colored_notification" const val CLASSIC_NOTIFICATION = "classic_notification" -const val GAP_LESS_PLAYBACK = "gap_less_playback" +const val GAP_LESS_PLAYBACK = "gapless_playback" const val ALBUM_ART_ON_LOCK_SCREEN = "album_art_on_lock_screen" const val BLURRED_ALBUM_ART = "blurred_album_art" const val NEW_BLUR_AMOUNT = "new_blur_amount" @@ -135,6 +135,7 @@ const val LOCK_SCREEN = "lock_screen" const val ALBUM_ARTISTS_ONLY = "album_artists_only" const val ALBUM_ARTIST = "album_artist" const val ALBUM_DETAIL_SONG_SORT_ORDER = "album_detail_song_sort_order" +const val ARTIST_DETAIL_SONG_SORT_ORDER = "artist_detail_song_sort_order" const val LYRICS_OPTIONS = "lyrics_tab_position" const val CHOOSE_EQUALIZER = "choose_equalizer" const val EQUALIZER = "equalizer" @@ -153,3 +154,4 @@ const val LAST_USED_TAB = "last_used_tab" const val WHITELIST_MUSIC = "whitelist_music" const val MATERIAL_YOU = "material_you" const val SNOWFALL = "snowfall" +const val LYRICS_TYPE = "lyrics_type" diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt index 716fef95c..e9aa2a3b3 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt @@ -62,7 +62,7 @@ class MainActivity : AbsCastActivity(), OnSharedPreferenceChangeListener { if (!hasPermissions()) { findNavController(R.id.fragment_container).navigate(R.id.permissionFragment) } - if (BuildConfig.VERSION_CODE > PreferenceUtil.lastVersion){ + if (BuildConfig.VERSION_CODE > PreferenceUtil.lastVersion && !BuildConfig.DEBUG){ NavigationUtil.gotoWhatNews(this) } } diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/CategoryInfoAdapter.java b/app/src/main/java/code/name/monkey/retromusic/adapter/CategoryInfoAdapter.java deleted file mode 100644 index 2354bb9af..000000000 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/CategoryInfoAdapter.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2019 Hemanth Savarala. - * - * Licensed under the GNU General Public License v3 - * - * This is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by - * the Free Software Foundation either version 3 of the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - */ - -package code.name.monkey.retromusic.adapter; - -import android.annotation.SuppressLint; -import android.content.res.ColorStateList; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.ItemTouchHelper; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.checkbox.MaterialCheckBox; - -import java.util.List; - -import code.name.monkey.appthemehelper.ThemeStore; -import code.name.monkey.retromusic.R; -import code.name.monkey.retromusic.model.CategoryInfo; -import code.name.monkey.retromusic.util.SwipeAndDragHelper; - -public class CategoryInfoAdapter extends RecyclerView.Adapter - implements SwipeAndDragHelper.ActionCompletionContract { - - private List categoryInfos; - private final ItemTouchHelper touchHelper; - - public CategoryInfoAdapter() { - SwipeAndDragHelper swipeAndDragHelper = new SwipeAndDragHelper(this); - touchHelper = new ItemTouchHelper(swipeAndDragHelper); - } - - public void attachToRecyclerView(RecyclerView recyclerView) { - touchHelper.attachToRecyclerView(recyclerView); - } - - @NonNull - public List getCategoryInfos() { - return categoryInfos; - } - - public void setCategoryInfos(@NonNull List categoryInfos) { - this.categoryInfos = categoryInfos; - notifyDataSetChanged(); - } - - @Override - public int getItemCount() { - return categoryInfos.size(); - } - - @SuppressLint("ClickableViewAccessibility") - @Override - public void onBindViewHolder(@NonNull CategoryInfoAdapter.ViewHolder holder, int position) { - CategoryInfo categoryInfo = categoryInfos.get(position); - - holder.checkBox.setChecked(categoryInfo.isVisible()); - holder.title.setText( - holder.title.getResources().getString(categoryInfo.getCategory().getStringRes())); - - holder.itemView.setOnClickListener( - v -> { - if (!(categoryInfo.isVisible() && isLastCheckedCategory(categoryInfo))) { - categoryInfo.setVisible(!categoryInfo.isVisible()); - holder.checkBox.setChecked(categoryInfo.isVisible()); - } else { - Toast.makeText( - holder.itemView.getContext(), - R.string.you_have_to_select_at_least_one_category, - Toast.LENGTH_SHORT) - .show(); - } - }); - - holder.dragView.setOnTouchListener( - (view, event) -> { - if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { - touchHelper.startDrag(holder); - } - return false; - }); - } - - @Override - @NonNull - public CategoryInfoAdapter.ViewHolder onCreateViewHolder( - @NonNull ViewGroup parent, int viewType) { - View view = - LayoutInflater.from(parent.getContext()) - .inflate(R.layout.preference_dialog_library_categories_listitem, parent, false); - return new ViewHolder(view); - } - - @Override - public void onViewMoved(int oldPosition, int newPosition) { - CategoryInfo categoryInfo = categoryInfos.get(oldPosition); - categoryInfos.remove(oldPosition); - categoryInfos.add(newPosition, categoryInfo); - notifyItemMoved(oldPosition, newPosition); - } - - private boolean isLastCheckedCategory(CategoryInfo categoryInfo) { - if (categoryInfo.isVisible()) { - for (CategoryInfo c : categoryInfos) { - if (c != categoryInfo && c.isVisible()) { - return false; - } - } - } - return true; - } - - static class ViewHolder extends RecyclerView.ViewHolder { - private final MaterialCheckBox checkBox; - private final View dragView; - private final TextView title; - - ViewHolder(View view) { - super(view); - checkBox = view.findViewById(R.id.checkbox); - checkBox.setButtonTintList( - ColorStateList.valueOf(ThemeStore.Companion.accentColor(checkBox.getContext()))); - title = view.findViewById(R.id.title); - dragView = view.findViewById(R.id.drag_view); - } - } -} diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/CategoryInfoAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/CategoryInfoAdapter.kt new file mode 100644 index 000000000..0347d42b7 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/CategoryInfoAdapter.kt @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2019 Hemanth Savarala. + * + * Licensed under the GNU General Public License v3 + * + * This is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by + * the Free Software Foundation either version 3 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + */ +package code.name.monkey.retromusic.adapter + +import android.annotation.SuppressLint +import android.content.res.ColorStateList +import android.view.LayoutInflater +import android.view.MotionEvent +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.RecyclerView +import code.name.monkey.appthemehelper.ThemeStore.Companion.accentColor +import code.name.monkey.retromusic.R +import code.name.monkey.retromusic.databinding.PreferenceDialogLibraryCategoriesListitemBinding +import code.name.monkey.retromusic.model.CategoryInfo +import code.name.monkey.retromusic.util.PreferenceUtil +import code.name.monkey.retromusic.util.SwipeAndDragHelper +import code.name.monkey.retromusic.util.SwipeAndDragHelper.ActionCompletionContract + +class CategoryInfoAdapter : RecyclerView.Adapter(), + ActionCompletionContract { + var categoryInfos: MutableList = + PreferenceUtil.libraryCategory.toMutableList() + @SuppressLint("NotifyDataSetChanged") + set(value) { + field = value + notifyDataSetChanged() + } + private val touchHelper: ItemTouchHelper + fun attachToRecyclerView(recyclerView: RecyclerView?) { + touchHelper.attachToRecyclerView(recyclerView) + } + + override fun getItemCount(): Int { + return categoryInfos.size + } + + @SuppressLint("ClickableViewAccessibility") + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val categoryInfo = categoryInfos[position] + holder.binding.checkbox.isChecked = categoryInfo.visible + holder.binding.title.text = + holder.binding.title.resources.getString(categoryInfo.category.stringRes) + holder.itemView.setOnClickListener { + if (!(categoryInfo.visible && isLastCheckedCategory(categoryInfo))) { + categoryInfo.visible = !categoryInfo.visible + holder.binding.checkbox.isChecked = categoryInfo.visible + } else { + Toast.makeText( + holder.itemView.context, + R.string.you_have_to_select_at_least_one_category, + Toast.LENGTH_SHORT + ) + .show() + } + } + holder.binding.dragView.setOnTouchListener { _: View?, event: MotionEvent -> + if (event.actionMasked == MotionEvent.ACTION_DOWN) { + touchHelper.startDrag(holder) + } + false + } + } + + override fun onCreateViewHolder( + parent: ViewGroup, viewType: Int + ): ViewHolder { + return ViewHolder( + PreferenceDialogLibraryCategoriesListitemBinding.inflate( + LayoutInflater.from( + parent.context + ), parent, false + ) + ) + } + + override fun onViewMoved(oldPosition: Int, newPosition: Int) { + val categoryInfo = categoryInfos[oldPosition] + categoryInfos.removeAt(oldPosition) + categoryInfos.add(newPosition, categoryInfo) + notifyItemMoved(oldPosition, newPosition) + } + + private fun isLastCheckedCategory(categoryInfo: CategoryInfo): Boolean { + if (categoryInfo.visible) { + for (c in categoryInfos) { + if (c !== categoryInfo && c.visible) { + return false + } + } + } + return true + } + + class ViewHolder(val binding: PreferenceDialogLibraryCategoriesListitemBinding) : + RecyclerView.ViewHolder(binding.root) { + + init { + binding.checkbox.buttonTintList = + ColorStateList.valueOf(accentColor(binding.checkbox.context)) + } + } + + init { + val swipeAndDragHelper = SwipeAndDragHelper(this) + touchHelper = ItemTouchHelper(swipeAndDragHelper) + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt index ea4e6e25e..383c19e26 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt @@ -14,6 +14,7 @@ */ package code.name.monkey.retromusic.adapter +import android.annotation.SuppressLint import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -21,7 +22,7 @@ import android.view.ViewOutlineProvider import androidx.fragment.app.FragmentActivity import androidx.recyclerview.widget.RecyclerView import code.name.monkey.retromusic.R -import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder +import code.name.monkey.retromusic.databinding.ItemGenreBinding import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.RetroGlideExtension import code.name.monkey.retromusic.glide.RetroMusicColoredTarget @@ -38,7 +39,6 @@ import java.util.* class GenreAdapter( private val activity: FragmentActivity, var dataSet: List, - private val mItemLayoutRes: Int, private val listener: IGenreClickListener ) : RecyclerView.Adapter() { @@ -51,13 +51,13 @@ class GenreAdapter( } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - return ViewHolder(LayoutInflater.from(activity).inflate(mItemLayoutRes, parent, false)) + return ViewHolder(ItemGenreBinding.inflate(LayoutInflater.from(activity), parent, false)) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val genre = dataSet[position] - holder.title?.text = genre.name - holder.text?.text = String.format( + holder.binding.title.text = genre.name + holder.binding.text.text = String.format( Locale.getDefault(), "%d %s", genre.songCount, @@ -72,33 +72,39 @@ class GenreAdapter( .asBitmapPalette() .load(RetroGlideExtension.getSongModel(genreSong)) .songCoverOptions(genreSong) - .into(object : RetroMusicColoredTarget(holder.image!!) { + .into(object : RetroMusicColoredTarget(holder.binding.image) { override fun onColorReady(colors: MediaNotificationProcessor) { setColors(holder, colors) } }) // Just for a bit of shadow around image - holder.image?.outlineProvider = ViewOutlineProvider.BOUNDS + holder.binding.image.outlineProvider = ViewOutlineProvider.BOUNDS } private fun setColors(holder: ViewHolder, color: MediaNotificationProcessor) { - holder.imageContainerCard?.setCardBackgroundColor(color.backgroundColor) - holder.title?.setTextColor(color.primaryTextColor) - holder.text?.setTextColor(color.secondaryTextColor) + holder.binding.imageContainerCard.setCardBackgroundColor(color.backgroundColor) + holder.binding.title.setTextColor(color.primaryTextColor) + holder.binding.text.setTextColor(color.secondaryTextColor) } override fun getItemCount(): Int { return dataSet.size } + @SuppressLint("NotifyDataSetChanged") fun swapDataSet(list: List) { dataSet = list notifyDataSetChanged() } - inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) { + inner class ViewHolder(val binding: ItemGenreBinding) : RecyclerView.ViewHolder(binding.root), + View.OnClickListener { override fun onClick(v: View?) { listener.onClickGenre(dataSet[layoutPosition], itemView) } + + init { + itemView.setOnClickListener(this) + } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt index 3e84aee43..35a2b2f88 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt @@ -248,7 +248,6 @@ class HomeAdapter( val genreAdapter = GenreAdapter( activity, home.arrayList as List, - R.layout.item_grid_genre, this@HomeAdapter ) recyclerView.apply { diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/backup/BackupAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/backup/BackupAdapter.kt index 81b2bbf83..adfcecf1b 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/backup/BackupAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/backup/BackupAdapter.kt @@ -1,15 +1,14 @@ package code.name.monkey.retromusic.adapter.backup +import android.annotation.SuppressLint import android.view.LayoutInflater import android.view.MenuItem -import android.view.View import android.view.ViewGroup -import android.widget.TextView -import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.PopupMenu import androidx.fragment.app.FragmentActivity import androidx.recyclerview.widget.RecyclerView import code.name.monkey.retromusic.R +import code.name.monkey.retromusic.databinding.ItemListBackupBinding import java.io.File @@ -21,27 +20,27 @@ class BackupAdapter( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { return ViewHolder( - LayoutInflater.from(activity).inflate(R.layout.item_list_card, parent, false) + ItemListBackupBinding.inflate(LayoutInflater.from(activity), parent, false) ) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { - holder.title.text = dataSet[position].nameWithoutExtension + holder.binding.title.text = dataSet[position].nameWithoutExtension } override fun getItemCount(): Int = dataSet.size + @SuppressLint("NotifyDataSetChanged") fun swapDataset(dataSet: List) { this.dataSet = ArrayList(dataSet) notifyDataSetChanged() } - inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - val title: TextView = itemView.findViewById(R.id.title) - val menu: AppCompatImageView = itemView.findViewById(R.id.menu) + inner class ViewHolder(val binding: ItemListBackupBinding) : + RecyclerView.ViewHolder(binding.root) { init { - menu.setOnClickListener { view -> + binding.menu.setOnClickListener { view -> val popupMenu = PopupMenu(activity, view) popupMenu.inflate(R.menu.menu_backup) popupMenu.setOnMenuItemClickListener { menuItem -> diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt index e7b771054..3c0d6d480 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt @@ -16,6 +16,7 @@ package code.name.monkey.retromusic.fragments import android.animation.ValueAnimator import android.widget.Toast +import androidx.core.animation.doOnEnd import androidx.lifecycle.* import code.name.monkey.retromusic.* import code.name.monkey.retromusic.db.* @@ -255,11 +256,13 @@ class LibraryViewModel( } repository.insertSongs(songEntities) } else { - val playListId = createPlaylist(PlaylistEntity(playlistName = playlist.name)) - val songEntities = playlist.getSongs().map { - it.toSongEntity(playListId) + if (playlist != Playlist.empty){ + val playListId = createPlaylist(PlaylistEntity(playlistName = playlist.name)) + val songEntities = playlist.getSongs().map { + it.toSongEntity(playListId) + } + repository.insertSongs(songEntities) } - repository.insertSongs(songEntities) } forceReload(Playlists) } @@ -365,7 +368,7 @@ class LibraryViewModel( Toast.LENGTH_SHORT ).show() if (songs.isNotEmpty()) { - Toast.makeText( + Toast.makeText( App.getContext(), "Adding songs to $playlistName", Toast.LENGTH_SHORT @@ -378,17 +381,21 @@ class LibraryViewModel( } fun setFabMargin(bottomMargin: Int) { + println("Bottom Margin $bottomMargin") val currentValue = DensityUtil.dip2px(App.getContext(), 16F) + bottomMargin - if (currentValue != fabMargin.value) { - ValueAnimator.ofInt(fabMargin.value!!, currentValue).apply { - addUpdateListener { - fabMargin.postValue( - it.animatedValue as Int - ) - } - start() + ValueAnimator.ofInt(fabMargin.value!!, currentValue).apply { + addUpdateListener { + fabMargin.postValue( + (it.animatedValue as Int).also { bottomMarginAnimated -> + println("Bottom Margin Animated $bottomMarginAnimated") + } + ) } + doOnEnd { + fabMargin.postValue(currentValue) + } + start() } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/AbsArtistDetailsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/AbsArtistDetailsFragment.kt index 39c092e69..750e79133 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/AbsArtistDetailsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/AbsArtistDetailsFragment.kt @@ -5,11 +5,9 @@ import android.content.Intent import android.graphics.Color import android.os.Bundle import android.text.Spanned -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View +import android.view.* import androidx.activity.addCallback +import androidx.appcompat.widget.PopupMenu import androidx.core.os.bundleOf import androidx.core.text.HtmlCompat import androidx.core.view.ViewCompat @@ -32,6 +30,7 @@ import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.RetroGlideExtension import code.name.monkey.retromusic.glide.SingleColorTarget import code.name.monkey.retromusic.helper.MusicPlayerRemote +import code.name.monkey.retromusic.helper.SortOrder import code.name.monkey.retromusic.interfaces.IAlbumClickListener import code.name.monkey.retromusic.interfaces.ICabCallback import code.name.monkey.retromusic.interfaces.ICabHolder @@ -39,10 +38,7 @@ import code.name.monkey.retromusic.model.Artist import code.name.monkey.retromusic.network.Result import code.name.monkey.retromusic.network.model.LastFmArtist import code.name.monkey.retromusic.repository.RealRepository -import code.name.monkey.retromusic.util.CustomArtistImageUtil -import code.name.monkey.retromusic.util.MusicUtil -import code.name.monkey.retromusic.util.RetroColorUtil -import code.name.monkey.retromusic.util.RetroUtil +import code.name.monkey.retromusic.util.* import com.afollestad.materialcab.attached.AttachedCab import com.afollestad.materialcab.attached.destroy import com.afollestad.materialcab.attached.isActive @@ -71,6 +67,9 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm private var lang: String? = null private var biography: Spanned? = null + private val savedSongSortOrder: String + get() = PreferenceUtil.artistDetailSongSortOrder + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) sharedElementEnterTransition = MaterialContainerTransform().apply { @@ -101,7 +100,7 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm setupRecyclerView() binding.fragmentArtistContent.playAction.apply { - setOnClickListener { MusicPlayerRemote.openQueue(artist.songs, 0, true) } + setOnClickListener { MusicPlayerRemote.openQueue(artist.sortedSongs, 0, true) } } binding.fragmentArtistContent.shuffleAction.apply { setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(artist.songs, true) } @@ -121,6 +120,7 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm requireActivity().onBackPressed() } } + setupSongSortButton() binding.appBarLayout?.statusBarForeground = MaterialShapeDrawable.createWithElevationOverlay(requireContext()) } @@ -168,7 +168,7 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm ) binding.fragmentArtistContent.songTitle.text = songText binding.fragmentArtistContent.albumTitle.text = albumText - songAdapter.swapDataSet(artist.songs.sortedBy { it.trackNumber }) + songAdapter.swapDataSet(artist.sortedSongs) albumAdapter.swapDataSet(artist.albums) } @@ -289,6 +289,53 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm return true } + private fun setupSongSortButton() { + binding.fragmentArtistContent.songSortOrder.setOnClickListener { + PopupMenu(requireContext(), binding.fragmentArtistContent.songSortOrder).apply { + inflate(R.menu.menu_artist_song_sort_order) + setUpSortOrderMenu(menu) + setOnMenuItemClickListener { menuItem -> + val sortOrder = when (menuItem.itemId) { + R.id.action_sort_order_title -> SortOrder.ArtistSongSortOrder.SONG_A_Z + R.id.action_sort_order_title_desc -> SortOrder.ArtistSongSortOrder.SONG_Z_A + R.id.action_sort_order_album -> SortOrder.ArtistSongSortOrder.SONG_ALBUM + R.id.action_sort_order_year -> SortOrder.ArtistSongSortOrder.SONG_YEAR + R.id.action_sort_order_song_duration -> SortOrder.ArtistSongSortOrder.SONG_DURATION + else -> { + throw IllegalArgumentException("invalid ${menuItem.title}") + } + } + menuItem.isChecked = true + setSaveSortOrder(sortOrder) + return@setOnMenuItemClickListener true + } + show() + } + } + } + + private fun setSaveSortOrder(sortOrder: String) { + PreferenceUtil.artistDetailSongSortOrder = sortOrder + songAdapter.swapDataSet(artist.sortedSongs) + } + + private fun setUpSortOrderMenu(sortOrder: Menu) { + when (savedSongSortOrder) { + SortOrder.ArtistSongSortOrder.SONG_A_Z -> sortOrder.findItem(R.id.action_sort_order_title).isChecked = true + SortOrder.ArtistSongSortOrder.SONG_Z_A -> sortOrder.findItem(R.id.action_sort_order_title_desc).isChecked = true + SortOrder.ArtistSongSortOrder.SONG_ALBUM -> + sortOrder.findItem(R.id.action_sort_order_album).isChecked = true + SortOrder.ArtistSongSortOrder.SONG_YEAR -> + sortOrder.findItem(R.id.action_sort_order_year).isChecked = true + SortOrder.ArtistSongSortOrder.SONG_DURATION -> + sortOrder.findItem(R.id.action_sort_order_song_duration).isChecked = true + else-> { + throw IllegalArgumentException("invalid $savedSongSortOrder") + } + } + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/backup/BackupFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/backup/BackupFragment.kt index 170ae9387..efa11bcd6 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/backup/BackupFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/backup/BackupFragment.kt @@ -17,6 +17,8 @@ import androidx.recyclerview.widget.RecyclerView import code.name.monkey.retromusic.R import code.name.monkey.retromusic.adapter.backup.BackupAdapter import code.name.monkey.retromusic.databinding.FragmentBackupBinding +import code.name.monkey.retromusic.extensions.accentColor +import code.name.monkey.retromusic.extensions.accentOutlineColor import code.name.monkey.retromusic.helper.BackupHelper import code.name.monkey.retromusic.helper.sanitize import code.name.monkey.retromusic.util.BackupUtil @@ -45,7 +47,7 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC else backupAdapter?.swapDataset(listOf()) } - backupViewModel.loadBackups() + backupViewModel.loadBackups(requireContext()) val openFilePicker = registerForActivityResult(ActivityResultContracts.OpenDocument()) { lifecycleScope.launch(Dispatchers.IO) { it?.let { @@ -55,6 +57,8 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC } } } + binding.createBackup.accentOutlineColor() + binding.restoreBackup.accentColor() binding.createBackup.setOnClickListener { showCreateBackupDialog() } @@ -91,11 +95,11 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC MaterialDialog(requireContext()).show { cornerRadius(res = R.dimen.m3_card_corner_radius) title(res = R.string.action_rename) - input(prefill = System.currentTimeMillis().toString()) { _, text -> + input(prefill = BackupHelper.getTimeStamp()) { _, text -> // Text submitted with the action button lifecycleScope.launch { BackupHelper.createBackup(requireContext(), text.sanitize()) - backupViewModel.loadBackups() + backupViewModel.loadBackups(requireContext()) } } positiveButton(android.R.string.ok) @@ -125,7 +129,7 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC Toast.LENGTH_SHORT ).show() } - backupViewModel.loadBackups() + backupViewModel.loadBackups(requireContext()) return true } R.id.action_share -> { @@ -143,10 +147,10 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC input(prefill = file.nameWithoutExtension) { _, text -> // Text submitted with the action button val renamedFile = - File(file.parent + File.separator + text + BackupHelper.APPEND_EXTENSION) + File(file.parent, "$text${BackupHelper.APPEND_EXTENSION}") if (!renamedFile.exists()) { file.renameTo(renamedFile) - backupViewModel.loadBackups() + backupViewModel.loadBackups(requireContext()) } else { Toast.makeText( requireContext(), diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/backup/BackupViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/backup/BackupViewModel.kt index f482cc915..87e3f05dd 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/backup/BackupViewModel.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/backup/BackupViewModel.kt @@ -1,6 +1,7 @@ package code.name.monkey.retromusic.fragments.backup import android.app.Activity +import android.content.Context import android.content.Intent import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData @@ -19,8 +20,8 @@ class BackupViewModel : ViewModel() { private val backupsMutableLiveData = MutableLiveData>() val backupsLiveData: LiveData> = backupsMutableLiveData - fun loadBackups() { - File(BackupHelper.backupRootPath).listFiles { _, name -> + fun loadBackups(context: Context) { + BackupHelper.getBackupRoot(context).listFiles { _, name -> return@listFiles name.endsWith(BackupHelper.BACKUP_EXTENSION) }?.toList()?.let { backupsMutableLiveData.value = it @@ -29,13 +30,16 @@ class BackupViewModel : ViewModel() { suspend fun restoreBackup(activity: Activity, inputStream: InputStream?, contents: List) { BackupHelper.restoreBackup(activity, inputStream, contents) - withContext(Dispatchers.Main) { - val intent = Intent( - activity, - MainActivity::class.java - ) - activity.startActivity(intent) - exitProcess(0) + if (contents.contains(BackupContent.SETTINGS) or contents.contains(BackupContent.CUSTOM_ARTIST_IMAGES)) { + // We have to restart App when Preferences i.e. Settings or Artist Images are to be restored + withContext(Dispatchers.Main) { + val intent = Intent( + activity, + MainActivity::class.java + ) + activity.startActivity(intent) + exitProcess(0) + } } } } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/backup/RestoreActivity.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/backup/RestoreActivity.kt index feab240ea..af92c73e2 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/backup/RestoreActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/backup/RestoreActivity.kt @@ -3,9 +3,11 @@ package code.name.monkey.retromusic.fragments.backup import android.net.Uri import android.os.Bundle import android.provider.MediaStore +import android.view.ViewGroup import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate +import androidx.core.view.updateLayoutParams import androidx.lifecycle.lifecycleScope import code.name.monkey.retromusic.databinding.ActivityRestoreBinding import code.name.monkey.retromusic.helper.BackupContent @@ -27,6 +29,7 @@ class RestoreActivity : AppCompatActivity() { super.onCreate(savedInstanceState) binding = ActivityRestoreBinding.inflate(layoutInflater) setContentView(binding.root) + setWidth() val backupUri = intent?.data binding.backupName.setText(getFileName(backupUri)) binding.cancelButton.setOnClickListener { @@ -35,7 +38,6 @@ class RestoreActivity : AppCompatActivity() { binding.restoreButton.setOnClickListener { val backupContents = mutableListOf() if (binding.checkSettings.isChecked) backupContents.add(SETTINGS) - if (binding.checkQueue.isChecked) backupContents.add(QUEUE) if (binding.checkDatabases.isChecked) backupContents.add(PLAYLISTS) if (binding.checkArtistImages.isChecked) backupContents.add(CUSTOM_ARTIST_IMAGES) if (binding.checkUserImages.isChecked) backupContents.add(USER_IMAGES) @@ -67,17 +69,13 @@ class RestoreActivity : AppCompatActivity() { return uri.lastPathSegment } "content" -> { - val proj = arrayOf(MediaStore.Images.Media.TITLE) + val proj = arrayOf(MediaStore.Files.FileColumns.DISPLAY_NAME) contentResolver.query( - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { - MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL) - } else { - MediaStore.Audio.Media.EXTERNAL_CONTENT_URI - }, proj, null, null, null + uri, proj, null, null, null )?.use { cursor -> if (cursor.count != 0) { val columnIndex: Int = - cursor.getColumnIndexOrThrow(MediaStore.Images.Media.TITLE) + cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME) cursor.moveToFirst() return cursor.getString(columnIndex) } @@ -86,4 +84,9 @@ class RestoreActivity : AppCompatActivity() { } return "Backup" } + + private fun setWidth() { + val width = resources.displayMetrics.widthPixels * 0.8 + binding.root.updateLayoutParams { this.width = width.toInt() } + } } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt index 403d5d6a8..bbbc8dd2a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt @@ -39,6 +39,7 @@ import androidx.lifecycle.lifecycleScope import androidx.navigation.findNavController import androidx.navigation.navOptions import androidx.viewpager.widget.ViewPager +import code.name.monkey.appthemehelper.util.VersionUtils import code.name.monkey.retromusic.EXTRA_ALBUM_ID import code.name.monkey.retromusic.EXTRA_ARTIST_ID import code.name.monkey.retromusic.R @@ -237,7 +238,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme val isFavorite: Boolean = libraryViewModel.isSongFavorite(MusicPlayerRemote.currentSong.id) withContext(Main) { - val icon = if (animate) { + val icon = if (animate && VersionUtils.hasMarshmallow()) { if (isFavorite) R.drawable.avd_favorite else R.drawable.avd_unfavorite } else { if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsRecyclerViewFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsRecyclerViewFragment.kt index 06fac152b..979e3646a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsRecyclerViewFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsRecyclerViewFragment.kt @@ -164,7 +164,7 @@ abstract class AbsRecyclerViewFragment, LM : Recycle if (itemCount > 0 && MusicPlayerRemote.playingQueue.isNotEmpty()) { binding.recyclerView.updatePadding(bottom = dip(R.dimen.mini_player_height_expanded)) } else { - binding.recyclerView.updatePadding(bottom = dip(R.dimen.mini_player_height)) + binding.recyclerView.updatePadding(bottom = dip(R.dimen.bottom_nav_height)) } } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/genres/GenresFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/genres/GenresFragment.kt index 603717767..a1b6cdb63 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/genres/GenresFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/genres/GenresFragment.kt @@ -62,7 +62,7 @@ GenresFragment : AbsRecyclerViewFragment(), override fun createAdapter(): GenreAdapter { val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet - return GenreAdapter(requireActivity(), dataSet, R.layout.item_genre, this) + return GenreAdapter(requireActivity(), dataSet, this) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/other/UserInfoFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/other/UserInfoFragment.kt index a1d749fd6..16cc7268f 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/other/UserInfoFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/other/UserInfoFragment.kt @@ -29,6 +29,7 @@ import android.widget.Toast import androidx.core.view.doOnPreDraw import androidx.core.view.updateLayoutParams import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import code.name.monkey.retromusic.Constants.USER_BANNER import code.name.monkey.retromusic.Constants.USER_PROFILE @@ -50,7 +51,6 @@ import com.bumptech.glide.request.target.Target import com.github.dhaval2404.imagepicker.ImagePicker import com.github.dhaval2404.imagepicker.constant.ImageProvider import com.google.android.material.transition.MaterialContainerTransform -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -202,15 +202,15 @@ class UserInfoFragment : Fragment() { } private fun saveImage(bitmap: Bitmap, fileName: String) { - CoroutineScope(Dispatchers.IO).launch { + lifecycleScope.launch(Dispatchers.IO) { val appDir = requireContext().filesDir val file = File(appDir, fileName) var successful = false runCatching { - val os = BufferedOutputStream(FileOutputStream(file)) - successful = ImageUtil.resizeBitmap(bitmap, 2048) - .compress(Bitmap.CompressFormat.WEBP, 100, os) - withContext(Dispatchers.IO) { os.close() } + BufferedOutputStream(FileOutputStream(file)).use { + successful = ImageUtil.resizeBitmap(bitmap, 2048) + .compress(Bitmap.CompressFormat.WEBP, 100, it) + } }.onFailure { it.printStackTrace() } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/PlayerAlbumCoverFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/PlayerAlbumCoverFragment.kt index 13fa1e28d..14ffa31a2 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/PlayerAlbumCoverFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/PlayerAlbumCoverFragment.kt @@ -14,17 +14,19 @@ */ package code.name.monkey.retromusic.fragments.player +import android.animation.ObjectAnimator import android.annotation.SuppressLint import android.content.SharedPreferences import android.graphics.Color import android.os.Bundle import android.view.View -import androidx.core.view.isInvisible +import androidx.core.animation.doOnEnd import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import androidx.preference.PreferenceManager import androidx.viewpager.widget.ViewPager import code.name.monkey.appthemehelper.util.MaterialValueHelper +import code.name.monkey.retromusic.LYRICS_TYPE import code.name.monkey.retromusic.R import code.name.monkey.retromusic.SHOW_LYRICS import code.name.monkey.retromusic.adapter.album.AlbumCoverPagerAdapter @@ -34,7 +36,6 @@ import code.name.monkey.retromusic.extensions.isColorLight import code.name.monkey.retromusic.extensions.surfaceColor import code.name.monkey.retromusic.fragments.NowPlayingScreen.* import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment -import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.base.goToLyrics import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper @@ -43,6 +44,7 @@ import code.name.monkey.retromusic.model.lyrics.Lyrics import code.name.monkey.retromusic.transform.CarousalPagerTransformer import code.name.monkey.retromusic.transform.ParallaxPagerTransformer import code.name.monkey.retromusic.util.LyricUtil +import code.name.monkey.retromusic.util.LyricsType import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.color.MediaNotificationProcessor import kotlinx.coroutines.Dispatchers @@ -201,6 +203,8 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe showLyrics(false) progressViewUpdateHelper?.stop() } + } else if (key == LYRICS_TYPE) { + maybeInitLyrics() } } @@ -223,8 +227,21 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe } private fun showLyrics(visible: Boolean) { - lrcView.isVisible = visible - viewPager.isInvisible = visible + binding.coverLyrics.isVisible = false + binding.lyricsView.isVisible = false + binding.viewPager.isVisible = true + val lyrics: View = if (PreferenceUtil.lyricsType == LyricsType.REPLACE_LYRICS) { + ObjectAnimator.ofFloat(viewPager, View.ALPHA, if (visible) 0F else 1F).start() + lrcView + } else { + binding.coverLyrics + } + ObjectAnimator.ofFloat(lyrics, View.ALPHA, if (visible) 1F else 0F).apply { + doOnEnd { + lyrics.isVisible = visible + } + start() + } } private fun maybeInitLyrics() { @@ -232,9 +249,9 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe // Don't show lyrics container for below conditions if (lyricViewNpsList.contains(nps) && PreferenceUtil.showLyrics) { showLyrics(true) - progressViewUpdateHelper?.start() - lrcView.animate().alpha(1f).duration = - AbsPlayerFragment.VISIBILITY_ANIM_DURATION + if (PreferenceUtil.lyricsType == LyricsType.REPLACE_LYRICS) { + progressViewUpdateHelper?.start() + } } else { showLyrics(false) progressViewUpdateHelper?.stop() diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/color/ColorFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/color/ColorFragment.kt index d37d475e2..c76d5b456 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/color/ColorFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/color/ColorFragment.kt @@ -16,6 +16,7 @@ package code.name.monkey.retromusic.fragments.player.color import android.animation.ValueAnimator import android.os.Bundle +import android.os.Handler import android.view.View import androidx.appcompat.widget.Toolbar import androidx.core.animation.doOnEnd @@ -60,11 +61,13 @@ class ColorFragment : AbsPlayerFragment(R.layout.fragment_color_player) { _binding?.root?.setBackgroundColor(color.backgroundColor) } animator.start() - ToolbarContentTintHelper.colorizeToolbar( - binding.playerToolbar, - color.secondaryTextColor, - requireActivity() - ) + Handler().post { + ToolbarContentTintHelper.colorizeToolbar( + binding.playerToolbar, + color.secondaryTextColor, + requireActivity() + ) + } } override fun onFavoriteToggled() { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt index 24098816e..c7f690b30 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt @@ -30,6 +30,7 @@ import android.widget.SeekBar import androidx.appcompat.widget.PopupMenu import androidx.lifecycle.lifecycleScope import code.name.monkey.appthemehelper.util.ColorUtil +import code.name.monkey.appthemehelper.util.VersionUtils import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.FragmentFullPlayerControlsBinding import code.name.monkey.retromusic.db.PlaylistEntity @@ -320,7 +321,7 @@ class FullPlaybackControlsFragment : val isFavorite: Boolean = libraryViewModel.isSongFavorite(MusicPlayerRemote.currentSong.id) withContext(Dispatchers.Main) { - val icon = if (animate) { + val icon = if (animate && VersionUtils.hasMarshmallow()) { if (isFavorite) R.drawable.avd_favorite else R.drawable.avd_unfavorite } else { if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt index c9a2bc778..03e42079d 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt @@ -35,6 +35,7 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import code.name.monkey.appthemehelper.util.ColorUtil +import code.name.monkey.appthemehelper.util.VersionUtils import code.name.monkey.retromusic.R import code.name.monkey.retromusic.RetroBottomSheetBehavior import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter @@ -89,8 +90,8 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play binding.playerQueueSheet.updatePadding( top = (slideOffset * binding.statusBarLayout.statusBar.height).toInt() ) - binding.recyclerView.updatePadding( - top = ((1 - slideOffset) * navBarHeight).toInt() + binding.container.updatePadding( + bottom = ((1 - slideOffset) * navBarHeight).toInt() ) } @@ -158,9 +159,9 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play } ViewCompat.setOnApplyWindowInsetsListener( (binding.container) - ) { _: View, insets: WindowInsetsCompat -> + ) { v: View, insets: WindowInsetsCompat -> navBarHeight = insets.safeGetBottomInsets() - binding.recyclerView.updatePadding(top = navBarHeight) + v.updatePadding(bottom = navBarHeight) insets } binding.playbackControlsFragment.root.drawAboveSystemBars() @@ -282,7 +283,7 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play val isFavorite: Boolean = libraryViewModel.isSongFavorite(MusicPlayerRemote.currentSong.id) withContext(Dispatchers.Main) { - val icon = if (animate) { + val icon = if (animate && VersionUtils.hasMarshmallow()) { if (isFavorite) R.drawable.avd_favorite else R.drawable.avd_unfavorite } else { if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border @@ -453,7 +454,7 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play private fun updateLabel() { (MusicPlayerRemote.playingQueue.size - 1).apply { if (this == (MusicPlayerRemote.position)) { - binding.nextSong.text = "Last song" + binding.nextSong.text = context?.resources?.getString(R.string.last_song) } else { val title = MusicPlayerRemote.playingQueue[MusicPlayerRemote.position + 1].title binding.nextSong.text = title @@ -473,7 +474,11 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play oldBottom: Int ) { val panel = getQueuePanel() - panel.peekHeight = binding.container.height + navBarHeight + if (panel.state == STATE_COLLAPSED) { + panel.peekHeight = binding.container.height + } else if (panel.state == STATE_EXPANDED) { + panel.peekHeight = binding.container.height + navBarHeight + } } private fun setupRecyclerView() { diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/BackupHelper.kt b/app/src/main/java/code/name/monkey/retromusic/helper/BackupHelper.kt index 3b1e1cde2..4b786bb33 100644 --- a/app/src/main/java/code/name/monkey/retromusic/helper/BackupHelper.kt +++ b/app/src/main/java/code/name/monkey/retromusic/helper/BackupHelper.kt @@ -2,39 +2,49 @@ package code.name.monkey.retromusic.helper import android.content.Context import android.os.Environment -import android.util.Log import android.widget.Toast -import androidx.core.content.edit -import androidx.preference.PreferenceManager import code.name.monkey.retromusic.App import code.name.monkey.retromusic.BuildConfig +import code.name.monkey.retromusic.db.PlaylistEntity +import code.name.monkey.retromusic.db.toSongEntity import code.name.monkey.retromusic.helper.BackupContent.* +import code.name.monkey.retromusic.model.Song +import code.name.monkey.retromusic.repository.Repository +import code.name.monkey.retromusic.repository.SongRepository import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject import java.io.* +import java.text.SimpleDateFormat +import java.util.* import java.util.zip.ZipEntry import java.util.zip.ZipInputStream import java.util.zip.ZipOutputStream -object BackupHelper { +object BackupHelper : KoinComponent { + private val repository by inject() + private val songRepository by inject() + suspend fun createBackup(context: Context, name: String) { val backupFile = - File(backupRootPath + File.separator + name + APPEND_EXTENSION) + File(getBackupRoot(context), name + APPEND_EXTENSION) if (backupFile.parentFile?.exists() != true) { backupFile.parentFile?.mkdirs() } val zipItems = mutableListOf() - zipItems.addAll(getDatabaseZipItems(context)) + zipItems.addAll(getPlaylistZipItems(context)) zipItems.addAll(getSettingsZipItems(context)) getUserImageZipItems(context)?.let { zipItems.addAll(it) } zipItems.addAll(getCustomArtistZipItems(context)) - zipItems.addAll(getQueueZipItems(context)) zipAll(zipItems, backupFile) + // Clean Cache Playlist Directory + File(context.filesDir, PLAYLISTS_PATH).deleteRecursively() } private suspend fun zipAll(zipItems: List, backupFile: File) = withContext(Dispatchers.IO) { - kotlin.runCatching { + runCatching { ZipOutputStream(BufferedOutputStream(FileOutputStream(backupFile))).use { out -> for (zipItem in zipItems) { FileInputStream(zipItem.filePath).use { fi -> @@ -51,7 +61,6 @@ object BackupHelper { Toast.makeText(App.getContext(), "Couldn't create backup", Toast.LENGTH_SHORT) .show() } - throw Exception(it) }.onSuccess { withContext(Dispatchers.Main) { Toast.makeText( @@ -62,34 +71,39 @@ object BackupHelper { .show() } } - } - private fun getDatabaseZipItems(context: Context): List { - return context.databaseList().filter { - it.endsWith(".db") && it != queueDatabase - }.map { - ZipItem(context.getDatabasePath(it).absolutePath, "$DATABASES_PATH${File.separator}$it") + private suspend fun getPlaylistZipItems(context: Context): List { + val playlistZipItems = mutableListOf() + // Cache Playlist files in App storage + val playlistFolder = File(context.filesDir, PLAYLISTS_PATH) + if (!playlistFolder.exists()) { + playlistFolder.mkdirs() } - } - - private fun getQueueZipItems(context: Context): List { - Log.d("RetroMusic", context.getDatabasePath(queueDatabase).absolutePath) - return listOf( - ZipItem( - context.getDatabasePath(queueDatabase).absolutePath, - "$QUEUE_PATH${File.separator}$queueDatabase" - ) - ) + for (playlist in repository.fetchPlaylistWithSongs()) { + runCatching { + M3UWriter.writeIO(playlistFolder, playlist) + }.onSuccess { playlistFile -> + if (playlistFile.exists()) { + playlistZipItems.add( + ZipItem( + playlistFile.absolutePath, + PLAYLISTS_PATH.child(playlistFile.name) + ) + ) + } + } + } + return playlistZipItems } private fun getSettingsZipItems(context: Context): List { - val sharedPrefPath = context.filesDir.parentFile?.absolutePath + "/shared_prefs/" + val sharedPrefPath = File(context.filesDir.parentFile, "shared_prefs") return listOf( "${BuildConfig.APPLICATION_ID}_preferences.xml", // App settings pref path "$THEME_PREFS_KEY_DEFAULT.xml" // appthemehelper pref path ).map { - ZipItem(sharedPrefPath + it, "$SETTINGS_PATH${File.separator}$it") + ZipItem(File(sharedPrefPath, it).absolutePath, SETTINGS_PATH.child(it)) } } @@ -97,35 +111,33 @@ object BackupHelper { return context.filesDir.listFiles { _, name -> name.endsWith(".jpg") }?.map { - ZipItem(it.absolutePath, "$IMAGES_PATH${File.separator}${it.name}") + ZipItem(it.absolutePath, IMAGES_PATH.child(it.name)) } } private fun getCustomArtistZipItems(context: Context): List { val zipItemList = mutableListOf() - val sharedPrefPath = context.filesDir.parentFile?.absolutePath + "/shared_prefs/" + val sharedPrefPath = File(context.filesDir.parentFile, "shared_prefs") zipItemList.addAll( File(context.filesDir, "custom_artist_images") .listFiles()?.map { ZipItem( it.absolutePath, - "$CUSTOM_ARTISTS_PATH${File.separator}custom_artist_images${File.separator}${it.name}" + CUSTOM_ARTISTS_PATH.child("custom_artist_images").child(it.name) ) }?.toList() ?: listOf() ) - File(sharedPrefPath + File.separator + "custom_artist_image.xml").let { + File(sharedPrefPath, "custom_artist_image.xml").let { if (it.exists()) { zipItemList.add( ZipItem( it.absolutePath, - "$CUSTOM_ARTISTS_PATH${File.separator}prefs${File.separator}custom_artist_image.xml" + CUSTOM_ARTISTS_PATH.child("prefs").child("custom_artist_image.xml") ) ) } } - - return zipItemList } @@ -138,23 +150,19 @@ object BackupHelper { ZipInputStream(inputStream).use { var entry = it.nextEntry while (entry != null) { - if (entry.isDatabaseEntry() && contents.contains(PLAYLISTS)) { - restoreDatabase(context, it, entry) + if (entry.isPlaylistEntry() && contents.contains(PLAYLISTS)) { + restorePlaylists(it, entry) } else if (entry.isPreferenceEntry() && contents.contains(SETTINGS)) { restorePreferences(context, it, entry) } else if (entry.isImageEntry() && contents.contains(USER_IMAGES)) { restoreImages(context, it, entry) - - } else if (entry.isCustomArtistImageEntry() && contents.contains( - CUSTOM_ARTIST_IMAGES - ) - ) { - restoreCustomArtistImages(context, it, entry) - restoreCustomArtistPrefs(context, it, entry) - } else if (entry.isQueueEntry() && contents.contains(QUEUE)) { - restoreQueueDatabase(context, it, entry) + } else if (entry.isCustomArtistEntry() && contents.contains(CUSTOM_ARTIST_IMAGES)) { + if (entry.isCustomArtistPrefEntry()) { + restoreCustomArtistPrefs(context, it, entry) + } else if (entry.isCustomArtistImageEntry()) { + restoreCustomArtistImages(context, it, entry) + } } - entry = it.nextEntry } } @@ -165,14 +173,11 @@ object BackupHelper { } private fun restoreImages(context: Context, zipIn: ZipInputStream, zipEntry: ZipEntry) { - val filePath = - context.filesDir.path + File.separator + zipEntry.getFileName() - BufferedOutputStream(FileOutputStream(filePath)).use { bos -> - val bytesIn = ByteArray(DEFAULT_BUFFER_SIZE) - var read: Int - while (zipIn.read(bytesIn).also { read = it } != -1) { - bos.write(bytesIn, 0, read) - } + val file = File( + context.filesDir.path, zipEntry.getFileName() + ) + BufferedOutputStream(FileOutputStream(file)).use { bos -> + zipIn.copyTo(bos) } } @@ -184,39 +189,38 @@ object BackupHelper { file.delete() } BufferedOutputStream(FileOutputStream(file)).use { bos -> - val bytesIn = ByteArray(DEFAULT_BUFFER_SIZE) - var read: Int - while (zipIn.read(bytesIn).also { read = it } != -1) { - bos.write(bytesIn, 0, read) - } + zipIn.copyTo(bos) } } - private fun restoreDatabase(context: Context, zipIn: ZipInputStream, zipEntry: ZipEntry) { - val filePath = - context.filesDir.parent!! + File.separator + DATABASES_PATH + File.separator + zipEntry.getFileName() - BufferedOutputStream(FileOutputStream(filePath)).use { bos -> - val bytesIn = ByteArray(DEFAULT_BUFFER_SIZE) - var read: Int - while (zipIn.read(bytesIn).also { read = it } != -1) { - bos.write(bytesIn, 0, read) - } - } - } + private suspend fun restorePlaylists( + zipIn: ZipInputStream, + zipEntry: ZipEntry + ) { + val playlistName = zipEntry.getFileName().substringBeforeLast(".") + val songs = mutableListOf() - private fun restoreQueueDatabase(context: Context, zipIn: ZipInputStream, zipEntry: ZipEntry) { - PreferenceManager.getDefaultSharedPreferences(context).edit(commit = true) { - putInt("POSITION", 0) - } - val filePath = - context.filesDir.parent!! + File.separator + DATABASES_PATH + File.separator + zipEntry.getFileName() - BufferedOutputStream(FileOutputStream(filePath)).use { bos -> - val bytesIn = ByteArray(DEFAULT_BUFFER_SIZE) - var read: Int - while (zipIn.read(bytesIn).also { read = it } != -1) { - bos.write(bytesIn, 0, read) + // Get songs from m3u playlist files + zipIn.bufferedReader().lineSequence().forEach { line -> + if (line.startsWith(File.separator)) { + if (File(line).exists()) { + songs.addAll(songRepository.songsByFilePath(line)) + } } } + val playlistEntity = repository.checkPlaylistExists(playlistName).firstOrNull() + if (playlistEntity != null) { + val songEntities = songs.map { + it.toSongEntity(playlistEntity.playListId) + } + repository.insertSongs(songEntities) + } else { + val playListId = repository.createPlaylist(PlaylistEntity(playlistName = playlistName)) + val songEntities = songs.map { + it.toSongEntity(playListId) + } + repository.insertSongs(songEntities) + } } private fun restoreCustomArtistImages( @@ -237,11 +241,7 @@ object BackupHelper { ) ) ).use { bos -> - val bytesIn = ByteArray(DEFAULT_BUFFER_SIZE) - var read: Int - while (zipIn.read(bytesIn).also { read = it } != -1) { - bos.write(bytesIn, 0, read) - } + zipIn.copyTo(bos) } } @@ -250,32 +250,30 @@ object BackupHelper { zipIn: ZipInputStream, zipEntry: ZipEntry ) { - val filePath = - context.filesDir.parentFile?.absolutePath + "/shared_prefs/" + zipEntry.getFileName() - BufferedOutputStream(FileOutputStream(filePath)).use { bos -> - val bytesIn = ByteArray(DEFAULT_BUFFER_SIZE) - var read: Int - while (zipIn.read(bytesIn).also { read = it } != -1) { - bos.write(bytesIn, 0, read) - } + val file = + File(context.filesDir.parentFile, "shared_prefs".child(zipEntry.getFileName())) + BufferedOutputStream(FileOutputStream(file)).use { bos -> + zipIn.copyTo(bos) } } - val backupRootPath = - Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) - .toString() + "/RetroMusic/Backups/" + fun getBackupRoot(context: Context): File { + return File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), + "RetroMusic/Backups" + ) + } + const val BACKUP_EXTENSION = "rmbak" const val APPEND_EXTENSION = ".$BACKUP_EXTENSION" - private const val DATABASES_PATH = "databases" - private const val QUEUE_PATH = "queue" + private const val PLAYLISTS_PATH = "Playlists" private const val SETTINGS_PATH = "prefs" private const val IMAGES_PATH = "userImages" private const val CUSTOM_ARTISTS_PATH = "artistImages" private const val THEME_PREFS_KEY_DEFAULT = "[[kabouzeid_app-theme-helper]]" - private const val queueDatabase = "music_playback_state.db" - private fun ZipEntry.isDatabaseEntry(): Boolean { - return name.startsWith(DATABASES_PATH) + private fun ZipEntry.isPlaylistEntry(): Boolean { + return name.startsWith(PLAYLISTS_PATH) } private fun ZipEntry.isPreferenceEntry(): Boolean { @@ -286,6 +284,10 @@ object BackupHelper { return name.startsWith(IMAGES_PATH) } + private fun ZipEntry.isCustomArtistEntry(): Boolean { + return name.startsWith(CUSTOM_ARTISTS_PATH) + } + private fun ZipEntry.isCustomArtistImageEntry(): Boolean { return name.startsWith(CUSTOM_ARTISTS_PATH) && name.contains("custom_artist_images") } @@ -294,12 +296,12 @@ object BackupHelper { return name.startsWith(CUSTOM_ARTISTS_PATH) && name.contains("prefs") } - private fun ZipEntry.isQueueEntry(): Boolean { - return name.startsWith(QUEUE_PATH) + private fun ZipEntry.getFileName(): String { + return name.substring(name.lastIndexOf(File.separator) + 1) } - private fun ZipEntry.getFileName(): String { - return name.substring(name.lastIndexOf(File.separator)) + fun getTimeStamp(): String { + return SimpleDateFormat("dd-MMM yyyy HHmmss", Locale.getDefault()).format(Date()) } } @@ -318,10 +320,13 @@ fun CharSequence.sanitize(): String { .replace("&", "_") } +fun String.child(child: String): String { + return this + File.separator + child +} + enum class BackupContent { SETTINGS, USER_IMAGES, CUSTOM_ARTIST_IMAGES, - PLAYLISTS, - QUEUE + PLAYLISTS } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/MusicPlayerRemote.kt b/app/src/main/java/code/name/monkey/retromusic/helper/MusicPlayerRemote.kt index 6bd424963..4101f89ef 100644 --- a/app/src/main/java/code/name/monkey/retromusic/helper/MusicPlayerRemote.kt +++ b/app/src/main/java/code/name/monkey/retromusic/helper/MusicPlayerRemote.kt @@ -459,7 +459,7 @@ object MusicPlayerRemote : KoinComponent { songFile = File(path) } if (songFile == null && uri.path != null) { - songFile = File(uri.path) + songFile = File(uri.path!!) } if (songFile != null) { songs = songRepository.songsByFilePath(songFile.absolutePath) diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/SortOrder.kt b/app/src/main/java/code/name/monkey/retromusic/helper/SortOrder.kt index 0771b2936..b77e39d09 100644 --- a/app/src/main/java/code/name/monkey/retromusic/helper/SortOrder.kt +++ b/app/src/main/java/code/name/monkey/retromusic/helper/SortOrder.kt @@ -134,7 +134,7 @@ class SortOrder { companion object { /* Artist song sort order A-Z */ - private const val SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER + const val SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER /* Artist song sort order Z-A */ const val SONG_Z_A = "$SONG_A_Z DESC" diff --git a/app/src/main/java/code/name/monkey/retromusic/lyrics/CoverLrcView.kt b/app/src/main/java/code/name/monkey/retromusic/lyrics/CoverLrcView.kt index 7f74fc8b3..d5d506339 100644 --- a/app/src/main/java/code/name/monkey/retromusic/lyrics/CoverLrcView.kt +++ b/app/src/main/java/code/name/monkey/retromusic/lyrics/CoverLrcView.kt @@ -167,12 +167,12 @@ class CoverLrcView @JvmOverloads constructor( isShowTimeline = false removeCallbacks(hideTimelineRunnable) mCurrentLine = centerLine - invalidate() - return true - } else { - callOnClick() + animateCurrentTextSize() return true } + } else { + callOnClick() + return true } return super.onSingleTapConfirmed(e) } @@ -458,6 +458,7 @@ class CoverLrcView @JvmOverloads constructor( mCurrentLine = line if (!isShowTimeline) { smoothScrollTo(line) + animateCurrentTextSize() } else { invalidate() } @@ -536,6 +537,18 @@ class CoverLrcView @JvmOverloads constructor( canvas.restore() } + fun animateCurrentTextSize() { + val currentTextSize = mCurrentTextSize + ValueAnimator.ofFloat(mNormalTextSize, currentTextSize).apply { + addUpdateListener { + mCurrentTextSize = it.animatedValue as Float + invalidate() + } + duration = 300L + start() + } + } + @SuppressLint("ClickableViewAccessibility") override fun onTouchEvent(event: MotionEvent): Boolean { if (event.action == MotionEvent.ACTION_UP @@ -613,7 +626,7 @@ class CoverLrcView @JvmOverloads constructor( private fun adjustCenter() { smoothScrollTo(centerLine, ADJUST_DURATION) } - /** 滚动到某一行 */ + /** 滚动到某一行 */ private fun smoothScrollTo(line: Int, duration: Long = mAnimationDuration) { val offset = getOffset(line) diff --git a/app/src/main/java/code/name/monkey/retromusic/model/Artist.kt b/app/src/main/java/code/name/monkey/retromusic/model/Artist.kt index faf133986..c9d7e42dc 100644 --- a/app/src/main/java/code/name/monkey/retromusic/model/Artist.kt +++ b/app/src/main/java/code/name/monkey/retromusic/model/Artist.kt @@ -14,7 +14,9 @@ package code.name.monkey.retromusic.model +import code.name.monkey.retromusic.helper.SortOrder import code.name.monkey.retromusic.util.MusicUtil +import code.name.monkey.retromusic.util.PreferenceUtil data class Artist( val id: Long, @@ -29,7 +31,7 @@ data class Artist( name = artistName } - var name: String = "" + var name: String = "-" get() { val name = if (isAlbumArtist) getAlbumArtistName() else getArtistName() @@ -57,6 +59,39 @@ data class Artist( val songs: List get() = albums.flatMap { it.songs } + val sortedSongs: List + get() = songs.sortedWith( + when (PreferenceUtil.artistDetailSongSortOrder) { + SortOrder.ArtistSongSortOrder.SONG_A_Z -> { o1, o2 -> + o1.title.compareTo( + o2.title + ) + } + SortOrder.ArtistSongSortOrder.SONG_Z_A -> { o1, o2 -> + o2.title.compareTo( + o1.title + ) + } + SortOrder.ArtistSongSortOrder.SONG_ALBUM -> { o1, o2 -> + o1.albumName.compareTo( + o2.albumName + ) + } + SortOrder.ArtistSongSortOrder.SONG_YEAR -> { o1, o2 -> + o2.year.compareTo( + o1.year + ) + } + SortOrder.ArtistSongSortOrder.SONG_DURATION -> { o1, o2 -> + o1.duration.compareTo( + o2.duration + ) + } + else -> { + throw IllegalArgumentException("invalid ${PreferenceUtil.artistDetailSongSortOrder}") + } + }) + fun safeGetFirstAlbum(): Album { return albums.firstOrNull() ?: Album.empty } diff --git a/app/src/main/java/code/name/monkey/retromusic/preferences/LibraryPreference.kt b/app/src/main/java/code/name/monkey/retromusic/preferences/LibraryPreference.kt index 6f28e1ce1..9b6e19e11 100644 --- a/app/src/main/java/code/name/monkey/retromusic/preferences/LibraryPreference.kt +++ b/app/src/main/java/code/name/monkey/retromusic/preferences/LibraryPreference.kt @@ -55,7 +55,6 @@ class LibraryPreferenceDialog : DialogFragment() { .inflate(R.layout.preference_dialog_library_categories, null) val categoryAdapter = CategoryInfoAdapter() - categoryAdapter.categoryInfos = PreferenceUtil.libraryCategory val recyclerView = view.findViewById(R.id.recycler_view) recyclerView.layoutManager = LinearLayoutManager(activity) recyclerView.adapter = categoryAdapter diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.java b/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.java index f8e89f111..a861543d3 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.java +++ b/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.java @@ -31,7 +31,9 @@ import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.service.playback.Playback; import code.name.monkey.retromusic.util.PreferenceUtil; -/** @author Andrew Neal, Karim Abou Zeid (kabouzeid) */ +/** + * @author Andrew Neal, Karim Abou Zeid (kabouzeid) + */ public class MultiPlayer implements Playback, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener { public static final String TAG = MultiPlayer.class.getSimpleName(); @@ -40,12 +42,14 @@ public class MultiPlayer private MediaPlayer mNextMediaPlayer; private final Context context; - @Nullable - private Playback.PlaybackCallbacks callbacks; + @Nullable + private Playback.PlaybackCallbacks callbacks; private boolean mIsInitialized = false; - /** Constructor of MultiPlayer */ + /** + * Constructor of MultiPlayer + */ MultiPlayer(final Context context) { this.context = context; mCurrentMediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK); @@ -67,7 +71,7 @@ public class MultiPlayer /** * @param player The {@link MediaPlayer} to use - * @param path The path of the file, or the http/rtsp URL of the stream you want to play + * @param path The path of the file, or the http/rtsp URL of the stream you want to play * @return True if the player has been prepared and is ready to play, false otherwise */ private boolean setDataSourceImpl(@NonNull final MediaPlayer player, @NonNull final String path) { @@ -155,13 +159,17 @@ public class MultiPlayer this.callbacks = callbacks; } - /** @return True if the player is ready to go, false otherwise */ + /** + * @return True if the player is ready to go, false otherwise + */ @Override public boolean isInitialized() { return mIsInitialized; } - /** Starts or resumes playback. */ + /** + * Starts or resumes playback. + */ @Override public boolean start() { try { @@ -172,14 +180,18 @@ public class MultiPlayer } } - /** Resets the MediaPlayer to its uninitialized state. */ + /** + * Resets the MediaPlayer to its uninitialized state. + */ @Override public void stop() { mCurrentMediaPlayer.reset(); mIsInitialized = false; } - /** Releases resources associated with this MediaPlayer object. */ + /** + * Releases resources associated with this MediaPlayer object. + */ @Override public void release() { stop(); @@ -189,7 +201,9 @@ public class MultiPlayer } } - /** Pauses playback. Call start() to resume. */ + /** + * Pauses playback. Call start() to resume. + */ @Override public boolean pause() { try { @@ -200,7 +214,9 @@ public class MultiPlayer } } - /** Checks whether the MultiPlayer is playing. */ + /** + * Checks whether the MultiPlayer is playing. + */ @Override public boolean isPlaying() { return mIsInitialized && mCurrentMediaPlayer.isPlaying(); @@ -291,7 +307,9 @@ public class MultiPlayer return mCurrentMediaPlayer.getAudioSessionId(); } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public boolean onError(final MediaPlayer mp, final int what, final int extra) { mIsInitialized = false; @@ -308,7 +326,9 @@ public class MultiPlayer return false; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public void onCompletion(final MediaPlayer mp) { if (mp.equals(mCurrentMediaPlayer) && mNextMediaPlayer != null) { @@ -323,6 +343,7 @@ public class MultiPlayer } } - @Override - public void setCrossFadeDuration(int duration) { } + @Override + public void setCrossFadeDuration(int duration) { + } } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java index 6399e8fdd..d6add80cc 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java +++ b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java @@ -431,9 +431,7 @@ public class MusicService extends MediaBrowserServiceCompat registerReceiver(lockScreenReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF)); setSessionToken(mediaSession.getSessionToken()); - if (VersionUtils.INSTANCE.hasMarshmallow()) { - notificationManager = getSystemService(NotificationManager.class); - } + notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); initNotification(); mediaStoreObserver = new MediaStoreObserver(this, playerHandler); diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt index 6aca8cde7..f310bb9cc 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt +++ b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt @@ -130,6 +130,13 @@ object PreferenceUtil { ) set(value) = sharedPreferences.edit { putString(ALBUM_DETAIL_SONG_SORT_ORDER, value) } + var artistDetailSongSortOrder + get() = sharedPreferences.getStringOrDefault( + ARTIST_DETAIL_SONG_SORT_ORDER, + ArtistSongSortOrder.SONG_A_Z + ) + set(value) = sharedPreferences.edit { putString(ARTIST_DETAIL_SONG_SORT_ORDER, value) } + var songSortOrder get() = sharedPreferences.getStringOrDefault( SONG_SORT_ORDER, @@ -660,4 +667,14 @@ object PreferenceUtil { val isSnowFalling get() = sharedPreferences.getBoolean(SNOWFALL, false) + + val lyricsType: LyricsType + get() = if (sharedPreferences.getString(LYRICS_TYPE, "0") == "0") { + LyricsType.REPLACE_LYRICS + } else { + LyricsType.OVER_LYRICS + } } +enum class LyricsType { + REPLACE_LYRICS, OVER_LYRICS +} \ No newline at end of file diff --git a/app/src/main/res/drawable-xxxhdpi/np_adaptive.webp b/app/src/main/res/drawable-xxxhdpi/np_adaptive.webp index b4c80dc7b..5cfb7997f 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_adaptive.webp and b/app/src/main/res/drawable-xxxhdpi/np_adaptive.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_blur.webp b/app/src/main/res/drawable-xxxhdpi/np_blur.webp index 3fe7e2017..7f859bf0f 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_blur.webp and b/app/src/main/res/drawable-xxxhdpi/np_blur.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_blur_card.webp b/app/src/main/res/drawable-xxxhdpi/np_blur_card.webp index 67d26de4e..885da0a94 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_blur_card.webp and b/app/src/main/res/drawable-xxxhdpi/np_blur_card.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_card.webp b/app/src/main/res/drawable-xxxhdpi/np_card.webp index 5a8f0a178..5f340374b 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_card.webp and b/app/src/main/res/drawable-xxxhdpi/np_card.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_circle.webp b/app/src/main/res/drawable-xxxhdpi/np_circle.webp index 5028d1b47..0988d3c6d 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_circle.webp and b/app/src/main/res/drawable-xxxhdpi/np_circle.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_classic.webp b/app/src/main/res/drawable-xxxhdpi/np_classic.webp index 78800c796..505ff6417 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_classic.webp and b/app/src/main/res/drawable-xxxhdpi/np_classic.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_color.webp b/app/src/main/res/drawable-xxxhdpi/np_color.webp index ec34d1fa4..5ec91cfc2 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_color.webp and b/app/src/main/res/drawable-xxxhdpi/np_color.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_fit.webp b/app/src/main/res/drawable-xxxhdpi/np_fit.webp index b5ed505dc..944a55926 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_fit.webp and b/app/src/main/res/drawable-xxxhdpi/np_fit.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_flat.webp b/app/src/main/res/drawable-xxxhdpi/np_flat.webp index e81cbcb36..10386e52c 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_flat.webp and b/app/src/main/res/drawable-xxxhdpi/np_flat.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_full.webp b/app/src/main/res/drawable-xxxhdpi/np_full.webp index b9d58a336..ae8cb1a51 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_full.webp and b/app/src/main/res/drawable-xxxhdpi/np_full.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_gradient.webp b/app/src/main/res/drawable-xxxhdpi/np_gradient.webp index 70f634fdb..5dc269570 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_gradient.webp and b/app/src/main/res/drawable-xxxhdpi/np_gradient.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_material.webp b/app/src/main/res/drawable-xxxhdpi/np_material.webp index e6ae21f29..d12a40ae9 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_material.webp and b/app/src/main/res/drawable-xxxhdpi/np_material.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_minimalistic_circle.webp b/app/src/main/res/drawable-xxxhdpi/np_minimalistic_circle.webp index bedbff790..039d35850 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_minimalistic_circle.webp and b/app/src/main/res/drawable-xxxhdpi/np_minimalistic_circle.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_normal.webp b/app/src/main/res/drawable-xxxhdpi/np_normal.webp index f54fadc78..99f607d2b 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_normal.webp and b/app/src/main/res/drawable-xxxhdpi/np_normal.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_peak.webp b/app/src/main/res/drawable-xxxhdpi/np_peak.webp index 80586e83e..eb4333e67 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_peak.webp and b/app/src/main/res/drawable-xxxhdpi/np_peak.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_plain.webp b/app/src/main/res/drawable-xxxhdpi/np_plain.webp index cbc8de8ef..861329431 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_plain.webp and b/app/src/main/res/drawable-xxxhdpi/np_plain.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_simple.webp b/app/src/main/res/drawable-xxxhdpi/np_simple.webp index 2bab76da0..e906822f0 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_simple.webp and b/app/src/main/res/drawable-xxxhdpi/np_simple.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/np_tiny.webp b/app/src/main/res/drawable-xxxhdpi/np_tiny.webp index 2374fccaa..98eaa2eaf 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/np_tiny.webp and b/app/src/main/res/drawable-xxxhdpi/np_tiny.webp differ diff --git a/app/src/main/res/layout-land/activity_drive_mode.xml b/app/src/main/res/layout-land/activity_drive_mode.xml index 6a7fcc8cb..b3806a5b2 100644 --- a/app/src/main/res/layout-land/activity_drive_mode.xml +++ b/app/src/main/res/layout-land/activity_drive_mode.xml @@ -181,6 +181,7 @@ android:layout_height="wrap_content" android:layout_weight="8" android:maxHeight="3dp" + android:paddingVertical="@dimen/seekbar_padding" android:progressDrawable="@drawable/color_progress_seek" android:progressTint="@color/md_white_1000" android:splitTrack="false" diff --git a/app/src/main/res/layout-land/fragment_circle_player.xml b/app/src/main/res/layout-land/fragment_circle_player.xml index cff4fcf3c..bfe771c6a 100644 --- a/app/src/main/res/layout-land/fragment_circle_player.xml +++ b/app/src/main/res/layout-land/fragment_circle_player.xml @@ -181,6 +181,7 @@ android:id="@+id/progressSlider" android:layout_width="0dp" android:layout_height="wrap_content" + android:paddingVertical="@dimen/seekbar_padding" app:layout_constraintBottom_toTopOf="@id/songInfo" app:layout_constraintEnd_toStartOf="@id/songTotalTime" app:layout_constraintStart_toEndOf="@id/songCurrentProgress" diff --git a/app/src/main/res/layout-land/fragment_player.xml b/app/src/main/res/layout-land/fragment_player.xml index 29c98c625..7b3931a8d 100755 --- a/app/src/main/res/layout-land/fragment_player.xml +++ b/app/src/main/res/layout-land/fragment_player.xml @@ -5,7 +5,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" - android:focusable="true"> + android:focusable="true" + android:background="?attr/colorSurface"> - - + android:text="@string/playlists" /> diff --git a/app/src/main/res/layout/fragment_adaptive_player_playback_controls.xml b/app/src/main/res/layout/fragment_adaptive_player_playback_controls.xml index 0938629a5..76b3ad3a5 100644 --- a/app/src/main/res/layout/fragment_adaptive_player_playback_controls.xml +++ b/app/src/main/res/layout/fragment_adaptive_player_playback_controls.xml @@ -27,6 +27,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:maxHeight="2dp" + android:paddingVertical="@dimen/seekbar_padding" android:progressDrawable="@drawable/color_progress_seek" app:layout_constraintEnd_toStartOf="@id/songTotalTime" app:layout_constraintStart_toEndOf="@id/songCurrentProgress" diff --git a/app/src/main/res/layout/fragment_artist_content.xml b/app/src/main/res/layout/fragment_artist_content.xml index 6c3fb06d9..e727ed704 100644 --- a/app/src/main/res/layout/fragment_artist_content.xml +++ b/app/src/main/res/layout/fragment_artist_content.xml @@ -1,5 +1,5 @@ - + app:layout_constraintTop_toBottomOf="@id/albumRecyclerView"/> + + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_blur_player_playback_controls.xml b/app/src/main/res/layout/fragment_blur_player_playback_controls.xml index 775858d14..b17263933 100644 --- a/app/src/main/res/layout/fragment_blur_player_playback_controls.xml +++ b/app/src/main/res/layout/fragment_blur_player_playback_controls.xml @@ -41,6 +41,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:maxHeight="2dp" + android:paddingVertical="@dimen/seekbar_padding" android:progressDrawable="@drawable/color_progress_seek" android:splitTrack="false" app:layout_constraintEnd_toStartOf="@id/songTotalTime" diff --git a/app/src/main/res/layout/fragment_card_blur_player_playback_controls.xml b/app/src/main/res/layout/fragment_card_blur_player_playback_controls.xml index c823c9f3e..719c6dbd3 100644 --- a/app/src/main/res/layout/fragment_card_blur_player_playback_controls.xml +++ b/app/src/main/res/layout/fragment_card_blur_player_playback_controls.xml @@ -53,6 +53,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:maxHeight="2dp" + android:paddingVertical="@dimen/seekbar_padding" android:paddingStart="20dp" android:paddingEnd="20dp" android:progressDrawable="@drawable/color_progress_seek" diff --git a/app/src/main/res/layout/fragment_card_player_playback_controls.xml b/app/src/main/res/layout/fragment_card_player_playback_controls.xml index 070149f99..6c019c1dc 100644 --- a/app/src/main/res/layout/fragment_card_player_playback_controls.xml +++ b/app/src/main/res/layout/fragment_card_player_playback_controls.xml @@ -28,10 +28,11 @@ + android:layout_weight="1" + android:paddingVertical="@dimen/seekbar_padding" /> diff --git a/app/src/main/res/layout/fragment_color_player_playback_controls.xml b/app/src/main/res/layout/fragment_color_player_playback_controls.xml index c2a580b88..207b52bf6 100644 --- a/app/src/main/res/layout/fragment_color_player_playback_controls.xml +++ b/app/src/main/res/layout/fragment_color_player_playback_controls.xml @@ -28,6 +28,7 @@ android:layout_height="wrap_content" android:layout_marginTop="8dp" android:maxHeight="2dp" + android:paddingVertical="@dimen/seekbar_padding" android:progressDrawable="@drawable/color_progress_seek" app:layout_constraintEnd_toStartOf="@id/songTotalTime" app:layout_constraintStart_toEndOf="@id/songCurrentProgress" diff --git a/app/src/main/res/layout/fragment_fit_playback_controls.xml b/app/src/main/res/layout/fragment_fit_playback_controls.xml index 982c5945b..888a68f01 100644 --- a/app/src/main/res/layout/fragment_fit_playback_controls.xml +++ b/app/src/main/res/layout/fragment_fit_playback_controls.xml @@ -37,6 +37,7 @@ style="@style/MusicProgressSlider" android:layout_width="0dp" android:layout_height="match_parent" + android:paddingVertical="@dimen/seekbar_padding" app:layout_constraintEnd_toStartOf="@id/songTotalTime" app:layout_constraintStart_toEndOf="@id/songCurrentProgress" tools:ignore="RtlHardcoded,UnusedAttribute" /> diff --git a/app/src/main/res/layout/fragment_flat_player_playback_controls.xml b/app/src/main/res/layout/fragment_flat_player_playback_controls.xml index bee59f8f8..85dda2d01 100644 --- a/app/src/main/res/layout/fragment_flat_player_playback_controls.xml +++ b/app/src/main/res/layout/fragment_flat_player_playback_controls.xml @@ -27,6 +27,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="8" + android:paddingVertical="@dimen/seekbar_padding" android:splitTrack="false" android:thumb="@drawable/switch_square" app:layout_constraintEnd_toStartOf="@id/songTotalTime" diff --git a/app/src/main/res/layout/fragment_full_player_controls.xml b/app/src/main/res/layout/fragment_full_player_controls.xml index 9baa5c70c..7e3828311 100644 --- a/app/src/main/res/layout/fragment_full_player_controls.xml +++ b/app/src/main/res/layout/fragment_full_player_controls.xml @@ -99,6 +99,7 @@ android:layout_height="wrap_content" android:layout_marginTop="16dp" android:maxHeight="2dp" + android:paddingVertical="@dimen/seekbar_padding" android:progressDrawable="@drawable/color_progress_seek" app:layout_constraintEnd_toStartOf="@id/songTotalTime" app:layout_constraintStart_toEndOf="@id/songCurrentProgress" diff --git a/app/src/main/res/layout/fragment_gradient_controls.xml b/app/src/main/res/layout/fragment_gradient_controls.xml index ae6b98ee7..59f4ff77e 100644 --- a/app/src/main/res/layout/fragment_gradient_controls.xml +++ b/app/src/main/res/layout/fragment_gradient_controls.xml @@ -101,6 +101,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="16dp" + android:paddingVertical="@dimen/seekbar_padding" app:layout_constraintEnd_toStartOf="@id/songTotalTime" app:layout_constraintStart_toEndOf="@id/songCurrentProgress" app:layout_constraintTop_toBottomOf="@id/titleContainer" diff --git a/app/src/main/res/layout/fragment_gradient_player.xml b/app/src/main/res/layout/fragment_gradient_player.xml index 0f00d905d..3368ea1b8 100644 --- a/app/src/main/res/layout/fragment_gradient_player.xml +++ b/app/src/main/res/layout/fragment_gradient_player.xml @@ -4,7 +4,9 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="?attr/colorSurface"> + android:background="?attr/colorSurface" + android:clickable="true" + android:focusable="true"> + + + app:fel_size_bottom="100dp" + app:fel_size_top="100dp"> - + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-ar-rSA/strings.xml b/app/src/main/res/values-ar-rSA/strings.xml index 2081dd35f..d2111c843 100644 --- a/app/src/main/res/values-ar-rSA/strings.xml +++ b/app/src/main/res/values-ar-rSA/strings.xml @@ -146,7 +146,6 @@ يستمع حالياً إلى %1$s لـ %2$s Custom Artist Images أسود قليلاً - Databases (Playlists, History, Most Played, etc.) حذف قائمة التشغيل %1$s؟]]> حذف قوائم التشغيل diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index 5888e4f96..3e12aec33 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -140,7 +140,6 @@ Aktuálně posloucháš %1$s od %2$s. Custom Artist Images Tmavá - Databases (Playlists, History, Most Played, etc.) Smazat seznam skladeb %1$s?]]> Smazat seznamy skladeb diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index d5054be18..57e8b115c 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -136,7 +136,6 @@ Spielt zur Zeit %1$s von %2$s. Custom Artist Images Dunkel - Databases (Playlists, History, Most Played, etc.) Playlist löschen %1$s löschen?]]> Playlisten löschen diff --git a/app/src/main/res/values-el-rGR/strings.xml b/app/src/main/res/values-el-rGR/strings.xml index feea07f59..14523ba85 100644 --- a/app/src/main/res/values-el-rGR/strings.xml +++ b/app/src/main/res/values-el-rGR/strings.xml @@ -136,7 +136,6 @@ Παίζει το %1$s από τους %2$s. Custom Artist Images Κάπως Σκούρο - Databases (Playlists, History, Most Played, etc.) Διαγραφή playlist %1$s?]]> Διαγραφή αυτών των λιστών αναπαραγωγής diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 1c4c0921f..eb91a4cac 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -136,7 +136,6 @@ Actualmente estás escuchando %1$s de %2$s. Custom Artist Images Un poco Oscuro - Databases (Playlists, History, Most Played, etc.) Eliminar lista de reproducción %1$s?]]> Eliminar listas de reproducción diff --git a/app/src/main/res/values-fa-rIR/strings.xml b/app/src/main/res/values-fa-rIR/strings.xml index 2992c1764..791030970 100644 --- a/app/src/main/res/values-fa-rIR/strings.xml +++ b/app/src/main/res/values-fa-rIR/strings.xml @@ -136,7 +136,6 @@ در حال حاضر شما به s$1% از s$2% گوش می‌دهید. Custom Artist Images تقریبا مشکی - Databases (Playlists, History, Most Played, etc.) حذف کردن پلی لیست %1$s??]]> حذف کردن پلی لیست ها diff --git a/app/src/main/res/values-fil-rPH/strings.xml b/app/src/main/res/values-fil-rPH/strings.xml index 7008b44be..5313f5b18 100644 --- a/app/src/main/res/values-fil-rPH/strings.xml +++ b/app/src/main/res/values-fil-rPH/strings.xml @@ -136,7 +136,6 @@ Kasalukuyang nakikinig sa %1$s ni %2$s. Custom Artist Images Medyo Madilim - Databases (Playlists, History, Most Played, etc.) Tanggalin ang playlist %1$s?]]> Tanggalin ang mga playlist diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml index e0f4d8824..c9046d5ba 100644 --- a/app/src/main/res/values-fr-rFR/strings.xml +++ b/app/src/main/res/values-fr-rFR/strings.xml @@ -136,7 +136,6 @@ Vous écoutez actuellement %1$s par %2$s. Custom Artist Images Plutôt Sombre - Databases (Playlists, History, Most Played, etc.) Supprimer la liste de lecture %1$s ?]]> Supprimer les listes de lecture diff --git a/app/src/main/res/values-hi-rIN/strings.xml b/app/src/main/res/values-hi-rIN/strings.xml index 6f28ea543..a73ad2937 100644 --- a/app/src/main/res/values-hi-rIN/strings.xml +++ b/app/src/main/res/values-hi-rIN/strings.xml @@ -136,7 +136,6 @@ Currently listening to %1$s by %2$s. Custom Artist Images Kinda Dark - Databases (Playlists, History, Most Played, etc.) Delete playlist %1$s?]]> Delete playlists diff --git a/app/src/main/res/values-hr-rHR/strings.xml b/app/src/main/res/values-hr-rHR/strings.xml index c7ecadb83..e4d7e6c5e 100644 --- a/app/src/main/res/values-hr-rHR/strings.xml +++ b/app/src/main/res/values-hr-rHR/strings.xml @@ -138,7 +138,6 @@ Currently listening to %1$s by %2$s. Custom Artist Images Kinda Dark - Databases (Playlists, History, Most Played, etc.) Delete playlist %1$s?]]> Delete playlists diff --git a/app/src/main/res/values-hu-rHU/strings.xml b/app/src/main/res/values-hu-rHU/strings.xml index c78241bab..bd7c0105e 100644 --- a/app/src/main/res/values-hu-rHU/strings.xml +++ b/app/src/main/res/values-hu-rHU/strings.xml @@ -136,7 +136,6 @@ Jelenleg %1$s hallgatása %2$s által. Custom Artist Images Kissé sötét - Databases (Playlists, History, Most Played, etc.) Lejátszási lista törlése %1$s lejátszási listát?]]> Lejátszási listák törlése diff --git a/app/src/main/res/values-in-rID/strings.xml b/app/src/main/res/values-in-rID/strings.xml index ce514da8f..37e9514e4 100644 --- a/app/src/main/res/values-in-rID/strings.xml +++ b/app/src/main/res/values-in-rID/strings.xml @@ -48,138 +48,137 @@ Pengatur waktu tidur Urut berdasarkan Pengubah label - Toggle favorite - Toggle shuffle mode - Adaptive - Add + Aktifkan/nonaktifkan favorit + Aktifkan/nonaktifkan mode acak + Adaptif + Tambahkan "Tambahkan ke daftar putar" - Add Time Framed Lyrics - "Added 1 title to the playing queue." - Added %1$d titles to the playing queue. + Tambahkan kerangka waktu pada lirik + "1 lagu ditambahkan ke antrean." + %1$d lagu telah ditambahkan ke antrean. Album - Songs + Lagu - Album Artist - Albums + Artis Album + Album - Albums + Album - Always - Hey check out this cool music player at: https://play.google.com/store/apps/details?id=%s - Shuffle - Top Tracks - Full Image - Card - Classic + Selalu + Hey, cobalah pemutar musik keren ini di: https://play.google.com/store/apps/details?id=%s + Acak + Lagu Teratas + Gambar penuh + Kartu + Klasik MD3 - Small - Minimal Text - Artist - Artists - Audio Fade Duration - Audio focus denied. - Change the sound settings and adjust the equalizer controls - Auto - Backup and restore your settings, playlists - - Backups - Biography - Just Black - Blacklist - Blur - Blur Card - Unable to send report - Invalid access token. Please contact the app developer. - Issues are not enabled for the selected repository. Please contact the app developer. - An unexpected error occurred. Please contact the app developer. - Wrong username or password - Issue - Send manually - Please enter an issue description - Please enter your valid GitHub password - Please enter an issue title - Please enter your valid GitHub username - An unexpected error occurred. Sorry you found this bug, if it keeps crashing \"Clear app data\" or send an Email - Send using GitHub account - Buy now - Cancel - Card - Colored Card - Square Card - Card - Carousel effect on the now playing screen - Cascading - Changelog - Check out What\'s New - Choose what to restore - Circle - Circular - Classic - Clear - Clear blacklist - Clear queue - Color - Colors - Composer - Copied device info to clipboard. - Couldn\u2019t create playlist. - "Couldn\u2019t download a matching album cover." - Could not restore purchase. - Could not scan %d files. - Create - Create - Created playlist %1$s. - Members and contributors - Currently listening to %1$s by %2$s. - Custom Artist Images - Kinda Dark - Databases (Playlists, History, Most Played, etc.) - Delete playlist - %1$s?]]> - Delete playlists - Delete song - %1$s?]]> - Delete songs - %1$d playlists?]]> - %1$d songs?]]> - Deleted %1$d songs. - Deleting Songs - Depth - Description - Device info - Allow Retro Music to modify audio settings - Set ringtone - Disc Number - Do you want to clear the blacklist? - %1$s from the blacklist?]]> - Donate - If you think I deserve to get paid for my work, you can leave some money here - Buy me a: - Done - Drive mode - Edit Button - Edit Lyrics - Edit Synced Lyrics - Empty + Kecil + Teks minimal + Artis + Artis + Durasi transisi antar lagu + Fokus suara ditolak. + Ubah pengaturan suara dan atur equalizer + Otomatis + Cadangkan dan pulihkan pengaturan, daftar putar anda + + Cadangkan + Biografi + Hitam Pekat + Daftar hitam + Keburaman + Kartu buram + Tidak dapat mengirim laporan + Token akses tidak valid. Silakan hubungi pengembang aplikasi. + Masalah tidak diaktifkan untuk repositori yang dipilih. Silakan hubungi pengembang aplikasi. + Terjadi kesalahan yang tak terduga. Silakan hubungi pengembang aplikasi. + Username atau password salah + Masalah + Kirim secara manual + Silakan masukkan deskripsi masalah + Mohon masukkan kata sandi Github Anda dengan benar + Harap masukkan judul masalah + Mohon masukkan nama pengguna Github Anda dengan benar + Terjadi kesalahan tak terduga. Maaf jika Anda menemukan bug ini, jika terus terjadi maka \"Hapus data aplikasi\" atau kirim Email + Kirim dengan menggunakan akun Github + Beli sekarang + Batal + Kartu + Kartu Berwarna + Kartu Persegi + Kartu + Efek korsel pada layar yang sedang diputar + Bergerak + Daftar Log Pembaruan + Lihat Apa Yang Baru + Pilih apa yang akan dipulihkan + Bulat + Melingkar + Klasik + Bersihkan + Bersihkan daftar hitam + Bersihkan antrean + Warna + Warna + Komposer + Info perangkat tersalin ke papan klip. + Tidak dapat membuat daftar putar. + "Tidak dapat mengunduh sampul album yang cocok." + Tidak dapat mengembalikan pembelian. + Tidak dapat memindai %d berkas. + Buat + Buat + %1$s daftar putar telah dibuat. + Member dan kontributor + Saat ini mendengarkan %1$s oleh %2$s. + Gambar Artis Kustom + Agak Gelap + Hapus daftar putar + %1$s?]]> + Hapus daftar putar + Hapus lagu + %1$s?]]> + Hapus lagu + %1$d daftar putar?]]> + %1$d lagu?]]> + Menghapus %1$d lagu. + Menghapus Lagu + Kedalaman + Keterangan + Info perangkat + Izinkan Retro Music untuk mengubah pengaturan audio + Setel nada dering + Nomer disk + Apakah Anda ingin menghapus daftar hitam? + %1$s dari daftar hitam?]]> + Donasi + Jika Anda pikir saya pantas dibayar untuk pekerjaan saya, Anda dapat meninggalkan sejumlah uang di sini + Belikan saya: + Selesai + Mode mengemudi + Tombol Edit + Edit Lirik + Edit Lirik Yang Disinkronkan + Kosong Equalizer - FAQ - Favorites - Finish last song - Fit - Flat - Folders - Follow system - For you - Free - Full - Full card - Change the theme and colors of the app - Look and feel + Pertanyaan Umum (FAQ) + Favorit + Selesaikan lagu terakhir + Paskan + Datar + Folder + Ikuti setelan sistem + Untuk Anda + Gratis + Penuh + Kartu penuh + Ubah tema dan warna aplikasi + Tampilan dan nuansa Genre - Genres - Fork the project on GitHub - Gradient + Genre + Beri fork pada proyek di GitHub + Gradasi 1 2 3 @@ -188,92 +187,92 @@ 6 7 8 - Grid style - Need more help? - Hinge - History - Home - Horizontal flip - Image - Gradient image - Change artist image download settings - Import - Import playlist - It imports all playlists listed in the Android Media Store with songs, if the playlists already exists, the songs will get merged. - Inserted %1$d songs into the playlist %2$s. - Share your Retro Music setup to showcase on Instagram - Keyboard + Gaya kisi + Butuh bantuan lebih? + Engsel + Riwayat + Beranda + Balik horisontal + Gambar + Gambar bergradasi + Ubah pengaturan unduhan gambar artis + Impor + Impor daftar putar + Ini mengimpor semua daftar putar yang terdaftar di Android Media Store dengan lagu, jika daftar putar sudah ada, lagu akan digabungkan. + Memasukkan %1$d lagu ke dalam daftar putar %2$s. + Bagikan pengaturan Musik Retro Anda untuk dipamerkan di Instagram + Papan ketik Bitrate Format - File name - File path - Size - More from %s + Nama file + Lokasi File + Ukuran + Lainnya dari %s Sampling rate - Length - Labeled - Last added - Last song - Library categories - Licenses - Clearly White - Listeners - Listing files - Loading products… - Login - Lyrics - Made with ❤️ in India + Durasi + Berlabel + Terakhir ditambahkan + Lagu terakhir + Kategori perpustakaan + Lisensi + Putih Terang + Pendengar + Daftar file + Memuat produk… + Masuk + Lirik + Dibuat dengan ❤️ di India Material - Error - Permission error - Name - Most played - Never + Kesalahan + Kesalahan izin + Nama + Paling sering diputar + Tidak pernah Daftar putar baru - %s is the new start directory. - Next Song - You have no albums - You have no artists - "Play a song first, then try again." - No Backups Found - No equalizer found - You have no genres - No lyrics found - No songs playing - You have no playlists - No purchase found. - No results - You have no songs + %s adalah direktori awal yang baru. + Lagu berikutnya + Tidak ada album + Tidak ada artis + "Putar lagu terlebih dahulu, lalu coba lagi." + Tidak ada cadangan yang ditemukan + Equalizer tidak ditemukan + Tidak ada genre + Lirik tidak ditemukan + Tidak ada lagu yang diputar + Tidak ada daftar putar + Tidak ada pembelian yang ditemukan. + Tidak ada hasil + Tidak ada lagu Normal - Normal lyrics - %s is not listed in the media store.]]> - Not recently played - Nothing to scan. - Nothing to see - Notification - Customize the notification style - Now playing - Now playing queue - Customize the now playing screen - 9+ now playing themes - Only on Wi-Fi - Advanced testing features - Other - Password - Past 3 months - Paste Lyrics Here - Paste timeframe lyrics here - Peak - Permission to access external storage denied. - The app needs permission to access your device storage for playing music - Storage Access - Permissions denied. - Personalize - Customize your now playing and UI controls - Pick from local storage + Lirik normal + %s tidak terdaftar di penyimpanan media.]]> + Tidak baru-baru ini dimainkan + Tidak ada yang di pindai. + Tidak ada yang bisa dilihat + Pemberitahuan + Sesuaikan gaya notifikasi + Sedang diputar + Sekarang memutar antrean + Sesuaikan tampilan layar yang sedang diputar + 9+ tema pemutar sekarang + Hanya di Wifi + Fitur pengujian lanjutan + Lainnya + Kata sandi + 3 bulan terakhir + Tempel Lirik Disini + Tempel kerangka waktu lirik di sini + Puncak + Izin untuk mengakses penyimpanan eksternal ditolak. + Aplikasi memerlukan izin untuk mengakses penyimpanan perangkat Anda untuk memutar musik + Akses Penyimpanan + Izin ditolak. + Personalisasi + Sesuaikan pemutar dan UI Anda + Pilih dari penyimpanan lokal Pinterest - Follow Pinterest page for Retro Music design inspiration - Plain + Ikuti halaman Pinterest untuk inspirasi desain Retro Music + Polos The playing notification provides actions for play/pause etc. Playing notification Playlist is empty @@ -286,7 +285,7 @@ Advanced Album style Audio - Blacklist + Daftar hitam Controls Theme Images @@ -337,7 +336,7 @@ Reduce volume on focus loss Fade Audio Auto-download artist images - Blacklist + Daftar hitam Bluetooth playback Blur album cover Classic notification design @@ -428,7 +427,7 @@ Share the app with your friends and family Share to Stories Show Album Artists - Shuffle + Acak Simple Sleep timer canceled. Sleep timer set for %d minutes from now. @@ -441,8 +440,8 @@ Ascending Album @string/album_artist - Artist - Composer + Artis + Komposer Date added Date modified Song count diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index 1c3eaa288..30fef24a9 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -137,7 +137,6 @@ https://play.google.com/store/apps/details?id=%s Ascoltando attualmente %1$s di %2$s. Immagini dell\'Artista Personalizzate Scuro - Database (Playlist, Cronologia, Più riprodotti, ecc.) Elimina playlist %1$s?]]> Elimina playlist diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index 4268eadde..4a759fb1a 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -135,7 +135,6 @@ 現在、 %1$s によって %2$s で聴いています。 Custom Artist Images ダーク - Databases (Playlists, History, Most Played, etc.) プレイリストを削除 %1$s を削除しますか?]]> プレイリストを削除 diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 4566f6978..04b9d5c16 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -134,7 +134,6 @@ 현재 %2$s의 %1$s를 듣는 중입니다. Custom Artist Images 카인다 다크 - Databases (Playlists, History, Most Played, etc.) 재생목록 삭제 %1$s 재생목록을 삭제하시겠습니까?]]> 재생목록 삭제 diff --git a/app/src/main/res/values-ml-rIN/strings.xml b/app/src/main/res/values-ml-rIN/strings.xml index 85ffd6afb..eaa2ac2f0 100644 --- a/app/src/main/res/values-ml-rIN/strings.xml +++ b/app/src/main/res/values-ml-rIN/strings.xml @@ -136,7 +136,6 @@ Currently listening to %1$s by %2$s. Custom Artist Images Kinda Dark - Databases (Playlists, History, Most Played, etc.) Delete playlist %1$s?]]> Delete playlists diff --git a/app/src/main/res/values-my-rMM/strings.xml b/app/src/main/res/values-my-rMM/strings.xml index 83e928281..087ab7858 100644 --- a/app/src/main/res/values-my-rMM/strings.xml +++ b/app/src/main/res/values-my-rMM/strings.xml @@ -134,7 +134,6 @@ %2$s သီဆိုထားသော %1$s ကိုယခုနားထောင်နေသည် Custom Artist Images အနက်ရောင်ဆန်ဆန် - Databases (Playlists, History, Most Played, etc.) Playlist ဖျက်ခြင်း %1$s Playlist ကိုဖျက်မှာလား]]> Playlist များဖျက်ခြင်း diff --git a/app/src/main/res/values-nl-rNL/strings.xml b/app/src/main/res/values-nl-rNL/strings.xml index 501097859..9ed36b5e4 100644 --- a/app/src/main/res/values-nl-rNL/strings.xml +++ b/app/src/main/res/values-nl-rNL/strings.xml @@ -136,7 +136,6 @@ Nu luisterend naar %1$s van %2$s. Custom Artist Images Soort van donker - Databases (Playlists, History, Most Played, etc.) Afspeellijst verwijderen %1$s verwijderen?]]> Afspeellijsten verwijderen diff --git a/app/src/main/res/values-no-rNO/strings.xml b/app/src/main/res/values-no-rNO/strings.xml index b22b9ac30..4d2c2b212 100644 --- a/app/src/main/res/values-no-rNO/strings.xml +++ b/app/src/main/res/values-no-rNO/strings.xml @@ -136,7 +136,6 @@ Currently listening to %1$s by %2$s. Custom Artist Images Kinda Dark - Databases (Playlists, History, Most Played, etc.) Delete playlist %1$s?]]> Delete playlists diff --git a/app/src/main/res/values-or-rIN/strings.xml b/app/src/main/res/values-or-rIN/strings.xml index 0ae540bef..1b3d4a237 100644 --- a/app/src/main/res/values-or-rIN/strings.xml +++ b/app/src/main/res/values-or-rIN/strings.xml @@ -136,7 +136,6 @@ Currently listening to %1$s by %2$s. Custom Artist Images Kinda Dark - Databases (Playlists, History, Most Played, etc.) Delete playlist %1$s?]]> Delete playlists diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index dcc526560..59d353453 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -140,7 +140,6 @@ Aktualnie odtwarzane %1$s wykonawcy %2$s. Custom Artist Images Dość ciemny - Databases (Playlists, History, Most Played, etc.) Usuń playlistę %1$s?]]> Usuń playlisty diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index c563a4586..ac96569f4 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -136,7 +136,6 @@ Atualmente ouvindo %1$s por %2$s. Custom Artist Images Meio escuro - Databases (Playlists, History, Most Played, etc.) Excluir playlist %1$s?]]> Excluir playlists diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index cc1a8d6f6..c01ccaaf7 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -136,7 +136,6 @@ A ouvir %1$s de %2$s. Custom Artist Images Meio escuro - Databases (Playlists, History, Most Played, etc.) Eliminar lista %1$s?]]> Eliminar listas diff --git a/app/src/main/res/values-ro-rRO/strings.xml b/app/src/main/res/values-ro-rRO/strings.xml index f4b9b9859..c834ca77a 100644 --- a/app/src/main/res/values-ro-rRO/strings.xml +++ b/app/src/main/res/values-ro-rRO/strings.xml @@ -138,7 +138,6 @@ Acum ascultați %1$s de %2$s. Custom Artist Images Suriu - Databases (Playlists, History, Most Played, etc.) Șterge playlist %1$s?]]> Șterge playlist-uri diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index d6b4fd747..2b056856b 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -140,7 +140,6 @@ Сейчас играет %1$s от %2$s. Custom Artist Images Тёмная - Databases (Playlists, History, Most Played, etc.) Удалить плейлист %1$s?]]> Удалить плейлисты diff --git a/app/src/main/res/values-sr-rSP/strings.xml b/app/src/main/res/values-sr-rSP/strings.xml index 08b85d0b3..0657b0e50 100644 --- a/app/src/main/res/values-sr-rSP/strings.xml +++ b/app/src/main/res/values-sr-rSP/strings.xml @@ -138,7 +138,6 @@ Trenutno se reprodukuje %1$s izvodjaca %2$s Custom Artist Images Kao tamno - Databases (Playlists, History, Most Played, etc.) Izbrisi plejlistu %1$s plejlistu?]]> Izbrisi plejlistu diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index cfabc1395..32b494e09 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -136,7 +136,6 @@ Lyssnar just nu på %1$s av %2$s. Custom Artist Images Ganska mörkt - Databases (Playlists, History, Most Played, etc.) Radera spellista %1$s?]]> Radera spellistor diff --git a/app/src/main/res/values-ta-rIN/strings.xml b/app/src/main/res/values-ta-rIN/strings.xml index 474260cab..2634e7bd3 100644 --- a/app/src/main/res/values-ta-rIN/strings.xml +++ b/app/src/main/res/values-ta-rIN/strings.xml @@ -136,7 +136,6 @@ Currently listening to %1$s by %2$s. Custom Artist Images Kinda Dark - Databases (Playlists, History, Most Played, etc.) Delete playlist %1$s?]]> Delete playlists diff --git a/app/src/main/res/values-th-rTH/strings.xml b/app/src/main/res/values-th-rTH/strings.xml index ad90fd815..f48a24e78 100644 --- a/app/src/main/res/values-th-rTH/strings.xml +++ b/app/src/main/res/values-th-rTH/strings.xml @@ -134,7 +134,6 @@ กำลังฟัง %1$s ของ %2$s Custom Artist Images Kinda Dark - Databases (Playlists, History, Most Played, etc.) ลบเพลย์ลิสต์ %1$s?]]> ลบเพลย์ลิสต์ diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index 0742ab4b7..ed827ded6 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -136,7 +136,6 @@ Şu anda %2$s şarkıcısından %1$s dinleniyor. Custom Artist Images Koyu - Databases (Playlists, History, Most Played, etc.) Çalma listesini sil %1$s silinsin mi?]]> Çalma listelerini sil diff --git a/app/src/main/res/values-uk-rUA/strings.xml b/app/src/main/res/values-uk-rUA/strings.xml index 8907d217c..5adaab45f 100644 --- a/app/src/main/res/values-uk-rUA/strings.xml +++ b/app/src/main/res/values-uk-rUA/strings.xml @@ -140,7 +140,6 @@ Зараз грає %1$s від %2$s. Custom Artist Images Майже темна - Databases (Playlists, History, Most Played, etc.) Видалити список відтворення %1$s?]]> Видалити списки відтворення diff --git a/app/src/main/res/values-vi-rVN/strings.xml b/app/src/main/res/values-vi-rVN/strings.xml index b3372da9c..7eaf75366 100644 --- a/app/src/main/res/values-vi-rVN/strings.xml +++ b/app/src/main/res/values-vi-rVN/strings.xml @@ -135,7 +135,6 @@ tiếp tục xảy ra hãy \"Xóa dữ liệu ứng dụng\" Đang nghe %1$s bởi %2$s. Custom Artist Images Xám đen - Databases (Playlists, History, Most Played, etc.) Xoá danh sách phát %1$s?]]> Xoá danh sách phát diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 267726dc2..3a2f33681 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -134,7 +134,6 @@ 正在收听 %2$s 的 %1$s。 自定义艺术家图像 深色 - 数据库(播放列表、播放历史、最多播放等) 删除播放列表 %1$s 吗?]]> 删除播放列表 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 29a512be3..85e626518 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -134,7 +134,6 @@ 我正在聽 %2$s 的 %1$s Custom Artist Images 暗沉 - Databases (Playlists, History, Most Played, etc.) 刪除播放清單 %1$s 嗎?]]> 刪除多個播放清單 diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 7c76d40ab..0db4d540d 100755 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -1,6 +1,6 @@ - + @string/normal @string/cascading @string/depth @@ -20,6 +20,16 @@ 6 + + 0 + 1 + + + + @string/replace_cover + @string/over_cover + + 0 1 diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index a3f2064cf..bf5ba4946 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -64,4 +64,6 @@ 24dp 40dp 16dp + + 16dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b66f5c1a7..daedc0c0a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,4 +1,3 @@ - About %s Team, social links @@ -138,7 +137,6 @@ Currently listening to %1$s by %2$s. Custom Artist Images Kinda Dark - Databases (Playlists, History, Most Played, etc.) Delete playlist %1$s?]]> @@ -276,6 +274,7 @@ Only on Wi-Fi Advanced testing features Other + Over Cover Password Past 3 months Paste Lyrics Here @@ -373,6 +372,7 @@ Ignore Media Store covers Last added playlist interval Fullscreen controls + Lyrics type Now playing theme Open source licences Remember Last Tab @@ -406,6 +406,7 @@ %1$d songs from the playlist?]]> Rename playlist + Replace Cover Report an issue Report bug Reset diff --git a/app/src/main/res/xml/pref_now_playing_screen.xml b/app/src/main/res/xml/pref_now_playing_screen.xml index f1c84acad..a1eecf692 100644 --- a/app/src/main/res/xml/pref_now_playing_screen.xml +++ b/app/src/main/res/xml/pref_now_playing_screen.xml @@ -21,6 +21,14 @@ android:layout="@layout/list_item_view_switch_no_title" android:title="Snow Fall Effect (Only on Normal theme)" /> + + @@ -33,7 +41,7 @@ - - \ No newline at end of file diff --git a/build.gradle b/build.gradle index 764e4911b..ea769cd98 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,12 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.6.10' - ext.navigation_version = '2.4.0-rc01' - ext.mdc_version = '1.5.0-rc01' - ext.preference_version = '1.2.0-rc01' + ext { + kotlin_version = '1.6.10' + navigation_version = '2.4.0-rc01' + mdc_version = '1.5.0-rc01' + preference_version = '1.2.0-rc01' + } repositories { @@ -17,9 +19,6 @@ buildscript { classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigation_version" } } -plugins { - id "com.github.ben-manes.versions" version "0.39.0" -} task clean(type: Delete) { delete rootProject.buildDir } \ No newline at end of file