From ccde2d91ecd20ce54672681ec8a9f8ea94682f42 Mon Sep 17 00:00:00 2001 From: h4h13 Date: Mon, 3 Jun 2019 21:53:37 +0530 Subject: [PATCH] Fix banner --- .../code/name/monkey/retromusic/Injection.kt | 5 + .../activities/ArtistDetailActivity.kt | 15 +- .../retromusic/activities/LyricsActivity.kt | 2 +- .../retromusic/activities/MainActivity.kt | 8 +- .../retromusic/activities/UserInfoActivity.kt | 339 ++++++++++++++++++ .../activities/base/AbsThemeActivity.kt | 1 + .../tageditor/AlbumTagEditorActivity.kt | 2 +- .../retromusic/adapter/CollageSongAdapter.kt | 75 ++++ .../monkey/retromusic/adapter/GenreAdapter.kt | 4 +- .../retromusic/adapter/SongFileAdapter.kt | 2 +- .../retromusic/adapter/SpanSongsAdapter.kt | 20 ++ .../adapter/playlist/PlaylistAdapter.kt | 15 +- .../song/OrderablePlaylistSongAdapter.kt | 6 +- .../adapter/song/PlaylistSongAdapter.kt | 1 + .../adapter/song/ShuffleButtonSongAdapter.kt | 4 +- .../retromusic/adapter/song/SongAdapter.kt | 5 +- .../shortcuttype/SearchShortCutType.kt | 2 +- .../dialogs/RenamePlaylistDialog.kt | 39 ++ .../retromusic/dialogs/SleepTimerDialog.kt | 71 ++++ .../retromusic/dialogs/SongShareDialog.kt | 36 ++ .../retromusic/fragments/NowPlayingScreen.kt | 2 + .../retromusic/fragments/VolumeFragment.kt | 5 + .../fragments/mainactivity/GenreFragment.kt | 91 +++++ .../mainactivity/LibraryFragment.java | 1 - .../fragments/mainactivity/SongsFragment.kt | 9 +- .../mainactivity/folders/FoldersFragment.java | 4 + .../mainactivity/home/BannerHomeFragment.kt | 57 ++- .../fragments/player/color/ColorFragment.kt | 4 +- .../player/flat/FlatPlayerFragment.kt | 2 + .../fragments/player/normal/PlayerFragment.kt | 16 +- .../player/slide/SlidePlayerFragment.kt | 332 +++++++++++++++++ .../tiny/TinyPlaybackControlsFragment.kt | 2 +- .../player/tiny/TinyPlayerFragment.kt | 6 +- .../MainActivityFragmentCallbacks.kt | 2 + .../monkey/retromusic/loaders/AlbumLoader.kt | 1 + .../misc/CustomFragmentStatePagerAdapter.java | 8 +- .../retromusic/misc/DisposableManager.kt | 38 ++ .../retromusic/misc/DisposingObserver.kt | 32 ++ .../misc/ScrollAwareFABBehavior.java | 90 +++++ .../retromusic/misc/SimpleAnimatorListener.kt | 36 ++ .../retromusic/misc/SpacesItemDecoration.java | 35 ++ .../retromusic/mvp/contract/AlbumContract.kt | 3 - .../mvp/contract/AlbumDetailsContract.kt | 4 - .../retromusic/mvp/contract/HomeContract.kt | 3 - .../mvp/presenter/ArtistPresenter.kt | 4 - .../retromusic/providers/NotPlayedStore.kt | 82 +++++ .../monkey/retromusic/rest/KogouClient.java | 89 +++++ .../retromusic/rest/model/KuGouRawLyric.java | 55 +++ .../rest/model/KuGouSearchLyricResult.java | 110 ++++++ .../rest/service/KuGouApiService.java | 38 ++ .../transform/RoundStackTransformer.java | 30 ++ .../transform/StackPagerTransformer.kt | 47 +++ .../monkey/retromusic/util/Compressor.java | 104 ++++++ .../retromusic/util/NavigationUtil.java | 12 +- .../monkey/retromusic/util/SystemUtils.java | 113 ++++++ .../monkey/retromusic/util/TempUtils.java | 82 +++++ .../views/MaterialButtonTextColor.kt | 37 ++ .../retromusic/views/PlayPauseDrawable.java | 225 ++++++++++++ .../retromusic/views/TintIconColorToolbar.kt | 36 ++ .../retromusic/views/UserImageView.java | 147 ++++++++ .../views/WidthFitSquareCardView.kt | 6 +- .../res/layout-land/fragment_banner_home.xml | 114 ++++++ .../main/res/layout-land/fragment_player.xml | 4 + .../fragment_banner_home.xml | 113 ++++++ .../layout-xlarge-land/fragment_player.xml | 5 + .../layout-xlarge/fragment_banner_home.xml | 112 ++++++ .../res/layout-xlarge/fragment_player.xml | 6 +- .../main/res/layout/fragment_banner_home.xml | 105 ++++++ app/src/main/res/layout/fragment_player.xml | 5 + app/src/main/res/values/styles_parents.xml | 8 + app/src/main/res/xml/pref_ui.xml | 7 + 71 files changed, 3059 insertions(+), 72 deletions(-) create mode 100644 app/src/main/java/code/name/monkey/retromusic/activities/UserInfoActivity.kt create mode 100644 app/src/main/java/code/name/monkey/retromusic/adapter/CollageSongAdapter.kt create mode 100644 app/src/main/java/code/name/monkey/retromusic/adapter/SpanSongsAdapter.kt create mode 100644 app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/GenreFragment.kt create mode 100644 app/src/main/java/code/name/monkey/retromusic/fragments/player/slide/SlidePlayerFragment.kt create mode 100644 app/src/main/java/code/name/monkey/retromusic/misc/DisposableManager.kt create mode 100644 app/src/main/java/code/name/monkey/retromusic/misc/DisposingObserver.kt create mode 100644 app/src/main/java/code/name/monkey/retromusic/misc/ScrollAwareFABBehavior.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/misc/SimpleAnimatorListener.kt create mode 100644 app/src/main/java/code/name/monkey/retromusic/misc/SpacesItemDecoration.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/providers/NotPlayedStore.kt create mode 100644 app/src/main/java/code/name/monkey/retromusic/rest/KogouClient.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/rest/model/KuGouRawLyric.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/rest/model/KuGouSearchLyricResult.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/rest/service/KuGouApiService.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/transform/RoundStackTransformer.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/transform/StackPagerTransformer.kt create mode 100644 app/src/main/java/code/name/monkey/retromusic/util/Compressor.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/util/SystemUtils.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/util/TempUtils.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/views/MaterialButtonTextColor.kt create mode 100644 app/src/main/java/code/name/monkey/retromusic/views/PlayPauseDrawable.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/views/TintIconColorToolbar.kt create mode 100644 app/src/main/java/code/name/monkey/retromusic/views/UserImageView.java create mode 100644 app/src/main/res/layout-land/fragment_banner_home.xml create mode 100644 app/src/main/res/layout-xlarge-land/fragment_banner_home.xml create mode 100644 app/src/main/res/layout-xlarge/fragment_banner_home.xml create mode 100644 app/src/main/res/layout/fragment_banner_home.xml diff --git a/app/src/main/java/code/name/monkey/retromusic/Injection.kt b/app/src/main/java/code/name/monkey/retromusic/Injection.kt index 8d3a29c6..55857020 100644 --- a/app/src/main/java/code/name/monkey/retromusic/Injection.kt +++ b/app/src/main/java/code/name/monkey/retromusic/Injection.kt @@ -16,6 +16,8 @@ package code.name.monkey.retromusic import code.name.monkey.retromusic.providers.RepositoryImpl import code.name.monkey.retromusic.providers.interfaces.Repository +import code.name.monkey.retromusic.rest.KogouClient +import code.name.monkey.retromusic.rest.service.KuGouApiService import code.name.monkey.retromusic.util.schedulers.BaseSchedulerProvider import code.name.monkey.retromusic.util.schedulers.SchedulerProvider @@ -29,4 +31,7 @@ object Injection { return SchedulerProvider.getInstance() } + fun provideKuGouApiService(): KuGouApiService { + return KogouClient().apiService + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt index 6b479f18..ded4bf05 100755 --- a/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt @@ -23,10 +23,6 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.retromusic.R -import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity -import code.name.monkey.retromusic.adapter.album.AlbumAdapter -import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter -import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.RetroGlideExtension @@ -38,6 +34,10 @@ import code.name.monkey.retromusic.mvp.contract.ArtistDetailContract import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsPresenter import code.name.monkey.retromusic.rest.LastFMRestClient import code.name.monkey.retromusic.rest.model.LastFmArtist +import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity +import code.name.monkey.retromusic.adapter.album.AlbumAdapter +import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter +import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter import code.name.monkey.retromusic.util.* import com.google.android.material.appbar.AppBarLayout import kotlinx.android.synthetic.main.activity_artist_content.* @@ -180,7 +180,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac super.onActivityResult(requestCode, resultCode, data) when (requestCode) { REQUEST_CODE_SELECT_IMAGE -> if (resultCode == Activity.RESULT_OK) { - CustomArtistImageUtil.getInstance(this).setCustomArtistImage(artist, data!!.data!!) + CustomArtistImageUtil.getInstance(this).setCustomArtistImage(artist!!, data!!.data!!) } else -> if (resultCode == Activity.RESULT_OK) { reload() @@ -208,7 +208,10 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac } private fun getArtist(): Artist { - return this.artist + if (artist == null) { + artist = Artist() + } + return this.artist!! } private fun setArtist(artist: Artist) { diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/LyricsActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/LyricsActivity.kt index 13842341..ed2c4f1a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/LyricsActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/LyricsActivity.kt @@ -216,7 +216,7 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage return baseUrl } - class PagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { + class PagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { class Tabs(@StringRes val title: Int, val fragment: Fragment) 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 940f2c4c..0e3add24 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 @@ -3,7 +3,6 @@ package code.name.monkey.retromusic.activities import android.annotation.SuppressLint import android.content.* import android.content.pm.PackageManager -import android.os.Build import android.os.Bundle import android.provider.MediaStore import android.util.Log @@ -85,12 +84,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP private fun checkShowChangelog() { try { val pInfo = packageManager.getPackageInfo(packageName, 0) - val currentVersion = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - pInfo.longVersionCode.toInt()// avoid huge version numbers and you will be ok - } else { - //noinspection deprecation - pInfo.versionCode - } + val currentVersion = pInfo.versionCode if (currentVersion != PreferenceUtil.getInstance().lastChangelogVersion) { startActivityForResult(Intent(this, WhatsNewActivity::class.java), APP_INTRO_REQUEST) } diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/UserInfoActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/UserInfoActivity.kt new file mode 100644 index 00000000..8c36a911 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/activities/UserInfoActivity.kt @@ -0,0 +1,339 @@ +package code.name.monkey.retromusic.activities + +import android.app.Activity +import android.content.* +import android.content.res.ColorStateList +import android.graphics.Bitmap +import android.net.Uri +import android.os.Bundle +import android.provider.DocumentsContract +import android.provider.MediaStore +import android.provider.MediaStore.Images.Media.getBitmap +import android.text.TextUtils +import android.view.MenuItem +import android.widget.Toast +import androidx.core.content.FileProvider +import code.name.monkey.appthemehelper.ThemeStore +import code.name.monkey.appthemehelper.util.ColorUtil +import code.name.monkey.appthemehelper.util.MaterialUtil +import code.name.monkey.appthemehelper.util.MaterialValueHelper +import code.name.monkey.retromusic.App +import code.name.monkey.retromusic.Constants.USER_BANNER +import code.name.monkey.retromusic.Constants.USER_PROFILE +import code.name.monkey.retromusic.R +import code.name.monkey.retromusic.activities.base.AbsBaseActivity +import code.name.monkey.retromusic.extensions.applyToolbar +import code.name.monkey.retromusic.util.Compressor +import code.name.monkey.retromusic.util.ImageUtil.getResizedBitmap +import code.name.monkey.retromusic.util.PreferenceUtil +import com.afollestad.materialdialogs.MaterialDialog +import com.afollestad.materialdialogs.bottomsheets.BottomSheet +import com.afollestad.materialdialogs.list.listItems +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.schedulers.Schedulers +import kotlinx.android.synthetic.main.activity_user_info.* +import java.io.File +import java.io.FileOutputStream +import java.io.IOException + +class UserInfoActivity : AbsBaseActivity() { + + private var disposable = CompositeDisposable() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_user_info) + setStatusbarColorAuto() + setNavigationbarColorAuto() + setTaskDescriptionColorAuto() + setLightNavigationBar(true) + + setupToolbar() + + MaterialUtil.setTint(nameContainer, false) + MaterialUtil.setTint(bioContainer, false) + name.setText(PreferenceUtil.getInstance().userName) + bio.setText(PreferenceUtil.getInstance().userBio) + + if (!PreferenceUtil.getInstance().profileImage.isEmpty()) { + loadImageFromStorage(PreferenceUtil.getInstance().profileImage) + } + if (!PreferenceUtil.getInstance().bannerImage.isEmpty()) { + loadBannerFromStorage(PreferenceUtil.getInstance().bannerImage) + } + userImage.setOnClickListener { + MaterialDialog(this, BottomSheet()).show { + title(text = getString(R.string.set_photo)) + listItems(items = listOf(getString(R.string.new_profile_photo), getString(R.string.remove_profile_photo))) { _, position, _ -> + when (position) { + 0 -> pickNewPhoto() + 1 -> PreferenceUtil.getInstance().saveProfileImage("") + } + } + } + } + bannerSelect.setOnClickListener { + showBannerOptions() + } + next.setOnClickListener { + val nameString = name.text.toString().trim { it <= ' ' } + if (TextUtils.isEmpty(nameString)) { + Toast.makeText(this, "Umm name is empty", Toast.LENGTH_SHORT).show() + return@setOnClickListener + } + val bioString = bio.text.toString().trim() { it <= ' ' } + if (TextUtils.isEmpty(bioString)) { + Toast.makeText(this, "Umm bio is empty", Toast.LENGTH_SHORT).show() + return@setOnClickListener + + } + PreferenceUtil.getInstance().userName = nameString + PreferenceUtil.getInstance().userBio = bioString + setResult(Activity.RESULT_OK) + finish() + } + next.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this)) + ColorStateList.valueOf(MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(ThemeStore.accentColor(this)))).apply { + next.setTextColor(this) + next.iconTint = this + } + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == android.R.id.home) { + onBackPressed() + } + return super.onOptionsItemSelected(item) + } + + private fun setupToolbar() { + val primaryColor = ThemeStore.primaryColor(this) + applyToolbar(toolbar) + appBarLayout.setBackgroundColor(primaryColor) + } + + private fun showBannerOptions() { + MaterialDialog(this, BottomSheet()).show { + title(R.string.select_banner_photo) + listItems(items = listOf(getString(R.string.new_banner_photo), getString(R.string.remove_banner_photo))) + { _, position, _ -> + when (position) { + 0 -> selectBannerImage() + 1 -> PreferenceUtil.getInstance().setBannerImagePath("") + } + } + } + } + + private fun selectBannerImage() { + + if (PreferenceUtil.getInstance().bannerImage.isEmpty()) { + val pickImageIntent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) + pickImageIntent.type = "image/*" + //pickImageIntent.putExtra("crop", "true") + pickImageIntent.putExtra("outputX", 1290) + pickImageIntent.putExtra("outputY", 720) + pickImageIntent.putExtra("aspectX", 16) + pickImageIntent.putExtra("aspectY", 9) + pickImageIntent.putExtra("scale", true) + //intent.setAction(Intent.ACTION_GET_CONTENT); + startActivityForResult(Intent.createChooser(pickImageIntent, + "Select Picture"), PICK_BANNER_REQUEST) + } else { + PreferenceUtil.getInstance().setBannerImagePath("") + bannerImage.setImageResource(android.R.color.transparent) + } + } + + + private fun pickNewPhoto() { + val pickImageIntent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) + pickImageIntent.type = "image/*" + pickImageIntent.putExtra("crop", "true") + pickImageIntent.putExtra("outputX", 512) + pickImageIntent.putExtra("outputY", 512) + pickImageIntent.putExtra("aspectX", 1) + pickImageIntent.putExtra("aspectY", 1) + pickImageIntent.putExtra("scale", true) + startActivityForResult(Intent.createChooser(pickImageIntent, "Select Picture"), PICK_IMAGE_REQUEST) + } + + public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (resultCode == Activity.RESULT_OK && data != null) { + when (requestCode) { + PICK_IMAGE_REQUEST -> { + val uri = data.data + try { + val bitmap = getResizedBitmap(getBitmap(contentResolver, uri), PROFILE_ICON_SIZE) + val profileImagePath = saveToInternalStorage(bitmap, USER_PROFILE) + PreferenceUtil.getInstance().saveProfileImage(profileImagePath) + loadImageFromStorage(profileImagePath) + } catch (e: IOException) { + e.printStackTrace() + } + } + CROP_IMAGE_REQUEST -> { + val extras: Bundle = data.extras!! + val selectedBitmap: Bitmap = extras.getParcelable("data") + val profileImagePath = saveToInternalStorage(selectedBitmap, USER_PROFILE) + PreferenceUtil.getInstance().saveProfileImage(profileImagePath) + loadImageFromStorage(profileImagePath) + } + PICK_BANNER_REQUEST -> { + val uri = data.data + try { + val bitmap = getBitmap(contentResolver, uri) + val profileImagePath = saveToInternalStorage(bitmap, USER_BANNER) + PreferenceUtil.getInstance().setBannerImagePath(profileImagePath) + loadBannerFromStorage(profileImagePath) + } catch (e: IOException) { + e.printStackTrace() + } + } + CROP_BANNER_REQUEST -> { + val extras: Bundle = data.extras!! + val selectedBitmap: Bitmap = extras.getParcelable("data") + val profileImagePath = saveToInternalStorage(selectedBitmap, USER_BANNER) + PreferenceUtil.getInstance().saveProfileImage(profileImagePath) + loadImageFromStorage(profileImagePath) + } + } + } + } + + + private fun getImagePathFromUri(aUri: Uri?): String? { + var imagePath: String? = null + if (aUri == null) { + return imagePath + } + if (DocumentsContract.isDocumentUri(App.context, aUri)) { + val documentId = DocumentsContract.getDocumentId(aUri) + if ("com.android.providers.media.documents" == aUri.authority) { + val id = documentId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1] + val selection = MediaStore.Images.Media._ID + "=" + id + imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection) + } else if ("com.android.providers.downloads.documents" == aUri.authority) { + val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), + java.lang.Long.valueOf(documentId)) + imagePath = getImagePath(contentUri, null) + } + } else if ("content".equals(aUri.scheme!!, ignoreCase = true)) { + imagePath = getImagePath(aUri, null) + } else if ("file".equals(aUri.scheme!!, ignoreCase = true)) { + imagePath = aUri.path + } + return imagePath + } + + private fun getImagePath(aUri: Uri, aSelection: String?): String? { + var path: String? = null + val cursor = App.context.contentResolver.query(aUri, null, aSelection, null, null) + if (cursor != null) { + if (cursor.moveToFirst()) { + path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)) + } + cursor.close() + } + return path + } + + private fun performBannerCrop(picturePath: Uri?) { + val photoUri = FileProvider.getUriForFile(this, "$packageName.provider", File(getImagePathFromUri(picturePath))) + try { + + val cropIntent = Intent("com.android.camera.action.CROP") + cropIntent.setDataAndType(photoUri, "image/*") + cropIntent.putExtra("crop", "true") + cropIntent.putExtra("aspectX", 1) + cropIntent.putExtra("aspectY", 1) + cropIntent.putExtra("return-data", true) + cropIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + startActivityForResult(cropIntent, CROP_BANNER_REQUEST) + } catch (anfe: ActivityNotFoundException) { + val errorMessage = "your device doesn't support the crop action!" + Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT).show() + } + } + + private fun performCrop(imageUri: Uri) { + val photoUri = FileProvider.getUriForFile(this, "$packageName.provider", File(getImagePathFromUri(imageUri))) + try { + val cropIntent = Intent("com.android.camera.action.CROP") + cropIntent.setDataAndType(photoUri, "image/*") + cropIntent.putExtra("crop", "true") + cropIntent.putExtra("aspectX", 1) + cropIntent.putExtra("aspectY", 1) + cropIntent.putExtra("outputX", 280) + cropIntent.putExtra("outputY", 280) + cropIntent.putExtra("return-data", true) + cropIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + startActivityForResult(cropIntent, CROP_IMAGE_REQUEST) + } catch (anfe: ActivityNotFoundException) { + val errorMessage = "your device doesn't support the crop action!" + Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT).show() + } + } + + private fun loadBannerFromStorage(profileImagePath: String) { + disposable.add(Compressor(this) + .setQuality(100) + .setCompressFormat(Bitmap.CompressFormat.WEBP) + .compressToBitmapAsFlowable(File(profileImagePath, USER_BANNER)) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { bitmap -> bannerImage.setImageBitmap(bitmap) }) + } + + private fun loadImageFromStorage(path: String) { + disposable.add(Compressor(this) + .setMaxHeight(300) + .setMaxWidth(300) + .setQuality(75) + .setCompressFormat(Bitmap.CompressFormat.WEBP) + .compressToBitmapAsFlowable(File(path, USER_PROFILE)) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { bitmap -> userImage!!.setImageBitmap(bitmap) }) + } + + private fun saveToInternalStorage(bitmapImage: Bitmap, userBanner: String): String { + val cw = ContextWrapper(this) + val directory = cw.getDir("imageDir", Context.MODE_PRIVATE) + val myPath = File(directory, userBanner) + var fos: FileOutputStream? = null + try { + fos = FileOutputStream(myPath) + // Use the compress method on the BitMap object to write image to the OutputStream + bitmapImage.compress(Bitmap.CompressFormat.WEBP, 100, fos) + } catch (e: Exception) { + e.printStackTrace() + } finally { + try { + fos?.close() + } catch (e: IOException) { + e.printStackTrace() + } + } + return directory.absolutePath + } + + companion object { + + private const val PICK_IMAGE_REQUEST = 9002 + private const val CROP_IMAGE_REQUEST = 9003 + private const val PICK_BANNER_REQUEST = 9004 + private const val CROP_BANNER_REQUEST = 9005 + private const val PROFILE_ICON_SIZE = 400 + } +} + +fun Activity.pickImage(requestCode: Int) { + Intent(Intent.ACTION_GET_CONTENT).apply { + addCategory(Intent.CATEGORY_OPENABLE) + type = "image/*" + startActivityForResult(this, requestCode) + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt index afd756b2..64e87c09 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt @@ -24,6 +24,7 @@ abstract class AbsThemeActivity : AbsCrashCollector(), Runnable { setTheme(PreferenceUtil.getInstance().generalTheme) hideStatusBar() super.onCreate(savedInstanceState) + //MaterialDialogsUtil.updateMaterialDialogsThemeSingleton(this) changeBackgroundShape() setImmersiveFullscreen() diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt index b1fb1815..c9778a40 100755 --- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt @@ -198,7 +198,7 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher { val songs = AlbumLoader.getAlbum(this, id).blockingFirst().songs val paths = ArrayList(songs!!.size) for (song in songs) { - paths.add(song.data) + paths.add(song.data!!) } return paths } diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/CollageSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/CollageSongAdapter.kt new file mode 100644 index 00000000..ef2dac03 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/CollageSongAdapter.kt @@ -0,0 +1,75 @@ +package code.name.monkey.retromusic.adapter + +import android.app.Activity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import code.name.monkey.appthemehelper.ThemeStore +import code.name.monkey.appthemehelper.util.ColorUtil +import code.name.monkey.appthemehelper.util.MaterialValueHelper +import code.name.monkey.retromusic.R +import code.name.monkey.retromusic.glide.GlideApp +import code.name.monkey.retromusic.glide.RetroGlideExtension +import code.name.monkey.retromusic.glide.RetroMusicColoredTarget +import code.name.monkey.retromusic.helper.MusicPlayerRemote +import code.name.monkey.retromusic.model.Song +import code.name.monkey.retromusic.adapter.CollageSongAdapter.CollageSongViewHolder +import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder +import java.util.* + +/** + * @author Hemanth S (h4h13). + */ +class CollageSongAdapter(private val activity: Activity, private val dataSet: ArrayList) : RecyclerView.Adapter() { + + override fun onBindViewHolder(holder: CollageSongViewHolder, position: Int) { + holder.bindSongs() + if (dataSet.size > 8) { + for (i in 0 until dataSet.subList(0, 8).size) { + GlideApp.with(activity) + .asBitmapPalette() + .load(RetroGlideExtension.getSongModel(dataSet[i])) + .transition(RetroGlideExtension.getDefaultTransition()) + .songOptions(dataSet[i]) + .into(object : RetroMusicColoredTarget(holder.itemView.findViewById(holder.ids[i]) as ImageView) { + override fun onColorReady(color: Int) { + + } + }) + } + } + } + + override fun getItemCount(): Int { + return 1 + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CollageSongViewHolder { + return CollageSongViewHolder(LayoutInflater.from(activity).inflate(R.layout.item_collage, parent, false)) + } + + inner class CollageSongViewHolder(itemView: View) : MediaEntryViewHolder(itemView) { + + val ids = arrayListOf(R.id.image_2, R.id.image_3, R.id.image_4, R.id.image_5, R.id.image_6, R.id.image_7, R.id.image_8, R.id.image_9) + private var textView: TextView = itemView.findViewById(R.id.image_1) + + fun bindSongs() { + for (i in ids) { + val imageView = itemView.findViewById(i) + imageView.setOnClickListener { + textView.setOnClickListener { MusicPlayerRemote.openQueue(dataSet, 0, true) } + } + } + + val context = itemView.context + val color = ThemeStore.accentColor(context); + + textView.setOnClickListener { MusicPlayerRemote.openQueue(dataSet, 0, true) } + textView.setBackgroundColor(color); + textView.setTextColor(MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color))) + } + } +} 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 1e70dc29..60839503 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 @@ -25,11 +25,11 @@ class GenreAdapter(private val mActivity: Activity, dataSet: ArrayList, p this.dataSet = dataSet } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GenreAdapter.ViewHolder { return ViewHolder(LayoutInflater.from(mActivity).inflate(mItemLayoutRes, parent, false)) } - override fun onBindViewHolder(holder: ViewHolder, position: Int) { + override fun onBindViewHolder(holder: GenreAdapter.ViewHolder, position: Int) { val genre = dataSet[position] if (holder.title != null) { holder.title!!.text = genre.name diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/SongFileAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/SongFileAdapter.kt index d4de1888..e3c18089 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/SongFileAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/SongFileAdapter.kt @@ -179,7 +179,7 @@ class SongFileAdapter(private val activity: AppCompatActivity, private var dataS private const val FOLDER = 1 fun readableFileSize(size: Long): String { - if (size <= 0) return "$size B" + if (size <= 0) return size.toString() + " B" val units = arrayOf("B", "KB", "MB", "GB", "TB") val digitGroups = (Math.log10(size.toDouble()) / Math.log10(1024.0)).toInt() return DecimalFormat("#,##0.##").format(size / Math.pow(1024.0, digitGroups.toDouble())) + " " + units[digitGroups] diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/SpanSongsAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/SpanSongsAdapter.kt new file mode 100644 index 00000000..313f65c2 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/SpanSongsAdapter.kt @@ -0,0 +1,20 @@ +package code.name.monkey.retromusic.adapter + +import androidx.appcompat.app.AppCompatActivity +import androidx.recyclerview.widget.StaggeredGridLayoutManager +import code.name.monkey.retromusic.interfaces.CabHolder +import code.name.monkey.retromusic.model.Song +import code.name.monkey.retromusic.adapter.song.SongAdapter +import java.util.* + +class SpanSongsAdapter(activity: AppCompatActivity, dataSet: ArrayList, itemLayoutRes: Int, usePalette: Boolean, cabHolder: CabHolder?) : SongAdapter(activity, dataSet, itemLayoutRes, usePalette, cabHolder) { + + override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) { + super.onBindViewHolder(holder, position) + if (position == 0) { + val params = StaggeredGridLayoutManager.LayoutParams(StaggeredGridLayoutManager.LayoutParams.WRAP_CONTENT, StaggeredGridLayoutManager.LayoutParams.MATCH_PARENT) + params.isFullSpan = true + holder.itemView.layoutParams = params + } + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt index 6094ca1e..e8465c09 100755 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt @@ -12,8 +12,6 @@ import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.retromusic.R -import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter -import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.dialogs.ClearSmartPlaylistDialog import code.name.monkey.retromusic.dialogs.DeletePlaylistDialog import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper @@ -25,6 +23,8 @@ import code.name.monkey.retromusic.model.Playlist import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist +import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter +import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.NavigationUtil import java.util.* @@ -61,6 +61,17 @@ class PlaylistAdapter(protected val activity: AppCompatActivity, dataSet: ArrayL } override fun onBindViewHolder(holder: ViewHolder, position: Int) { + /* if (getItemViewType(position) == SMART_PLAYLIST) { + if (holder.viewList != null) { + holder.viewList.get(0).setOnClickListener( + v -> NavigationUtil.goToPlaylistNew(activity, new HistoryPlaylist(activity))); + holder.viewList.get(1).setOnClickListener( + v -> NavigationUtil.goToPlaylistNew(activity, new LastAddedPlaylist(activity))); + holder.viewList.get(2).setOnClickListener( + v -> NavigationUtil.goToPlaylistNew(activity, new MyTopTracksPlaylist(activity))); + } + return; + }*/ val playlist = dataSet[position] val songs = getSongs(playlist) holder.itemView.isActivated = isChecked(playlist) diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt index abbec065..88f78b8b 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt @@ -24,7 +24,7 @@ class OrderablePlaylistSongAdapter(activity: AppCompatActivity, private val onMoveItemListener: OnMoveItemListener?) : PlaylistSongAdapter(activity, dataSet, itemLayoutRes, usePalette, cabHolder), DraggableItemAdapter { init { - setMultiSelectMenuRes(R.menu.menu_playlists_songs_selection) + setMultiSelectMenuRes(code.name.monkey.retromusic.R.menu.menu_playlists_songs_selection) } override fun createViewHolder(view: View): SongAdapter.ViewHolder { @@ -92,7 +92,7 @@ class OrderablePlaylistSongAdapter(activity: AppCompatActivity, private var mDragStateFlags: Int = 0 override var songMenuRes: Int - get() = R.menu.menu_item_playlist_song + get() = code.name.monkey.retromusic.R.menu.menu_item_playlist_song set(value) { super.songMenuRes = value } @@ -109,7 +109,7 @@ class OrderablePlaylistSongAdapter(activity: AppCompatActivity, override fun onSongMenuItemClick(item: MenuItem): Boolean { when (item.itemId) { - R.id.action_remove_from_playlist -> { + code.name.monkey.retromusic.R.id.action_remove_from_playlist -> { RemoveFromPlaylistDialog.create(song as PlaylistSong).show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST") return true } diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlaylistSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlaylistSongAdapter.kt index 56838b22..b39a0823 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlaylistSongAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlaylistSongAdapter.kt @@ -32,6 +32,7 @@ open class PlaylistSongAdapter(activity: AppCompatActivity, dataSet: ArrayList(), GenreContract.GenreView { + + private var mPresenter: GenrePresenter? = null + + override val emptyMessage: Int + get() = R.string.no_genres + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setHasOptionsMenu(true) + mPresenter = GenrePresenter(this) + } + + override fun setMenuVisibility(menuVisible: Boolean) { + super.setMenuVisibility(menuVisible) + if (menuVisible) { + libraryFragment.setTitle(if (PreferenceUtil.getInstance().tabTitles()) R.string.library else R.string.genres) + } + } + + override fun onResume() { + super.onResume() + libraryFragment.setTitle(if (PreferenceUtil.getInstance().tabTitles()) R.string.library else R.string.genres) + if (adapter!!.dataSet.isEmpty()) { + mPresenter!!.subscribe() + } + } + + + override fun onDestroy() { + super.onDestroy() + mPresenter!!.unsubscribe() + } + + override fun createLayoutManager(): LinearLayoutManager { + return LinearLayoutManager(activity) + } + + override fun createAdapter(): GenreAdapter { + val dataSet = adapter!!.dataSet + return GenreAdapter(libraryFragment.mainActivity, dataSet, R.layout.item_list) + } + + override fun loading() { + + } + + override fun showData(list: ArrayList) { + adapter!!.swapDataSet(list) + } + + override fun showEmptyView() { + adapter!!.swapDataSet(ArrayList()) + } + + override fun completed() { + + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + super.onCreateOptionsMenu(menu, inflater) + menu.removeItem(R.id.action_sort_order) + menu.removeItem(R.id.action_grid_size) + menu.removeItem(R.id.action_new_playlist) + } + + companion object { + + fun newInstance(): GenreFragment { + val args = Bundle() + val fragment = GenreFragment() + fragment.arguments = args + return fragment + } + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/LibraryFragment.java b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/LibraryFragment.java index 7819f304..50b3dd1e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/LibraryFragment.java +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/LibraryFragment.java @@ -148,7 +148,6 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde appBarLayout.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> getMainActivity().setLightStatusbar(!ATHUtil.INSTANCE.isWindowBackgroundDark(getContext()))); getMainActivity().setSupportActionBar(toolbar); - } private Fragment getCurrentFragment() { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/SongsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/SongsFragment.kt index 534b76ec..6fe1aae2 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/SongsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/SongsFragment.kt @@ -2,13 +2,14 @@ package code.name.monkey.retromusic.fragments.mainactivity import android.os.Bundle import androidx.recyclerview.widget.GridLayoutManager + import code.name.monkey.retromusic.R -import code.name.monkey.retromusic.adapter.song.ShuffleButtonSongAdapter -import code.name.monkey.retromusic.adapter.song.SongAdapter -import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.mvp.contract.SongContract import code.name.monkey.retromusic.mvp.presenter.SongPresenter +import code.name.monkey.retromusic.adapter.song.ShuffleButtonSongAdapter +import code.name.monkey.retromusic.adapter.song.SongAdapter +import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment import code.name.monkey.retromusic.util.PreferenceUtil import java.util.* @@ -127,7 +128,7 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment() + when (timeOfDay) { + in 0..5 -> images = resources.getStringArray(R.array.night) + in 6..11 -> images = resources.getStringArray(R.array.morning) + in 12..15 -> images = resources.getStringArray(R.array.after_noon) + in 16..19 -> images = resources.getStringArray(R.array.evening) + in 20..23 -> images = resources.getStringArray(R.array.night) + } + + val day = images[Random().nextInt(images.size)] + loadTimeImage(day) + } + + + private fun loadTimeImage(day: String) { + if (bannerImage != null) { + if (PreferenceUtil.getInstance().bannerImage.isEmpty()) { + GlideApp.with(activity!!) + .load(day) + .placeholder(R.drawable.material_design_default) + .diskCacheStrategy(DiskCacheStrategy.ALL) + .into(bannerImage!!) + } else { + disposable.add(Compressor(context!!) + .setQuality(100) + .setCompressFormat(Bitmap.CompressFormat.WEBP) + .compressToBitmapAsFlowable(File(PreferenceUtil.getInstance().bannerImage, USER_BANNER)) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { bannerImage!!.setImageBitmap(it) }) + } + } + } + companion object { const val TAG: String = "BannerHomeFragment" 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 09120b1d..3529b55c 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 @@ -19,8 +19,6 @@ import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.retromusic.R -import code.name.monkey.retromusic.activities.LyricsActivity -import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.RetroGlideExtension import code.name.monkey.retromusic.glide.RetroMusicColoredTarget @@ -28,6 +26,8 @@ import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.lyrics.Lyrics +import code.name.monkey.retromusic.activities.LyricsActivity +import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.ViewUtil diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlayerFragment.kt index e19b6369..1a83b67b 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlayerFragment.kt @@ -101,6 +101,8 @@ class FlatPlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbac callbacks!!.onPaletteColorChanged() val isLight = ColorUtil.isColorLight(color) + + //TransitionManager.beginDelayedTransition(mToolbar); val iconColor = if (PreferenceUtil.getInstance().adaptiveColor) MaterialValueHelper.getPrimaryTextColor(context!!, isLight) else diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/normal/PlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/normal/PlayerFragment.kt index 952883f0..dfea11f7 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/normal/PlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/normal/PlayerFragment.kt @@ -12,10 +12,10 @@ import androidx.appcompat.widget.Toolbar import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.retromusic.R -import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment -import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.model.Song +import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment +import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.views.DrawableGradient @@ -101,8 +101,20 @@ class PlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks { super.onViewCreated(view, savedInstanceState) setUpSubFragments() setUpPlayerToolbar() + snowfall.visibility = if (PreferenceUtil.getInstance().isSnowFall) View.VISIBLE else View.GONE + + + //val display = activity?.windowManager?.defaultDisplay + //val outMetrics = DisplayMetrics() + //display?.getMetrics(outMetrics) + + //val density = resources.displayMetrics.density + //val dpWidth = outMetrics.widthPixels / density + + //playerAlbumCoverContainer?.layoutParams?.height = RetroUtil.convertDpToPixel((dpWidth - getCutOff()), context!!).toInt() } + private fun setUpSubFragments() { playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as PlayerPlaybackControlsFragment diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/slide/SlidePlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/slide/SlidePlayerFragment.kt new file mode 100644 index 00000000..afe71387 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/slide/SlidePlayerFragment.kt @@ -0,0 +1,332 @@ +/* + * 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.fragments.player.slide + +import android.animation.ObjectAnimator +import android.graphics.Color +import android.graphics.PorterDuff +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.animation.LinearInterpolator +import android.widget.SeekBar +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.Toolbar +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.LinearSmoothScroller +import androidx.recyclerview.widget.RecyclerView +import code.name.monkey.appthemehelper.ThemeStore +import code.name.monkey.appthemehelper.util.* +import code.name.monkey.retromusic.R +import code.name.monkey.retromusic.glide.GlideApp +import code.name.monkey.retromusic.glide.RetroGlideExtension +import code.name.monkey.retromusic.glide.RetroMusicColoredTarget +import code.name.monkey.retromusic.helper.MusicPlayerRemote +import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper +import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler +import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener +import code.name.monkey.retromusic.model.Song +import code.name.monkey.retromusic.service.MusicService +import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity +import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter +import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment +import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment +import code.name.monkey.retromusic.util.MusicUtil +import code.name.monkey.retromusic.util.PreferenceUtil +import code.name.monkey.retromusic.util.ViewUtil +import kotlinx.android.synthetic.main.fragment_slide_player.* + +/** + * Created by hemanths on 3/15/19 + */ +class SlidePlayerFragment : AbsPlayerFragment(), MusicProgressViewUpdateHelper.Callback { + private var lastColor: Int = 0 + override val paletteColor: Int + get() = lastColor + + override fun playerToolbar(): Toolbar { + return playerToolbar + } + + override fun onShow() { + + } + + override fun onHide() { + + } + + override fun onBackPressed(): Boolean { + return false + } + + override fun toolbarIconColor(): Int { + return Color.WHITE + } + + override fun onColorChanged(color: Int) { + + } + + override fun onFavoriteToggled() { + toggleFavorite(MusicPlayerRemote.currentSong) + } + + override fun toggleFavorite(song: Song) { + super.toggleFavorite(song) + if (song.id == MusicPlayerRemote.currentSong.id) { + updateIsFavorite() + } + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.fragment_slide_player, container, false) + } + + override fun onResume() { + super.onResume() + progressViewUpdateHelper.start() + } + + override fun onPause() { + super.onPause() + progressViewUpdateHelper.stop() + } + + + override fun onPlayingMetaChanged() { + super.onPlayingMetaChanged() + updateSong() + updateIsFavorite() + } + + override fun onQueueChanged() { + super.onQueueChanged() + updateQueue() + } + + override fun onServiceConnected() { + updatePlayPauseDrawableState() + updateRepeatState() + updateShuffleState() + updateSong() + updateIsFavorite() + updateQueue() + } + + private fun updateQueue() { + songAdapter.swapDataSet(MusicPlayerRemote.playingQueue) + } + + + + + private fun updatePlayPauseDrawableState() { + if (MusicPlayerRemote.isPlaying) { + albumCoverContainer.cardElevation = 24.0f + playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp) + } else { + albumCoverContainer.cardElevation = 0.0f + playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp) + } + } + + fun updateRepeatState() { + when (MusicPlayerRemote.repeatMode) { + MusicService.REPEAT_MODE_NONE -> { + repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp) + repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + } + MusicService.REPEAT_MODE_ALL -> { + repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp) + repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + } + MusicService.REPEAT_MODE_THIS -> { + repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp) + repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + } + } + } + + fun updateShuffleState() { + when (MusicPlayerRemote.shuffleMode) { + MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + } + } + + + private fun updateSong() { + val song = MusicPlayerRemote.currentSong + title.text = song.title + text.text = song.artistName + + GlideApp.with(activity!!).asBitmapPalette() + .load(RetroGlideExtension.getSongModel(song)) + .songOptions(song) + .transition(RetroGlideExtension.getDefaultTransition()) + .into(object : RetroMusicColoredTarget(playerImage) { + override fun onColorReady(color: Int) { + setColor(color) + } + }) + } + + private fun setColor(color: Int) { + lastColor = color + val colorBg = ATHUtil.resolveColor(context!!, android.R.attr.colorBackground) + if (ColorUtil.isColorLight(colorBg)) { + lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(context!!, true) + lastDisabledPlaybackControlsColor = MaterialValueHelper.getSecondaryDisabledTextColor(context!!, true) + } else { + lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(context!!, false) + lastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(context!!, false) + } + + val colorFinal = if (PreferenceUtil.getInstance().adaptiveColor) { + color + } else { + ThemeStore.accentColor(context!!) + } + + + text.setTextColor(colorFinal) + playerQueueSubHeader.setTextColor(colorFinal) + TintHelper.setTintAuto(playPauseButton, lastPlaybackControlsColor, false) + ViewUtil.setProgressDrawable(progressSlider, colorFinal) + + updateRepeatState() + updateShuffleState() + updatePrevNextColor() + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setUpMusicControllers() + setUpPlayerToolbar() + (activity as AbsSlidingMusicPanelActivity).setAntiDragView(recyclerView) + playerQueueSubHeader.setTextColor(ThemeStore.accentColor(context!!)) + } + + private fun setUpMusicControllers() { + setUpPlayPauseFab() + setUpPrevNext() + setUpRepeatButton() + setUpShuffleButton() + setUpProgressSlider() + setUpRecyclerView() + } + + private lateinit var songAdapter: SimpleSongAdapter + + private fun setUpRecyclerView() { + songAdapter = SimpleSongAdapter(context = activity as AppCompatActivity, + songs = ArrayList(), i = R.layout.item_song, useNumbers = true) + recyclerView.apply { + adapter = songAdapter + layoutManager = LinearLayoutManager(context) + } + } + + private fun setUpProgressSlider() { + progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() { + override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { + if (fromUser) { + MusicPlayerRemote.seekTo(progress) + onUpdateProgressViews(MusicPlayerRemote.songProgressMillis, MusicPlayerRemote.songDurationMillis) + } + } + }) + } + + override fun onUpdateProgressViews(progress: Int, total: Int) { + progressSlider.max = total + + val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress) + animator.duration = AbsPlayerControlsFragment.SLIDER_ANIMATION_TIME + animator.interpolator = LinearInterpolator() + animator.start() + + songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong()) + songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong()) + } + + private fun setUpPlayPauseFab() { + playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler()) + } + + private fun setUpRepeatButton() { + repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() } + } + + private fun setUpShuffleButton() { + shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() } + } + + private fun setUpPrevNext() { + updatePrevNextColor() + nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() } + previousButton.setOnClickListener { MusicPlayerRemote.back() } + } + + private fun updatePrevNextColor() { + nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + } + + private var lastPlaybackControlsColor: Int = 0 + private var lastDisabledPlaybackControlsColor: Int = 0 + private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper + + override fun onPlayStateChanged() { + updatePlayPauseDrawableState() + } + + override fun onRepeatModeChanged() { + updateRepeatState() + } + + override fun onShuffleModeChanged() { + updateShuffleState() + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + progressViewUpdateHelper = MusicProgressViewUpdateHelper(this) + } + + private fun setUpPlayerToolbar() { + playerToolbar.inflateMenu(R.menu.menu_player) + playerToolbar.setNavigationOnClickListener { activity!!.onBackPressed() } + playerToolbar.setOnMenuItemClickListener(this) + + ToolbarContentTintHelper.colorizeToolbar(playerToolbar, Color.WHITE, activity) + } + + fun RecyclerView.smoothSnapToPosition(position: Int, snapMode: Int = LinearSmoothScroller.SNAP_TO_START) { + val smoothScroller = object : LinearSmoothScroller(this.context) { + override fun getVerticalSnapPreference(): Int { + return snapMode + } + + override fun getHorizontalSnapPreference(): Int { + return snapMode + } + } + smoothScroller.targetPosition = position + this.layoutManager?.startSmoothScroll(smoothScroller) + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/tiny/TinyPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/tiny/TinyPlaybackControlsFragment.kt index 74f350bb..09043a6e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/tiny/TinyPlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/tiny/TinyPlaybackControlsFragment.kt @@ -8,9 +8,9 @@ import android.view.ViewGroup import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.retromusic.R -import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.service.MusicService +import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment import kotlinx.android.synthetic.main.fragment_tiny_controls_fragment.* class TinyPlaybackControlsFragment : AbsPlayerControlsFragment() { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/tiny/TinyPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/tiny/TinyPlayerFragment.kt index 170abcb4..51ec79ee 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/tiny/TinyPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/tiny/TinyPlayerFragment.kt @@ -14,13 +14,13 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.retromusic.R -import code.name.monkey.retromusic.fragments.MiniPlayerFragment -import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment -import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler import code.name.monkey.retromusic.model.Song +import code.name.monkey.retromusic.fragments.MiniPlayerFragment +import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment +import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.PreferenceUtil import kotlinx.android.synthetic.main.fragment_tiny_player.* diff --git a/app/src/main/java/code/name/monkey/retromusic/interfaces/MainActivityFragmentCallbacks.kt b/app/src/main/java/code/name/monkey/retromusic/interfaces/MainActivityFragmentCallbacks.kt index cf8172aa..e85cc827 100644 --- a/app/src/main/java/code/name/monkey/retromusic/interfaces/MainActivityFragmentCallbacks.kt +++ b/app/src/main/java/code/name/monkey/retromusic/interfaces/MainActivityFragmentCallbacks.kt @@ -20,4 +20,6 @@ package code.name.monkey.retromusic.interfaces interface MainActivityFragmentCallbacks { fun handleBackPress(): Boolean + + //void selectedFragment(Fragment fragment); } diff --git a/app/src/main/java/code/name/monkey/retromusic/loaders/AlbumLoader.kt b/app/src/main/java/code/name/monkey/retromusic/loaders/AlbumLoader.kt index e489ce0c..e1949a08 100644 --- a/app/src/main/java/code/name/monkey/retromusic/loaders/AlbumLoader.kt +++ b/app/src/main/java/code/name/monkey/retromusic/loaders/AlbumLoader.kt @@ -102,6 +102,7 @@ open class AlbumLoader { private fun getSongLoaderSortOrder(): String { return PreferenceUtil.getInstance().albumSortOrder + ", " + + //PreferenceUtil.getInstance().getAlbumSongSortOrder() + "," + PreferenceUtil.getInstance().albumDetailSongSortOrder } } diff --git a/app/src/main/java/code/name/monkey/retromusic/misc/CustomFragmentStatePagerAdapter.java b/app/src/main/java/code/name/monkey/retromusic/misc/CustomFragmentStatePagerAdapter.java index 31ce1874..f9e68b65 100644 --- a/app/src/main/java/code/name/monkey/retromusic/misc/CustomFragmentStatePagerAdapter.java +++ b/app/src/main/java/code/name/monkey/retromusic/misc/CustomFragmentStatePagerAdapter.java @@ -16,10 +16,6 @@ package code.name.monkey.retromusic.misc; import android.os.Bundle; import android.os.Parcelable; -import android.util.Log; -import android.view.View; -import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; @@ -27,6 +23,10 @@ import androidx.fragment.app.FragmentPagerAdapter; import androidx.fragment.app.FragmentTransaction; import androidx.viewpager.widget.PagerAdapter; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; + import java.util.ArrayList; /** diff --git a/app/src/main/java/code/name/monkey/retromusic/misc/DisposableManager.kt b/app/src/main/java/code/name/monkey/retromusic/misc/DisposableManager.kt new file mode 100644 index 00000000..2102843e --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/misc/DisposableManager.kt @@ -0,0 +1,38 @@ +/* + * 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.misc + +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.disposables.Disposable + +object DisposableManager { + + private var compositeDisposable: CompositeDisposable? = null + + fun add(disposable: Disposable) { + getCompositeDisposable().add(disposable) + } + + fun dispose() { + getCompositeDisposable().dispose() + } + + private fun getCompositeDisposable(): CompositeDisposable { + if (compositeDisposable == null || compositeDisposable!!.isDisposed) { + compositeDisposable = CompositeDisposable() + } + return compositeDisposable!! + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/misc/DisposingObserver.kt b/app/src/main/java/code/name/monkey/retromusic/misc/DisposingObserver.kt new file mode 100644 index 00000000..dcb3c8ac --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/misc/DisposingObserver.kt @@ -0,0 +1,32 @@ +/* + * 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.misc + +import androidx.annotation.CallSuper +import io.reactivex.Observer +import io.reactivex.disposables.Disposable + +class DisposingObserver : Observer { + @CallSuper + override fun onSubscribe(d: Disposable) { + DisposableManager.add(d) + } + + override fun onNext(next: T) {} + + override fun onError(e: Throwable) {} + + override fun onComplete() {} +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/misc/ScrollAwareFABBehavior.java b/app/src/main/java/code/name/monkey/retromusic/misc/ScrollAwareFABBehavior.java new file mode 100644 index 00000000..7f416f69 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/misc/ScrollAwareFABBehavior.java @@ -0,0 +1,90 @@ +/* + * 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.misc; + +import android.content.Context; +import android.os.Handler; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.view.animation.LinearInterpolator; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; + +import androidx.annotation.NonNull; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.view.ViewCompat; + +/*Don't delete even if its not showing not using*/ +public class ScrollAwareFABBehavior extends CoordinatorLayout.Behavior { + private static final String TAG = "ScrollingFABBehavior"; + Handler mHandler; + + public ScrollAwareFABBehavior(Context context, AttributeSet attrs) { + super(); + } + + @Override + public void onStopNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, + @NonNull FloatingActionButton child, + @NonNull View target) { + super.onStopNestedScroll(coordinatorLayout, child, target); + + if (mHandler == null) + mHandler = new Handler(); + + + mHandler.postDelayed(() -> { + child.animate().translationY(0).setInterpolator(new LinearInterpolator()).start(); + Log.d("FabAnim", "startHandler()"); + }, 1000); + + } + + @Override + public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, + @NonNull FloatingActionButton child, + @NonNull View target, + int dxConsumed, + int dyConsumed, + int dxUnconsumed, + int dyUnconsumed) { + super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed); + + //child -> Floating Action Button + if (dyConsumed > 0) { + Log.d("Scrolling", "Up"); + CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams(); + int fab_bottomMargin = layoutParams.bottomMargin; + child.animate().translationY(child.getHeight() + fab_bottomMargin).setInterpolator(new LinearInterpolator()).start(); + } else if (dyConsumed < 0) { + Log.d("Scrolling", "down"); + child.animate().translationY(0).setInterpolator(new LinearInterpolator()).start(); + } + } + + @Override + public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, + @NonNull FloatingActionButton child, + @NonNull View directTargetChild, + @NonNull View target, + int nestedScrollAxes) { + if (mHandler != null) { + mHandler.removeMessages(0); + Log.d("Scrolling", "stopHandler()"); + } + return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL; + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/misc/SimpleAnimatorListener.kt b/app/src/main/java/code/name/monkey/retromusic/misc/SimpleAnimatorListener.kt new file mode 100644 index 00000000..2ee76b78 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/misc/SimpleAnimatorListener.kt @@ -0,0 +1,36 @@ +/* + * 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.misc + +import android.animation.Animator + + +abstract class SimpleAnimatorListener : Animator.AnimatorListener { + override fun onAnimationStart(animation: Animator) { + + } + + override fun onAnimationEnd(animation: Animator) { + + } + + override fun onAnimationCancel(animation: Animator) { + + } + + override fun onAnimationRepeat(animation: Animator) { + + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/misc/SpacesItemDecoration.java b/app/src/main/java/code/name/monkey/retromusic/misc/SpacesItemDecoration.java new file mode 100644 index 00000000..984bba15 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/misc/SpacesItemDecoration.java @@ -0,0 +1,35 @@ +/* + * 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.misc; + +import android.graphics.Rect; +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +public class SpacesItemDecoration extends RecyclerView.ItemDecoration { + private int space; + + public SpacesItemDecoration(int space) { + this.space = space; + } + + @Override + public void getItemOffsets(Rect outRect, View view, + RecyclerView parent, RecyclerView.State state) { + outRect.right = space; + outRect.bottom = space; + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/contract/AlbumContract.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/contract/AlbumContract.kt index bca9e950..c5a04136 100644 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/contract/AlbumContract.kt +++ b/app/src/main/java/code/name/monkey/retromusic/mvp/contract/AlbumContract.kt @@ -18,9 +18,6 @@ import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.mvp.BasePresenter import code.name.monkey.retromusic.mvp.BaseView import java.util.ArrayList -/** - * Created by hemanths on 16/08/17. - */ interface AlbumContract { diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/contract/AlbumDetailsContract.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/contract/AlbumDetailsContract.kt index 0ad215dd..f94af5ab 100644 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/contract/AlbumDetailsContract.kt +++ b/app/src/main/java/code/name/monkey/retromusic/mvp/contract/AlbumDetailsContract.kt @@ -19,10 +19,6 @@ import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.mvp.BasePresenter import code.name.monkey.retromusic.mvp.BaseView -/** - * Created by hemanths on 16/08/17. - */ - interface AlbumDetailsContract { interface AlbumDetailsView : BaseView diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/contract/HomeContract.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/contract/HomeContract.kt index 56fda999..34e84795 100644 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/contract/HomeContract.kt +++ b/app/src/main/java/code/name/monkey/retromusic/mvp/contract/HomeContract.kt @@ -17,9 +17,6 @@ package code.name.monkey.retromusic.mvp.contract import code.name.monkey.retromusic.model.Home import code.name.monkey.retromusic.mvp.BasePresenter import code.name.monkey.retromusic.mvp.BaseView -/** - * Created by hemanths on 16/08/17. - */ interface HomeContract { diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistPresenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistPresenter.kt index a05d607d..f7763d0a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistPresenter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistPresenter.kt @@ -19,10 +19,6 @@ import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.contract.ArtistContract import java.util.* -/** - * Created by hemanths on 16/08/17. - */ - class ArtistPresenter(private val mView: ArtistContract.ArtistView) : Presenter(), ArtistContract.Presenter { override fun subscribe() { diff --git a/app/src/main/java/code/name/monkey/retromusic/providers/NotPlayedStore.kt b/app/src/main/java/code/name/monkey/retromusic/providers/NotPlayedStore.kt new file mode 100644 index 00000000..7d96e075 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/providers/NotPlayedStore.kt @@ -0,0 +1,82 @@ +/* + * 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.providers + +import android.content.ContentValues +import android.content.Context +import android.database.sqlite.SQLiteDatabase +import android.database.sqlite.SQLiteOpenHelper +import code.name.monkey.retromusic.loaders.SongLoader +import code.name.monkey.retromusic.model.Song +import io.reactivex.schedulers.Schedulers + +class NotPlayedStore(val context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, VERSION) { + + private val dataBaseCreate = "CREATE TABLE IF NOT EXISTS $NAME ( $ID LONG PRIMARY KEY )" + + override fun onCreate(db: SQLiteDatabase) { + db.execSQL(dataBaseCreate) + } + + override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { + db.execSQL("DROP TABLE IF EXISTS $NAME") + } + + fun removeSong(id: Long) { + val db = writableDatabase + db.apply { + beginTransaction() + delete(NAME, "$ID = $id", null) + setTransactionSuccessful() + endTransaction() + close() + } + } + + fun addAllSongs(songs: ArrayList) { + SongLoader.getAllSongs(context) + .map { + val database = writableDatabase; + database.apply { + val contentValues = ContentValues() + for (song in songs) { + contentValues.put(ID, song.id) + insert(NAME, null, contentValues) + } + setTransactionSuccessful() + endTransaction() + } + return@map true + } + .subscribeOn(Schedulers.io()) + .subscribe() + } + + companion object { + const val NAME = "not_played_songs" + const val ID = "song_id" + const val DATABASE_NAME = "not_played.db" + private const val VERSION = 1 + private var sInstance: NotPlayedStore? = null + + @Synchronized + fun getInstance(context: Context): NotPlayedStore { + if (sInstance == null) { + sInstance = NotPlayedStore(context.applicationContext) + } + return sInstance!! + } + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/rest/KogouClient.java b/app/src/main/java/code/name/monkey/retromusic/rest/KogouClient.java new file mode 100644 index 00000000..c2ca1d63 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/rest/KogouClient.java @@ -0,0 +1,89 @@ + +/* + * 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.rest; + +import android.content.Context; + +import java.io.File; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import code.name.monkey.retromusic.App; +import code.name.monkey.retromusic.rest.service.KuGouApiService; +import okhttp3.Cache; +import okhttp3.Call; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; + +import static code.name.monkey.retromusic.Constants.BASE_API_URL_KUGOU; + +/** + * Created by hemanths on 23/08/17. + */ + +public class KogouClient { + + private static final String BASE_URL = BASE_API_URL_KUGOU; + + private KuGouApiService apiService; + + public KogouClient() { + this(createDefaultOkHttpClientBuilder().build()); + } + + private KogouClient(@NonNull Call.Factory client) { + Retrofit restAdapter = new Retrofit.Builder() + .baseUrl(BASE_URL) + .callFactory(client) + .addConverterFactory(GsonConverterFactory.create()) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) + .build(); + + apiService = restAdapter.create(KuGouApiService.class); + } + + @Nullable + private static Cache createDefaultCache(Context context) { + File cacheDir = new File(context.getCacheDir().getAbsolutePath(), "/okhttp-lastfm/"); + if (cacheDir.mkdirs() || cacheDir.isDirectory()) { + return new Cache(cacheDir, 1024 * 1024 * 10); + } + return null; + } + + private static Interceptor createCacheControlInterceptor() { + return chain -> { + Request modifiedRequest = chain.request().newBuilder() + .addHeader("Cache-Control", String.format("max-age=%d, max-stale=%d", 31536000, 31536000)) + .build(); + return chain.proceed(modifiedRequest); + }; + } + + private static OkHttpClient.Builder createDefaultOkHttpClientBuilder() { + return new OkHttpClient.Builder() + .cache(createDefaultCache(App.Companion.getInstance())) + .addInterceptor(createCacheControlInterceptor()); + } + + public KuGouApiService getApiService() { + return apiService; + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/rest/model/KuGouRawLyric.java b/app/src/main/java/code/name/monkey/retromusic/rest/model/KuGouRawLyric.java new file mode 100644 index 00000000..e4e491f5 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/rest/model/KuGouRawLyric.java @@ -0,0 +1,55 @@ +/* + * 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.rest.model; + +import com.google.gson.annotations.SerializedName; + +/** + * Created by hefuyi on 2017/1/20. + */ + +public class KuGouRawLyric { + + private static final String CHARSET = "charset"; + private static final String CONTENT = "content"; + private static final String FMT = "fmt"; + private static final String INFO = "info"; + private static final String STATUS = "status"; + + @SerializedName(CHARSET) + public String charset; + + @SerializedName(CONTENT) + public String content; + + @SerializedName(FMT) + public String fmt; + @SerializedName(INFO) + public String info; + @SerializedName(STATUS) + public int status; + + @Override + public String toString() { + return "KuGouRawLyric{" + + "charset='" + charset + '\'' + + ", content='" + content + '\'' + + ", fmt='" + fmt + '\'' + + ", info='" + info + '\'' + + ", status=" + status + + '}'; + } + +} diff --git a/app/src/main/java/code/name/monkey/retromusic/rest/model/KuGouSearchLyricResult.java b/app/src/main/java/code/name/monkey/retromusic/rest/model/KuGouSearchLyricResult.java new file mode 100644 index 00000000..3667ac05 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/rest/model/KuGouSearchLyricResult.java @@ -0,0 +1,110 @@ +/* + * 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.rest.model; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +import androidx.annotation.NonNull; + +/** + * Created by hefuyi on 2017/1/20. + */ + +public class KuGouSearchLyricResult { + + private static final String INFO = "info"; + private static final String STATUS = "status"; + private static final String PROPOSAL = "proposal"; + private static final String KEYWORD = "keyword"; + private static final String CANDIDATES = "candidates"; + + @NonNull + @SerializedName(INFO) + public String info; + + @SerializedName(STATUS) + public int status; + + @NonNull + @SerializedName(PROPOSAL) + public String proposal; + + @NonNull + @SerializedName(KEYWORD) + public String keyword; + + @NonNull + @SerializedName(CANDIDATES) + public List candidates; + + @Override + public String toString() { + return "KuGouSearchLyricResult{" + + "info='" + info + '\'' + + ", status=" + status + + ", proposal='" + proposal + '\'' + + ", keyword='" + keyword + '\'' + + ", candidates=" + candidates + + '}'; + } + + public static class Candidates { + private static final String NICKNAME = "nickname"; + private static final String ACCESSKEY = "accesskey"; + private static final String SCORE = "score"; + private static final String DURATION = "duration"; + private static final String UID = "uid"; + private static final String SONG = "song"; + private static final String ID = "id"; + private static final String SINGER = "singer"; + private static final String LANGUAGE = "language"; + @SerializedName(NICKNAME) + public String nickname; + @SerializedName(ACCESSKEY) + public String accesskey; + @SerializedName(SCORE) + public int score; + @SerializedName(DURATION) + public long duration; + @SerializedName(UID) + public String uid; + @SerializedName(SONG) + public String songName; + @SerializedName(ID) + public String id; + @SerializedName(SINGER) + public String singer; + @SerializedName(LANGUAGE) + public String language; + + @Override + public String toString() { + return "Candidates{" + + "nickname='" + nickname + '\'' + + ", accesskey='" + accesskey + '\'' + + ", score=" + score + + ", duration=" + duration + + ", uid='" + uid + '\'' + + ", songName='" + songName + '\'' + + ", id='" + id + '\'' + + ", singer='" + singer + '\'' + + ", language='" + language + '\'' + + '}'; + } + + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/rest/service/KuGouApiService.java b/app/src/main/java/code/name/monkey/retromusic/rest/service/KuGouApiService.java new file mode 100644 index 00000000..ff82ecaa --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/rest/service/KuGouApiService.java @@ -0,0 +1,38 @@ +/* + * 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.rest.service; + +import androidx.annotation.NonNull; +import code.name.monkey.retromusic.rest.model.KuGouRawLyric; +import code.name.monkey.retromusic.rest.model.KuGouSearchLyricResult; + +import io.reactivex.Observable; +import retrofit2.http.GET; +import retrofit2.http.Query; + +/** + * Created by hemanths on 28/07/17. + */ + +public interface KuGouApiService { + + @NonNull + @GET("search?ver=1&man=yes&client=pc") + Observable searchLyric(@Query("keyword") @NonNull String songName, @Query("duration") @NonNull String duration); + + @NonNull + @GET("download?ver=1&client=pc&fmt=lrc&charset=utf8") + Observable getRawLyric(@Query("id") @NonNull String id, @Query("accesskey") @NonNull String accesskey); +} diff --git a/app/src/main/java/code/name/monkey/retromusic/transform/RoundStackTransformer.java b/app/src/main/java/code/name/monkey/retromusic/transform/RoundStackTransformer.java new file mode 100644 index 00000000..abeb39e1 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/transform/RoundStackTransformer.java @@ -0,0 +1,30 @@ +/* + * 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.transform; + +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.viewpager.widget.ViewPager; + +/** + * Created by hemanths on 3/9/19 + */ +public class RoundStackTransformer implements ViewPager.PageTransformer { + @Override + public void transformPage(@NonNull View page, float position) { + + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/transform/StackPagerTransformer.kt b/app/src/main/java/code/name/monkey/retromusic/transform/StackPagerTransformer.kt new file mode 100644 index 00000000..8215c423 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/transform/StackPagerTransformer.kt @@ -0,0 +1,47 @@ +/* + * 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.transform + +import android.view.View +import androidx.viewpager.widget.ViewPager + +class StackPagerTransformer : ViewPager.PageTransformer { + + + override fun transformPage(view: View, position: Float) { + + if (position < -1f) { + view.translationX = view.width * position + } + + if (position < 0f) { + view.translationX = 0f + view.scaleX = 1f + view.scaleY = 1f + + } else if (position <= 1f) { + + val scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)) + view.pivotY = 0.5f * view.height + view.translationX = view.width * -position + view.scaleX = scaleFactor + view.scaleY = scaleFactor + } + } + + companion object { + private val MIN_SCALE = 0.75f + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/util/Compressor.java b/app/src/main/java/code/name/monkey/retromusic/util/Compressor.java new file mode 100644 index 00000000..a684fc8b --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/util/Compressor.java @@ -0,0 +1,104 @@ +/* + * 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.util; + +import android.content.Context; +import android.graphics.Bitmap; + +import java.io.File; +import java.io.IOException; + +import io.reactivex.Flowable; + +/** + * Created on : June 18, 2016 + * Author : zetbaitsu + * Name : Zetra + * GitHub : https://github.com/zetbaitsu + */ +public class Compressor { + //max width and height values of the compressed image is taken as 612x816 + private int maxWidth = 612; + private int maxHeight = 816; + private Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.JPEG; + private int quality = 80; + private String destinationDirectoryPath; + + public Compressor(Context context) { + destinationDirectoryPath = context.getCacheDir().getPath() + File.separator + "images"; + } + + public Compressor setMaxWidth(int maxWidth) { + this.maxWidth = maxWidth; + return this; + } + + public Compressor setMaxHeight(int maxHeight) { + this.maxHeight = maxHeight; + return this; + } + + public Compressor setCompressFormat(Bitmap.CompressFormat compressFormat) { + this.compressFormat = compressFormat; + return this; + } + + public Compressor setQuality(int quality) { + this.quality = quality; + return this; + } + + public Compressor setDestinationDirectoryPath(String destinationDirectoryPath) { + this.destinationDirectoryPath = destinationDirectoryPath; + return this; + } + + public File compressToFile(File imageFile) throws IOException { + return compressToFile(imageFile, imageFile.getName()); + } + + public File compressToFile(File imageFile, String compressedFileName) throws IOException { + return ImageUtil.compressImage(imageFile, maxWidth, maxHeight, compressFormat, quality, + destinationDirectoryPath + File.separator + compressedFileName); + } + + public Bitmap compressToBitmap(File imageFile) throws IOException { + return ImageUtil.decodeSampledBitmapFromFile(imageFile, maxWidth, maxHeight); + } + + public Flowable compressToFileAsFlowable(final File imageFile) { + return compressToFileAsFlowable(imageFile, imageFile.getName()); + } + + public Flowable compressToFileAsFlowable(final File imageFile, final String compressedFileName) { + return Flowable.defer(() -> { + try { + return Flowable.just(compressToFile(imageFile, compressedFileName)); + } catch (IOException e) { + return Flowable.error(e); + } + }); + } + + public Flowable compressToBitmapAsFlowable(final File imageFile) { + return Flowable.defer(() -> { + try { + return Flowable.just(compressToBitmap(imageFile)); + } catch (IOException e) { + return Flowable.error(e); + } + }); + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.java index 1b5d4e43..2c39e534 100755 --- a/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.java +++ b/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.java @@ -26,8 +26,10 @@ import androidx.annotation.Nullable; import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityOptionsCompat; import androidx.core.util.Pair; - import code.name.monkey.retromusic.R; +import code.name.monkey.retromusic.helper.MusicPlayerRemote; +import code.name.monkey.retromusic.model.Genre; +import code.name.monkey.retromusic.model.Playlist; import code.name.monkey.retromusic.activities.AboutActivity; import code.name.monkey.retromusic.activities.AlbumDetailsActivity; import code.name.monkey.retromusic.activities.ArtistDetailActivity; @@ -41,10 +43,8 @@ import code.name.monkey.retromusic.activities.PurchaseActivity; import code.name.monkey.retromusic.activities.SearchActivity; import code.name.monkey.retromusic.activities.SettingsActivity; import code.name.monkey.retromusic.activities.SupportDevelopmentActivity; +import code.name.monkey.retromusic.activities.UserInfoActivity; import code.name.monkey.retromusic.activities.WhatsNewActivity; -import code.name.monkey.retromusic.helper.MusicPlayerRemote; -import code.name.monkey.retromusic.model.Genre; -import code.name.monkey.retromusic.model.Playlist; import static code.name.monkey.retromusic.Constants.RATE_ON_GOOGLE_PLAY; import static code.name.monkey.retromusic.util.RetroUtil.openUrl; @@ -138,6 +138,10 @@ public class NavigationUtil { ActivityCompat.startActivity(activity, new Intent(activity, AboutActivity.class), null); } + public static void goToUserInfo(@NonNull Activity activity) { + ActivityCompat.startActivity(activity, new Intent(activity, UserInfoActivity.class), null); + } + public static void goToOpenSource(@NonNull Activity activity) { ActivityCompat.startActivity(activity, new Intent(activity, LicenseActivity.class), null); } diff --git a/app/src/main/java/code/name/monkey/retromusic/util/SystemUtils.java b/app/src/main/java/code/name/monkey/retromusic/util/SystemUtils.java new file mode 100644 index 00000000..ac7ebb68 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/util/SystemUtils.java @@ -0,0 +1,113 @@ +/* + * 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.util; + +import android.app.Activity; +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.util.DisplayMetrics; +import android.view.ViewGroup; + +import code.name.monkey.retromusic.App; + +public class SystemUtils { + + private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height"; + private static final String NAV_BAR_HEIGHT_RES_NAME = "navigation_bar_height"; + private static final String NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME = "navigation_bar_height_landscape"; + private static final String NAV_BAR_WIDTH_RES_NAME = "navigation_bar_width"; + private static final String SHOW_NAV_BAR_RES_NAME = "config_showNavigationBar"; + private final float mSmallestWidthDp; + private final boolean mInPortrait; + + private Activity activity; + + public SystemUtils(Activity activity) { + this.activity = activity; + Resources resources = activity.getResources(); + mSmallestWidthDp = getSmallestWidthDp(activity); + mInPortrait = (resources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT); + } + + private static boolean hasNavBar(Resources resources) { + int id = resources.getIdentifier(SHOW_NAV_BAR_RES_NAME, "bool", "android"); + if (id > 0) + return resources.getBoolean(id); + else + return false; + } + + public static int getNavigationBarHeight() { + int result = 0; + int resourceId = App.Companion.getContext().getResources().getIdentifier("navigation_bar_height", "dimen", "android"); + if (resourceId > 0) { + result = App.Companion.getContext().getResources().getDimensionPixelSize(resourceId); + } + return result; + } + + public int getComboHeight() { + if (isNavigationAtBottom()) { + return getNavigationBarWidth(); + } else { + return getNavigationBarHeight(); + } + } + + public int getNavigationBarWidth() { + Resources res = activity.getResources(); + int result = 0; + if (hasNavBar(activity.getResources())) { + if (!isNavigationAtBottom()) + return getInternalDimensionSize(res, NAV_BAR_WIDTH_RES_NAME); + } + return result; + } + + public void addPadding(ViewGroup viewGroup) { + Context context = viewGroup.getContext(); + Resources resources = context.getResources(); + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) viewGroup.getLayoutParams(); + if (isNavigationAtBottom()) { + params.leftMargin = getNavigationBarWidth(); + params.rightMargin = getNavigationBarWidth(); + } else { + params.bottomMargin = getNavigationBarHeight(); + } + } + + private int getInternalDimensionSize(Resources res, String key) { + int result = 0; + int resourceId = res.getIdentifier(key, "dimen", "android"); + if (resourceId > 0) { + result = res.getDimensionPixelSize(resourceId); + } + return result; + } + + private float getSmallestWidthDp(Activity activity) { + DisplayMetrics metrics = new DisplayMetrics(); + activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics); + float widthDp = metrics.widthPixels / metrics.density; + float heightDp = metrics.heightPixels / metrics.density; + return Math.min(widthDp, heightDp); + } + + boolean isNavigationAtBottom() { + return (mSmallestWidthDp >= 600 || mInPortrait); + } + +} diff --git a/app/src/main/java/code/name/monkey/retromusic/util/TempUtils.java b/app/src/main/java/code/name/monkey/retromusic/util/TempUtils.java new file mode 100644 index 00000000..2a0fac4e --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/util/TempUtils.java @@ -0,0 +1,82 @@ +/* + * 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.util; + +/** + * @author Hemanth S (h4h13). + */ +public class TempUtils { + + // Enums + public static final int TEMPO_STROLL = 0; + public static final int TEMPO_WALK = 1; + public static final int TEMPO_LIGHT_JOG = 2; + public static final int TEMPO_JOG = 3; + public static final int TEMPO_RUN = 4; + public static final int TEMPO_SPRINT = 5; + public static final int TEMPO_UNKNOWN = 6; + + // take BPM as an int + public static int getTempoFromBPM(int bpm) { + + // STROLL less than 60 + if (bpm < 60) { + return TEMPO_STROLL; + } + + // WALK between 60 and 70, or between 120 and 140 + else if (bpm < 70 || bpm >= 120 && bpm < 140) { + return TEMPO_WALK; + } + + // LIGHT_JOG between 70 and 80, or between 140 and 160 + else if (bpm < 80 || bpm >= 140 && bpm < 160) { + return TEMPO_LIGHT_JOG; + } + + // JOG between 80 and 90, or between 160 and 180 + else if (bpm < 90 || bpm >= 160 && bpm < 180) { + return TEMPO_JOG; + } + + // RUN between 90 and 100, or between 180 and 200 + else if (bpm < 100 || bpm >= 180 && bpm < 200) { + return TEMPO_RUN; + } + + // SPRINT between 100 and 120 + else if (bpm < 120) { + return TEMPO_SPRINT; + } + + // UNKNOWN + else { + return TEMPO_UNKNOWN; + } + } + + // take BPM as a string + public static int getTempoFromBPM(String bpm) { + // cast to an int from string + try { + // convert the string to an int + return getTempoFromBPM(Integer.parseInt(bpm.trim())); + } catch (NumberFormatException nfe) { + + // + return TEMPO_UNKNOWN; + } + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/views/MaterialButtonTextColor.kt b/app/src/main/java/code/name/monkey/retromusic/views/MaterialButtonTextColor.kt new file mode 100644 index 00000000..069b8b6c --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/views/MaterialButtonTextColor.kt @@ -0,0 +1,37 @@ +/* + * 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.views + +import android.content.Context +import android.content.res.ColorStateList +import android.util.AttributeSet +import code.name.monkey.appthemehelper.ThemeStore +import code.name.monkey.appthemehelper.util.ATHUtil +import code.name.monkey.appthemehelper.util.ColorUtil +import code.name.monkey.appthemehelper.util.MaterialValueHelper +import code.name.monkey.retromusic.R +import code.name.monkey.retromusic.util.RetroUtil +import com.google.android.material.button.MaterialButton + +class MaterialButtonTextColor @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = -1) : MaterialButton(context, attrs, defStyleAttr) { + + init { + setTextColor(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(ThemeStore.primaryColor(getContext())))) + iconTint = ColorStateList.valueOf(ATHUtil.resolveColor(context, R.attr.iconColor)) + rippleColor = ColorStateList.valueOf(ColorUtil.withAlpha(ThemeStore.accentColor(context), 0.4f)) + //minHeight = RetroUtil.convertDpToPixel(42f, context).toInt() + iconSize = RetroUtil.convertDpToPixel(20f, context).toInt() + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/views/PlayPauseDrawable.java b/app/src/main/java/code/name/monkey/retromusic/views/PlayPauseDrawable.java new file mode 100644 index 00000000..863e615f --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/views/PlayPauseDrawable.java @@ -0,0 +1,225 @@ +/* + * 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.views; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import androidx.annotation.NonNull; +import android.util.Property; +import android.view.animation.DecelerateInterpolator; + +import code.name.monkey.retromusic.R; + + +public class PlayPauseDrawable extends Drawable { + private static final long PLAY_PAUSE_ANIMATION_DURATION = 250; + + private static final Property PROGRESS = + new Property(Float.class, "progress") { + @Override + public Float get(@NonNull PlayPauseDrawable d) { + return d.getProgress(); + } + + @Override + public void set(@NonNull PlayPauseDrawable d, Float value) { + d.setProgress(value); + } + }; + + private final Path leftPauseBar = new Path(); + private final Path rightPauseBar = new Path(); + private final Paint paint = new Paint(); + private final float pauseBarWidth; + private final float pauseBarHeight; + private final float pauseBarDistance; + + private float width; + private float height; + + private float progress; + private boolean isPlay; + private boolean isPlaySet; + + private Animator animator; + + public PlayPauseDrawable(@NonNull Context context) { + final Resources res = context.getResources(); + paint.setAntiAlias(true); + paint.setStyle(Paint.Style.FILL); + paint.setColor(Color.WHITE); + + pauseBarWidth = res.getDimensionPixelSize(R.dimen.pause_bar_width); + pauseBarHeight = res.getDimensionPixelSize(R.dimen.pause_bar_height); + pauseBarDistance = res.getDimensionPixelSize(R.dimen.pause_bar_distance); + } + + /** + * Linear interpolate between a and b with parameter t. + */ + private static float lerp(float a, float b, float t) { + return a + (b - a) * t; + } + + @Override + protected void onBoundsChange(@NonNull final Rect bounds) { + super.onBoundsChange(bounds); + if (bounds.width() > 0 && bounds.height() > 0) { + width = bounds.width(); + height = bounds.height(); + } + } + + @Override + public void draw(@NonNull Canvas canvas) { + leftPauseBar.rewind(); + rightPauseBar.rewind(); + + // The current distance between the two pause bars. + final float barDist = lerp(pauseBarDistance, 0f, progress); + // The current width of each pause bar. + float rawBarWidth = lerp(pauseBarWidth, pauseBarHeight / 1.75f, progress); + // We have to round the bar width when finishing the progress to prevent the gap + // that might occur onDraw because of a pixel is lost when casting float to int instead of rounding it. + final float barWidth = progress == 1f ? Math.round(rawBarWidth) : rawBarWidth; + // The current position of the left pause bar's top left coordinate. + final float firstBarTopLeft = lerp(0f, barWidth, progress); + // The current position of the right pause bar's top right coordinate. + final float secondBarTopRight = lerp(2f * barWidth + barDist, barWidth + barDist, progress); + + // Draw the left pause bar. The left pause bar transforms into the + // top half of the play button triangle by animating the position of the + // rectangle's top left coordinate and expanding its bottom width. + leftPauseBar.moveTo(0f, 0f); + leftPauseBar.lineTo(firstBarTopLeft, -pauseBarHeight); + leftPauseBar.lineTo(barWidth, -pauseBarHeight); + leftPauseBar.lineTo(barWidth, 0f); + leftPauseBar.close(); + + // Draw the right pause bar. The right pause bar transforms into the + // bottom half of the play button triangle by animating the position of the + // rectangle's top right coordinate and expanding its bottom width. + rightPauseBar.moveTo(barWidth + barDist, 0f); + rightPauseBar.lineTo(barWidth + barDist, -pauseBarHeight); + rightPauseBar.lineTo(secondBarTopRight, -pauseBarHeight); + rightPauseBar.lineTo(2 * barWidth + barDist, 0f); + rightPauseBar.close(); + + final int saveCount = canvas.save(); + + // Translate the play button a tiny bit to the right so it looks more centered. + canvas.translate(lerp(0f, pauseBarHeight / 8f, progress), 0f); + + // (1) Pause --> Play: rotate 0 to 90 degrees clockwise. + // (2) Play --> Pause: rotate 90 to 180 degrees clockwise. + final float rotationProgress = isPlay ? 1f - progress : progress; + final float startingRotation = isPlay ? 90f : 0f; + canvas.rotate(lerp(startingRotation, startingRotation + 90f, rotationProgress), width / 2f, height / 2f); + + // Position the pause/play button in the center of the drawable's bounds. + canvas.translate(Math.round(width / 2f - ((2f * barWidth + barDist) / 2f)), Math.round(height / 2f + (pauseBarHeight / 2f))); + + // Draw the two bars that form the animated pause/play button. + canvas.drawPath(leftPauseBar, paint); + canvas.drawPath(rightPauseBar, paint); + + canvas.restoreToCount(saveCount); + } + + @NonNull + private Animator getPausePlayAnimator() { + isPlaySet = !isPlaySet; + final Animator anim = ObjectAnimator.ofFloat(this, PROGRESS, isPlay ? 1f : 0f, isPlay ? 0f : 1f); + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + isPlay = !isPlay; + } + }); + return anim; + } + + private float getProgress() { + return progress; + } + + private void setProgress(float progress) { + this.progress = progress; + invalidateSelf(); + } + + @Override + public void setAlpha(int alpha) { + paint.setAlpha(alpha); + invalidateSelf(); + } + + @Override + public void setColorFilter(ColorFilter cf) { + paint.setColorFilter(cf); + invalidateSelf(); + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } + + public void setPlay(boolean animate) { + if (animate) { + if (!isPlaySet) { + togglePlayPause(); + } + } else { + isPlaySet = true; + isPlay = true; + setProgress(1f); + } + } + + public void setPause(boolean animate) { + if (animate) { + if (isPlaySet) { + togglePlayPause(); + } + } else { + isPlaySet = false; + isPlay = false; + setProgress(0f); + } + } + + public void togglePlayPause() { + if (animator != null) { + animator.cancel(); + } + + animator = getPausePlayAnimator(); + animator.setInterpolator(new DecelerateInterpolator()); + animator.setDuration(PLAY_PAUSE_ANIMATION_DURATION); + animator.start(); + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/views/TintIconColorToolbar.kt b/app/src/main/java/code/name/monkey/retromusic/views/TintIconColorToolbar.kt new file mode 100644 index 00000000..58f69863 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/views/TintIconColorToolbar.kt @@ -0,0 +1,36 @@ +/* + * 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.views + +import android.content.Context +import android.graphics.PorterDuff +import android.graphics.drawable.Drawable +import android.util.AttributeSet +import androidx.appcompat.widget.Toolbar +import code.name.monkey.appthemehelper.ThemeStore + +class TintIconColorToolbar : Toolbar { + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + + override fun setNavigationIcon(icon: Drawable?) { + super.setNavigationIcon(icon) + icon?.setColorFilter(ThemeStore.textColorSecondary(context), PorterDuff.Mode.SRC_IN) + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/views/UserImageView.java b/app/src/main/java/code/name/monkey/retromusic/views/UserImageView.java new file mode 100644 index 00000000..51df25eb --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/views/UserImageView.java @@ -0,0 +1,147 @@ +/* + * 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.views; + +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.preference.PreferenceManager; +import android.util.AttributeSet; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bumptech.glide.request.Request; +import com.bumptech.glide.request.target.SizeReadyCallback; +import com.bumptech.glide.request.target.Target; +import com.bumptech.glide.request.transition.Transition; + +import java.io.File; + +import code.name.monkey.retromusic.R; +import code.name.monkey.retromusic.glide.GlideApp; +import code.name.monkey.retromusic.util.PreferenceUtil; + +import static code.name.monkey.retromusic.Constants.USER_PROFILE; + +public class UserImageView extends CircularImageView implements SharedPreferences.OnSharedPreferenceChangeListener { + public UserImageView(@NonNull Context context) { + super(context); + init(context); + } + + public UserImageView(@NonNull Context context, @NonNull AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public UserImageView(@NonNull Context context, @NonNull AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context); + } + + void init(@NonNull Context context) { + resetImage(context); + } + + private void resetImage(@NonNull Context context) { + GlideApp.with(context) + .asDrawable() + .placeholder(R.drawable.ic_account_white_24dp) + .fallback(R.drawable.ic_account_white_24dp) + .load(new File(PreferenceUtil.getInstance().getProfileImage(), USER_PROFILE)) + .into(new Target() { + @Override + public void onLoadStarted(@Nullable Drawable placeholder) { + setImageDrawable(placeholder); + setBackgroundColor(Color.TRANSPARENT); + } + + @Override + public void onLoadFailed(@Nullable Drawable errorDrawable) { + setImageDrawable(errorDrawable); + setBackgroundColor(Color.TRANSPARENT); + + } + + @Override + public void onResourceReady(@NonNull Drawable resource, @Nullable Transition transition) { + setImageDrawable(resource); + setBackgroundColor(Color.TRANSPARENT); + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + + } + + @Override + public void getSize(@NonNull SizeReadyCallback cb) { + cb.onSizeReady(96, 96); + } + + @Override + public void removeCallback(@NonNull SizeReadyCallback cb) { + + } + + @Nullable + @Override + public Request getRequest() { + return null; + } + + @Override + public void setRequest(@Nullable Request request) { + + } + + @Override + public void onStart() { + + } + + @Override + public void onStop() { + + } + + @Override + public void onDestroy() { + + } + }); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + PreferenceManager.getDefaultSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this); + } + + @Override + public void onSharedPreferenceChanged(@NonNull SharedPreferences sharedPreferences, @NonNull String key) { + if (key.equals(PreferenceUtil.PROFILE_IMAGE_PATH)) { + resetImage(getContext()); + } + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/views/WidthFitSquareCardView.kt b/app/src/main/java/code/name/monkey/retromusic/views/WidthFitSquareCardView.kt index 27d32a60..6aaabe73 100644 --- a/app/src/main/java/code/name/monkey/retromusic/views/WidthFitSquareCardView.kt +++ b/app/src/main/java/code/name/monkey/retromusic/views/WidthFitSquareCardView.kt @@ -35,11 +35,11 @@ class WidthFitSquareCardView : MaterialCardView { } override fun onMeasure(i: Int, i2: Int) { - var i2Final = i2 + var i2 = i2 if (this.forceSquare) { - i2Final = i + i2 = i } - super.onMeasure(i, i2Final) + super.onMeasure(i, i2) } private var forceSquare = true diff --git a/app/src/main/res/layout-land/fragment_banner_home.xml b/app/src/main/res/layout-land/fragment_banner_home.xml new file mode 100644 index 00000000..7aa5128c --- /dev/null +++ b/app/src/main/res/layout-land/fragment_banner_home.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-land/fragment_player.xml b/app/src/main/res/layout-land/fragment_player.xml index e06906ae..ee835e88 100755 --- a/app/src/main/res/layout-land/fragment_player.xml +++ b/app/src/main/res/layout-land/fragment_player.xml @@ -12,6 +12,10 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> + diff --git a/app/src/main/res/layout-xlarge-land/fragment_banner_home.xml b/app/src/main/res/layout-xlarge-land/fragment_banner_home.xml new file mode 100644 index 00000000..acea2177 --- /dev/null +++ b/app/src/main/res/layout-xlarge-land/fragment_banner_home.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-xlarge-land/fragment_player.xml b/app/src/main/res/layout-xlarge-land/fragment_player.xml index 6d0d7e37..6fdce2d4 100644 --- a/app/src/main/res/layout-xlarge-land/fragment_player.xml +++ b/app/src/main/res/layout-xlarge-land/fragment_player.xml @@ -12,6 +12,11 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-xlarge/fragment_player.xml b/app/src/main/res/layout-xlarge/fragment_player.xml index 94c5f1ac..1d6d7a61 100644 --- a/app/src/main/res/layout-xlarge/fragment_player.xml +++ b/app/src/main/res/layout-xlarge/fragment_player.xml @@ -11,8 +11,10 @@ android:id="@+id/colorGradientBackground" android:layout_width="match_parent" android:layout_height="match_parent" /> - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_player.xml b/app/src/main/res/layout/fragment_player.xml index 96acc1ff..9d992988 100644 --- a/app/src/main/res/layout/fragment_player.xml +++ b/app/src/main/res/layout/fragment_player.xml @@ -12,6 +12,11 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> + + @font/circular @color/md_white_1000 + false + @@ -128,6 +132,8 @@ @transition/grid_exit @transition/grid_exit @font/circular + + false diff --git a/app/src/main/res/xml/pref_ui.xml b/app/src/main/res/xml/pref_ui.xml index 57764763..11247eaf 100644 --- a/app/src/main/res/xml/pref_ui.xml +++ b/app/src/main/res/xml/pref_ui.xml @@ -1,6 +1,7 @@ + + +