From 7a42723b9e6564dc5e40d4991286a4b0c8c43d42 Mon Sep 17 00:00:00 2001 From: h4h13 Date: Mon, 25 Mar 2019 18:13:43 +0530 Subject: [PATCH] updated --- app/build.gradle | 36 +- app/src/main/AndroidManifest.xml | 4 +- app/src/main/assets/retro-changelog.html | 2 +- .../retromusic/dialogs/AddToPlaylistDialog.kt | 2 +- .../dialogs/OptionsSheetDialogFragment.kt | 15 +- .../retromusic/dialogs/SleepTimerDialog.kt | 2 +- .../retromusic/exfab/FabIconAnimator.java | 143 ++++++++ .../exfab/TransientBarBehavior.java | 75 ++++ .../glide/artistimage/ArtistImageLoader.kt | 3 +- .../retromusic/misc/GenericFileProvider.java | 20 ++ .../monkey/retromusic/model/Contributor.kt | 4 +- .../retromusic/model/lyrics/Lyrics.java | 14 +- .../retromusic/rest/LastFMRestClient.java | 91 ++--- .../ui/activities/AlbumDetailsActivity.kt | 15 +- .../ui/activities/ArtistDetailActivity.kt | 12 +- .../ui/activities/GenreDetailsActivity.kt | 14 +- .../ui/activities/PlayingQueueActivity.kt | 14 +- .../ui/activities/PlaylistDetailActivity.kt | 17 +- .../ui/activities/UserInfoActivity.kt | 167 ++++++++- .../base/AbsSlidingMusicPanelActivity.kt | 324 +----------------- .../tageditor/AbsTagEditorActivity.kt | 18 +- .../tageditor/AlbumTagEditorActivity.kt | 7 + .../tageditor/SongTagEditorActivity.kt | 11 + .../ui/adapter/ContributorAdapter.kt | 34 +- .../retromusic/ui/adapter/HomeAdapter.kt | 7 +- .../ui/fragments/NowPlayingScreen.kt | 2 +- .../AbsLibraryPagerRecyclerViewFragment.kt | 5 +- .../fragments/base/AbsMusicServiceFragment.kt | 5 +- .../ui/fragments/base/AbsPlayerFragment.kt | 67 +++- .../fragments/mainactivity/GenreFragment.kt | 5 +- .../mainactivity/LibraryFragment.java | 24 +- .../mainactivity/PlaylistsFragment.kt | 9 +- .../mainactivity/home/BannerHomeFragment.kt | 28 +- .../player/PlayerAlbumCoverFragment.kt | 23 +- .../player/classic/ClassicPlayerFragment.kt | 4 +- .../fragments/player/color/ColorFragment.kt | 10 +- .../player/full/FullPlayerFragment.kt | 94 ++++- .../fragments/player/normal/PlayerFragment.kt | 32 +- .../fragments/settings/AbsSettingsFragment.kt | 3 +- .../ui/fragments/settings/AudioSettings.kt | 5 +- .../settings/ImageSettingFragment.kt | 5 +- .../settings/NotificationSettingsFragment.kt | 4 +- .../settings/NowPlayingSettingsFragment.kt | 12 +- .../settings/OtherSettingsFragment.kt | 3 +- .../settings/PersonaizeSettingsFragment.kt | 15 +- .../settings/ThemeSettingsFragment.kt | 9 +- .../monkey/retromusic/util/ImagePicker.java | 202 +++++++++++ .../retromusic/util/PreferenceUtil.java | 20 +- .../retromusic/views/CollapsingFAB.java | 95 ----- .../views/LollipopFixedWebView.java | 49 +++ .../retromusic/views/NetworkImageView.java | 13 +- .../retromusic/views/OptionMenuItemView.java | 70 ++++ app/src/main/res/drawable/bg_fab.xml | 17 + .../res/drawable/ic_delete_white_24dp.xml | 4 +- .../res/drawable/ic_grid_size_white_24dp.xml | 23 ++ .../main/res/layout-land/activity_album.xml | 13 +- .../layout-land/activity_album_tag_editor.xml | 77 +---- .../layout-land/activity_artist_details.xml | 13 +- .../res/layout-xlarge-land/activity_album.xml | 12 +- .../activity_artist_details.xml | 13 +- .../main/res/layout-xlarge/activity_album.xml | 14 +- .../layout-xlarge/activity_artist_details.xml | 12 +- .../res/layout-xlarge/activity_user_info.xml | 41 ++- app/src/main/res/layout/abs_playlists.xml | 6 +- app/src/main/res/layout/activity_album.xml | 14 +- .../res/layout/activity_album_tag_editor.xml | 72 ++-- .../res/layout/activity_artist_details.xml | 13 +- .../res/layout/activity_playing_queue.xml | 10 +- .../res/layout/activity_playlist_detail.xml | 11 +- .../res/layout/activity_song_tag_editor.xml | 135 ++------ .../main/res/layout/activity_user_info.xml | 38 +- .../main/res/layout/activity_whats_new.xml | 2 +- app/src/main/res/layout/card_credit.xml | 55 +-- app/src/main/res/layout/card_other.xml | 25 +- app/src/main/res/layout/card_retro_info.xml | 21 +- app/src/main/res/layout/card_social.xml | 56 +-- .../collapsing_floating_action_button.xml | 3 +- app/src/main/res/layout/fab_collapsed.xml | 33 ++ app/src/main/res/layout/fab_extended.xml | 33 ++ .../main/res/layout/fragment_banner_home.xml | 1 + app/src/main/res/layout/fragment_full.xml | 37 ++ app/src/main/res/layout/fragment_library.xml | 31 +- .../main/res/layout/fragment_main_options.xml | 102 ++++-- .../fragment_material_playback_controls.xml | 2 - .../fragment_plain_controls_fragment.xml | 2 - .../main/res/layout/fragment_plain_player.xml | 2 +- .../layout/fragment_player_album_cover.xml | 1 - .../fragment_player_playback_controls.xml | 10 +- app/src/main/res/layout/item_contributor.xml | 10 +- app/src/main/res/layout/item_option_menu.xml | 42 +++ .../layout/metal_section_recycler_view.xml | 9 +- .../main/res/layout/section_recycler_view.xml | 5 - .../res/layout/sliding_music_panel_layout.xml | 14 +- app/src/main/res/menu/menu_main.xml | 32 +- app/src/main/res/values/attrs.xml | 12 +- app/src/main/res/values/dimens.xml | 3 +- app/src/main/res/values/strings.xml | 3 + appthemehelper/build.gradle | 6 +- .../common/views/ATEAccentTextView.kt | 39 +++ .../views/ATEExtendedFloatingActionButton.kt | 32 ++ .../common/views/ATETextInputLayout.java | 14 +- .../appthemehelper/util/MaterialUtil.kt | 33 +- build.gradle | 2 +- 103 files changed, 1879 insertions(+), 1195 deletions(-) create mode 100644 app/src/main/java/code/name/monkey/retromusic/exfab/FabIconAnimator.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/exfab/TransientBarBehavior.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/misc/GenericFileProvider.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/util/ImagePicker.java delete mode 100644 app/src/main/java/code/name/monkey/retromusic/views/CollapsingFAB.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/views/LollipopFixedWebView.java create mode 100644 app/src/main/java/code/name/monkey/retromusic/views/OptionMenuItemView.java create mode 100644 app/src/main/res/drawable/bg_fab.xml create mode 100644 app/src/main/res/drawable/ic_grid_size_white_24dp.xml create mode 100644 app/src/main/res/layout/fab_collapsed.xml create mode 100644 app/src/main/res/layout/fab_extended.xml create mode 100644 app/src/main/res/layout/item_option_menu.xml create mode 100644 appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/views/ATEAccentTextView.kt create mode 100644 appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/views/ATEExtendedFloatingActionButton.kt diff --git a/app/build.gradle b/app/build.gradle index 288fd850..11c7b2de 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -32,7 +32,7 @@ android { vectorDrawables.useSupportLibrary = true applicationId "code.name.monkey.retromusic" - versionCode 305 + versionCode 308 versionName '3.1.300' multiDexEnabled true @@ -86,8 +86,8 @@ android { abortOnError false } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility '1.8' + targetCompatibility '1.8' } configurations.all { @@ -120,17 +120,17 @@ static def getDate() { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'androidx.multidex:multidex:2.0.1' - implementation "androidx.fragment:fragment:$supportLibVersion" - implementation 'androidx.appcompat:appcompat:1.0.2' - implementation "androidx.recyclerview:recyclerview:$supportLibVersion" - implementation "androidx.gridlayout:gridlayout:$supportLibVersion" - implementation "androidx.cardview:cardview:$supportLibVersion" - implementation "androidx.palette:palette:$supportLibVersion" - implementation "androidx.annotation:annotation:$supportLibVersion" - implementation "androidx.preference:preference:$supportLibVersion" - implementation "androidx.legacy:legacy-support-v13:$supportLibVersion" - implementation "androidx.legacy:legacy-preference-v14:$supportLibVersion" - implementation "com.google.android.material:material:$supportLibVersion" + implementation 'androidx.fragment:fragment:1.1.0-alpha05' + implementation 'androidx.appcompat:appcompat:1.1.0-alpha03' + implementation "androidx.recyclerview:recyclerview:1.1.0-alpha03" + implementation "androidx.gridlayout:gridlayout:1.0.0" + implementation "androidx.cardview:cardview:1.0.0" + implementation "androidx.palette:palette:1.0.0" + implementation 'androidx.annotation:annotation:1.1.0-alpha02' + implementation 'androidx.preference:preference:1.1.0-alpha04' + implementation "androidx.legacy:legacy-support-v13:1.0.0" + implementation "androidx.legacy:legacy-preference-v14:1.0.0" + implementation 'com.google.android.material:material:1.1.0-alpha04' implementation 'androidx.palette:palette-ktx:1.0.0' implementation 'com.squareup.retrofit2:retrofit:2.5.0' implementation 'com.squareup.retrofit2:converter-gson:2.5.0' @@ -141,6 +141,7 @@ dependencies { implementation 'com.afollestad.material-dialogs:color:2.0.0' implementation 'com.afollestad:material-cab:0.1.12' implementation 'com.github.bumptech.glide:glide:4.8.0' + kapt 'com.github.bumptech.glide:compiler:4.8.0' implementation 'com.github.bumptech.glide:okhttp3-integration:4.8.0' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'io.reactivex.rxjava2:rxjava:2.2.7' @@ -151,18 +152,17 @@ dependencies { implementation 'com.github.kabouzeid:RecyclerView-FastScroll:1.0.16-kmod' implementation 'com.anjlab.android.iab.v3:library:1.0.44' /*UI Library*/ - implementation 'me.zhanghai.android.materialprogressbar:library:1.4.2' + implementation 'me.zhanghai.android.materialprogressbar:library:1.6.1' implementation 'com.r0adkll:slidableactivity:2.0.6' /*Backend all*/ implementation 'com.github.kabouzeid:AndroidSlidingUpPanel:3.3.0-kmod3' implementation 'com.github.AdrienPoupa:jaudiotagger:2.2.3' implementation 'org.nanohttpd:nanohttpd:2.3.1' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:2.1.5' + implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:3.4.0.201406110918-r' implementation 'com.github.jetradarmobile:android-snowfall:1.2.0' implementation 'com.github.takahirom.downloadable.calligraphy:downloadable-calligraphy:0.1.3' - kapt 'com.github.bumptech.glide:compiler:4.8.0' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2' implementation project(':appthemehelper') } repositories { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cc08aaec..1ab0c62f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -165,8 +165,8 @@ android:value="code.name.monkey.retromusic.cast.CastOptionsProvider" />

v3.1.300

  • Added new slide theme
  • Fix Home screen sections loading slow

v3.1.240

  • Fix Search not showing from home screen
  • Fix Volume controls color issue
  • Fix Seek bar alignment
  • Added tiny theme
  • Improved full theme appearances
  • Now playing theme preview updated
  • Fix composer error

v3.1.200

  • Added composer sort and editing
  • Fix Crash in Album tag editor while selecting options
  • Added Filter song length
  • Added Favourites playlist icon will be accent color
  • Added Colorful settings icons
  • Added Corners for dialog

v3.0.570

  • Fix Album/Artist square image
  • Fix Delete dialog text format
  • Fix Profile picture not showing after coming back from folders
  • Fix Play button color i Simple and Plain themes
  • Fix Sleep timer dialog crashing
  • Fix Share song dialog title and text

If you see entire app white or dark or black select same theme in settings to fix

FAQ's

*If you face any UI related issues you clear app data and cache, if its not working try to uninstall and install again.

\ No newline at end of file +

v3.1.300

  • Improved home sections loading
  • Removed library options which are duplicated (it's available from profile menu)
  • Replaced collapsing Fab with Android Floating Extended Fab
  • Replaced home with for you
  • Fixed profile image not loading in about
  • Improved selecting user profile image
  • Added bio to enter custom message
  • Improved some UI screens

v3.1.240

  • Fix Search not showing from home screen
  • Fix Volume controls color issue
  • Fix Seek bar alignment
  • Added tiny theme
  • Improved full theme appearances
  • Now playing theme preview updated
  • Fix composer error
  • Bottom Options improved(internal)

v3.1.200

  • Added composer sort and editing
  • Fix Crash in Album tag editor while selecting options
  • Added Filter song length
  • Added Favourites playlist icon will be accent color
  • Added Colorful settings icons
  • Added Corners for dialog

v3.0.570

  • Fix Album/Artist square image
  • Fix Delete dialog text format
  • Fix Profile picture not showing after coming back from folders
  • Fix Play button color i Simple and Plain themes
  • Fix Sleep timer dialog crashing
  • Fix Share song dialog title and text

If you see entire app white or dark or black select same theme in settings to fix

FAQ's

*If you face any UI related issues you clear app data and cache, if its not working try to uninstall and install again.

\ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt index e420bf1a..db03ddc4 100644 --- a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt @@ -50,7 +50,7 @@ class AddToPlaylistDialog : RoundedBottomSheetDialogFragment() { bannerTitle.setTextColor(ThemeStore.textColorPrimary(context!!)) val playlists = PlaylistLoader.getAllPlaylists(activity!!).blockingFirst() - val playlistAdapter = AddToPlaylist(activity!!, playlists, R.layout.item_playlist, songs!!, dialog) + val playlistAdapter = AddToPlaylist(activity!!, playlists, R.layout.item_playlist, songs!!, dialog!!) recyclerView.apply { layoutManager = LinearLayoutManager(context) itemAnimator = DefaultItemAnimator() diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/OptionsSheetDialogFragment.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/OptionsSheetDialogFragment.kt index e8225019..7a1ca934 100644 --- a/app/src/main/java/code/name/monkey/retromusic/dialogs/OptionsSheetDialogFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/OptionsSheetDialogFragment.kt @@ -15,7 +15,6 @@ package code.name.monkey.retromusic.dialogs import android.content.Intent -import android.content.res.ColorStateList import android.graphics.Bitmap import android.os.Bundle import android.view.LayoutInflater @@ -62,7 +61,7 @@ class OptionsSheetDialogFragment : RoundedBottomSheetDialogFragment(), View.OnCl override fun onDestroyView() { super.onDestroyView() - disposable.clear() + disposable.dispose() } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -72,9 +71,11 @@ class OptionsSheetDialogFragment : RoundedBottomSheetDialogFragment(), View.OnCl override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - text!!.setTextColor(ThemeStore.textColorSecondary(context!!)) - titleWelcome!!.setTextColor(ThemeStore.textColorPrimary(context!!)) - titleWelcome!!.text = String.format("%s %s!", timeOfTheDay, PreferenceUtil.getInstance().userName) + text.setTextColor(ThemeStore.textColorSecondary(context!!)) + text.text = PreferenceUtil.getInstance().userBio + titleWelcome.setTextColor(ThemeStore.textColorPrimary(context!!)) + titleWelcome.text = String.format("%s %s!", timeOfTheDay, PreferenceUtil.getInstance().userName) + loadImageFromStorage() actionSettings.setOnClickListener(this) @@ -99,9 +100,7 @@ class OptionsSheetDialogFragment : RoundedBottomSheetDialogFragment(), View.OnCl override fun onClick(view: View) { val mainActivity = activity as MainActivity? ?: return when (view.id) { - R.id.actionFolders -> { - mainActivity.setCurrentFragment(FoldersFragment.newInstance(context), true) - } + R.id.actionFolders -> mainActivity.setCurrentFragment(FoldersFragment.newInstance(context), true) R.id.actionSettings -> NavigationUtil.goToSettings(mainActivity) R.id.actionAbout -> NavigationUtil.goToAbout(mainActivity) R.id.actionSleepTimer -> if (fragmentManager != null) { diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/SleepTimerDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/SleepTimerDialog.kt index 851471b7..641e3ac1 100755 --- a/app/src/main/java/code/name/monkey/retromusic/dialogs/SleepTimerDialog.kt +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/SleepTimerDialog.kt @@ -45,7 +45,7 @@ class SleepTimerDialog : RoundedBottomSheetDialogFragment() { private var seekArcProgress: Int = 0 private lateinit var timerUpdater: TimerUpdater - override fun onDismiss(dialog: DialogInterface?) { + override fun onDismiss(dialog: DialogInterface) { super.onDismiss(dialog) timerUpdater.cancel() } diff --git a/app/src/main/java/code/name/monkey/retromusic/exfab/FabIconAnimator.java b/app/src/main/java/code/name/monkey/retromusic/exfab/FabIconAnimator.java new file mode 100644 index 00000000..e3384af0 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/exfab/FabIconAnimator.java @@ -0,0 +1,143 @@ +/* + * 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.exfab; + +/** + * Created by hemanths on 3/20/19 + */ + +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.transition.AutoTransition; +import android.transition.Transition; +import android.transition.TransitionManager; +import android.view.View; + +import com.google.android.material.button.MaterialButton; + +import java.util.concurrent.atomic.AtomicBoolean; + +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.constraintlayout.widget.ConstraintSet; +import code.name.monkey.retromusic.R; + +public class FabIconAnimator { + + private static final String ROTATION_Y_PROPERTY = "rotationY"; + + private static final float TWITCH_END = 20F; + private static final float TWITCH_START = 0F; + private static final int DURATION = 200; + private final MaterialButton button; + private final ConstraintLayout container; + @DrawableRes + private int currentIcon; + @StringRes + private int currentText; + private boolean isAnimating; + private final Transition.TransitionListener listener = new Transition.TransitionListener() { + public void onTransitionStart(Transition transition) { + isAnimating = true; + } + + public void onTransitionEnd(Transition transition) { + isAnimating = false; + } + + public void onTransitionCancel(Transition transition) { + isAnimating = false; + } + + public void onTransitionPause(Transition transition) { + } + + public void onTransitionResume(Transition transition) { + } + }; + + public FabIconAnimator(ConstraintLayout container) { + this.container = container; + this.button = container.findViewById(R.id.fab); + } + + public void update(@DrawableRes int icon, @StringRes int text) { + boolean isSame = currentIcon == icon && currentText == text; + currentIcon = icon; + currentText = text; + animateChange(icon, text, isSame); + } + + public void setOnClickListener(@Nullable View.OnClickListener clickListener) { + if (clickListener == null) { + button.setOnClickListener(null); + return; + } + AtomicBoolean flag = new AtomicBoolean(true); + button.setOnClickListener(view -> { + if (!flag.getAndSet(false)) return; + clickListener.onClick(view); + button.postDelayed(() -> flag.set(true), 2000); + }); + } + + private boolean isExtended() { // R.dimen.triple_and_half_margin is 56 dp. + return button.getLayoutParams().height != button.getResources().getDimensionPixelSize(R.dimen.triple_and_half_margin); + } + + public void setExtended(boolean extended) { + setExtended(extended, false); + } + + private void animateChange(@DrawableRes int icon, @StringRes int text, boolean isSame) { + boolean extended = isExtended(); + button.setText(text); + button.setIconResource(icon); + setExtended(extended, !isSame); + if (!extended) twitch(); + } + + private void setExtended(boolean extended, boolean force) { + if (isAnimating || (extended && isExtended() && !force)) return; + + ConstraintSet set = new ConstraintSet(); + set.clone(container.getContext(), extended ? R.layout.fab_extended : R.layout.fab_collapsed); + + TransitionManager.beginDelayedTransition(container, new AutoTransition() + .addListener(listener).setDuration(150)); + + if (extended) button.setText(currentText); + else button.setText(""); + + set.applyTo(container); + } + + private void twitch() { + AnimatorSet set = new AnimatorSet(); + ObjectAnimator twitchA = animateProperty(ROTATION_Y_PROPERTY, TWITCH_START, TWITCH_END); + ObjectAnimator twitchB = animateProperty(ROTATION_Y_PROPERTY, TWITCH_END, TWITCH_START); + + set.play(twitchB).after(twitchA); + set.start(); + } + + @NonNull + private ObjectAnimator animateProperty(String property, float start, float end) { + return ObjectAnimator.ofFloat(container, property, start, end).setDuration(DURATION); + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/exfab/TransientBarBehavior.java b/app/src/main/java/code/name/monkey/retromusic/exfab/TransientBarBehavior.java new file mode 100644 index 00000000..132ed5de --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/exfab/TransientBarBehavior.java @@ -0,0 +1,75 @@ +/* + * 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.exfab; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.animation.Interpolator; + +import com.google.android.material.snackbar.Snackbar; + +import java.util.List; + +import androidx.annotation.NonNull; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.view.ViewCompat; +import androidx.interpolator.view.animation.FastOutSlowInInterpolator; + +public class TransientBarBehavior extends CoordinatorLayout.Behavior { + + private static final Interpolator fastOutSlowInInterpolator = new FastOutSlowInInterpolator(); + + public TransientBarBehavior(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, @NonNull View child, @NonNull View dependency) { + return dependency instanceof Snackbar.SnackbarLayout; + } + + @Override + public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent, @NonNull View child, @NonNull View dependency) { + if (child.getVisibility() == View.VISIBLE) { + float translationY = this.getViewTranslationYForSnackbar(parent, child); + child.setTranslationY(translationY); + } + return true; + } + + @Override + public void onDependentViewRemoved(@NonNull CoordinatorLayout parent, @NonNull View child, @NonNull View dependency) { + if (dependency instanceof Snackbar.SnackbarLayout && child.getTranslationY() != 0.0F) { + ViewCompat.animate(child).translationY(0.0F).scaleX(1.0F).scaleY(1.0F).alpha(1.0F) + .setInterpolator(fastOutSlowInInterpolator); + } + } + + private float getViewTranslationYForSnackbar(CoordinatorLayout parent, View child) { + float minOffset = 0.0F; + List dependencies = parent.getDependencies(child); + int i = 0; + + for (int z = dependencies.size(); i < z; ++i) { + View view = (View) dependencies.get(i); + if (view instanceof Snackbar.SnackbarLayout && parent.doViewsOverlap(child, view)) { + minOffset = Math.min(minOffset, view.getTranslationY() - (float) view.getHeight()); + } + } + + return minOffset; + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/glide/artistimage/ArtistImageLoader.kt b/app/src/main/java/code/name/monkey/retromusic/glide/artistimage/ArtistImageLoader.kt index 4e544005..aaeaa191 100644 --- a/app/src/main/java/code/name/monkey/retromusic/glide/artistimage/ArtistImageLoader.kt +++ b/app/src/main/java/code/name/monkey/retromusic/glide/artistimage/ArtistImageLoader.kt @@ -16,6 +16,7 @@ package code.name.monkey.retromusic.glide.artistimage import android.content.Context import android.text.TextUtils +import code.name.monkey.retromusic.App import code.name.monkey.retromusic.rest.LastFMRestClient import code.name.monkey.retromusic.rest.model.LastFmArtist import code.name.monkey.retromusic.util.LastFMUtil @@ -58,7 +59,7 @@ class ArtistImageFetcher(private val context: Context, private val lastFMRestCli override fun loadData(priority: Priority, callback: DataFetcher.DataCallback) { try { - if (!MusicUtil.isArtistNameUnknown(model.artistName) && RetroUtil.isAllowedToDownloadMetadata(context)) { + if (!MusicUtil.isArtistNameUnknown(model.artistName) && RetroUtil.isAllowedToDownloadMetadata(context) ) { call = lastFMRestClient.apiService.getArtistInfo(model.artistName, null, if (model.skipOkHttpCache) "no-cache" else null) call!!.enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { diff --git a/app/src/main/java/code/name/monkey/retromusic/misc/GenericFileProvider.java b/app/src/main/java/code/name/monkey/retromusic/misc/GenericFileProvider.java new file mode 100644 index 00000000..1e87ad8e --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/misc/GenericFileProvider.java @@ -0,0 +1,20 @@ +/* + * 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.core.content.FileProvider; + +public class GenericFileProvider extends FileProvider { +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/model/Contributor.kt b/app/src/main/java/code/name/monkey/retromusic/model/Contributor.kt index bd33bb85..fa71cdce 100644 --- a/app/src/main/java/code/name/monkey/retromusic/model/Contributor.kt +++ b/app/src/main/java/code/name/monkey/retromusic/model/Contributor.kt @@ -14,4 +14,6 @@ package code.name.monkey.retromusic.model -class Contributor(val name: String, val summary: String, val link: String, val profileImage: String) +import com.google.gson.annotations.SerializedName + +class Contributor(val name: String, val summary: String, val link: String, @SerializedName("profile_image") val profileImage: String) diff --git a/app/src/main/java/code/name/monkey/retromusic/model/lyrics/Lyrics.java b/app/src/main/java/code/name/monkey/retromusic/model/lyrics/Lyrics.java index 09599cdd..1cc25264 100644 --- a/app/src/main/java/code/name/monkey/retromusic/model/lyrics/Lyrics.java +++ b/app/src/main/java/code/name/monkey/retromusic/model/lyrics/Lyrics.java @@ -17,10 +17,8 @@ package code.name.monkey.retromusic.model.lyrics; import java.util.ArrayList; -import androidx.annotation.NonNull; import code.name.monkey.retromusic.model.Song; - public class Lyrics { private static final ArrayList> FORMATS = new ArrayList<>(); @@ -28,16 +26,12 @@ public class Lyrics { Lyrics.FORMATS.add(SynchronizedLyricsLRC.class); } - @NonNull public Song song; - @NonNull public String data; - protected boolean parsed = false; protected boolean valid = false; - @NonNull - public static Lyrics parse(@NonNull Song song, @NonNull String data) { + public static Lyrics parse(Song song, String data) { for (Class format : Lyrics.FORMATS) { try { Lyrics lyrics = format.newInstance().setData(song, data); @@ -49,7 +43,7 @@ public class Lyrics { return new Lyrics().setData(song, data).parse(false); } - public static boolean isSynchronized(@NonNull String data) { + public static boolean isSynchronized(String data) { for (Class format : Lyrics.FORMATS) { try { Lyrics lyrics = format.newInstance().setData(null, data); @@ -61,13 +55,12 @@ public class Lyrics { return false; } - public Lyrics setData(@NonNull Song song, @NonNull String data) { + public Lyrics setData(Song song, String data) { this.song = song; this.data = data; return this; } - @NonNull public Lyrics parse(boolean check) { this.valid = true; this.parsed = true; @@ -83,7 +76,6 @@ public class Lyrics { return this.valid; } - @NonNull public String getText() { return this.data.trim().replaceAll("(\r?\n){3,}", "\r\n\r\n"); } diff --git a/app/src/main/java/code/name/monkey/retromusic/rest/LastFMRestClient.java b/app/src/main/java/code/name/monkey/retromusic/rest/LastFMRestClient.java index 21268bdd..12c5616c 100644 --- a/app/src/main/java/code/name/monkey/retromusic/rest/LastFMRestClient.java +++ b/app/src/main/java/code/name/monkey/retromusic/rest/LastFMRestClient.java @@ -15,12 +15,16 @@ package code.name.monkey.retromusic.rest; import android.content.Context; + +import java.io.File; +import java.util.concurrent.TimeUnit; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import code.name.monkey.retromusic.rest.service.LastFMService; -import java.io.File; import okhttp3.Cache; import okhttp3.Call; +import okhttp3.ConnectionPool; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -31,50 +35,55 @@ import retrofit2.converter.gson.GsonConverterFactory; public class LastFMRestClient { - private static final String BASE_URL = "https://ws.audioscrobbler.com/2.0/"; + private static final String BASE_URL = "https://ws.audioscrobbler.com/2.0/"; - private LastFMService apiService; + private LastFMService apiService; - public LastFMRestClient(@NonNull Context context) { - this(createDefaultOkHttpClientBuilder(context).build()); - } - - public LastFMRestClient(@NonNull Call.Factory client) { - Retrofit restAdapter = new Retrofit.Builder() - .baseUrl(BASE_URL) - .callFactory(client) - .addConverterFactory(GsonConverterFactory.create()) - .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) - .build(); - - apiService = restAdapter.create(LastFMService.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); + public LastFMRestClient(@NonNull Context context) { + this(createDefaultOkHttpClientBuilder(context).build()); } - 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); - }; - } + public LastFMRestClient(@NonNull Call.Factory client) { + Retrofit restAdapter = new Retrofit.Builder() + .baseUrl(BASE_URL) + .callFactory(client) + .addConverterFactory(GsonConverterFactory.create()) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) + .build(); - public static OkHttpClient.Builder createDefaultOkHttpClientBuilder(Context context) { - return new OkHttpClient.Builder() - .cache(createDefaultCache(context)) - .addInterceptor(createCacheControlInterceptor()); - } + apiService = restAdapter.create(LastFMService.class); + } - public LastFMService getApiService() { - return apiService; - } + @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); + }; + } + + public static OkHttpClient.Builder createDefaultOkHttpClientBuilder(Context context) { + return new OkHttpClient.Builder() + .connectionPool(new ConnectionPool(0, 1, TimeUnit.NANOSECONDS)) + .retryOnConnectionFailure(true) + .connectTimeout(1, TimeUnit.MINUTES) // connect timeout + .writeTimeout(1, TimeUnit.MINUTES) // write timeout + .readTimeout(1, TimeUnit.MINUTES) // read timeout + .cache(createDefaultCache(context)) + .addInterceptor(createCacheControlInterceptor()); + } + + public LastFMService getApiService() { + return apiService; + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/AlbumDetailsActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/AlbumDetailsActivity.kt index afc8f2d8..fa8edde0 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/AlbumDetailsActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/AlbumDetailsActivity.kt @@ -1,6 +1,7 @@ package code.name.monkey.retromusic.ui.activities import android.content.Intent +import android.content.res.ColorStateList import android.graphics.Color import android.os.Bundle import android.transition.Slide @@ -15,6 +16,7 @@ import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.util.ColorUtil +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 @@ -91,10 +93,10 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac contentContainer.setOnScrollChangeListener { _: NestedScrollView?, _: Int, scrollY: Int, _: Int, oldScrollY: Int -> run { if (scrollY > oldScrollY) { - actionShuffleAll!!.setShowTitle(false) + actionShuffleAll.shrink(true) } if (scrollY < oldScrollY) { - actionShuffleAll!!.setShowTitle(true) + actionShuffleAll.extend(true) } } } @@ -109,7 +111,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac } private fun setupRecyclerView() { - simpleSongAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song,false) + simpleSongAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song, false) recyclerView.apply { layoutManager = LinearLayoutManager(this@AlbumDetailsActivity) itemAnimator = DefaultItemAnimator() @@ -255,7 +257,12 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac val themeColor = if (PreferenceUtil.getInstance().adaptiveColor) color else ThemeStore.accentColor(this) songTitle.setTextColor(themeColor) moreTitle.setTextColor(themeColor) - actionShuffleAll.setColor(themeColor) + + actionShuffleAll.backgroundTintList = ColorStateList.valueOf(themeColor) + ColorStateList.valueOf(MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(themeColor))).apply { + actionShuffleAll.setTextColor(this) + actionShuffleAll.iconTint = this + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/ArtistDetailActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/ArtistDetailActivity.kt index a8c2a457..74260809 100755 --- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/ArtistDetailActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/ArtistDetailActivity.kt @@ -2,6 +2,7 @@ package code.name.monkey.retromusic.ui.activities import android.app.Activity import android.content.Intent +import android.content.res.ColorStateList import android.graphics.Color import android.os.Build import android.os.Bundle @@ -18,6 +19,7 @@ import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.util.ColorUtil +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 @@ -89,10 +91,10 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac contentContainer.setOnScrollChangeListener { _: NestedScrollView?, _: Int, scrollY: Int, _: Int, oldScrollY: Int -> run { if (scrollY > oldScrollY) { - actionShuffleAll!!.setShowTitle(false) + actionShuffleAll.shrink(true) } if (scrollY < oldScrollY) { - actionShuffleAll!!.setShowTitle(true) + actionShuffleAll.extend(true) } } } @@ -294,7 +296,11 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac songTitle.setTextColor(textColor) biographyTitle.setTextColor(textColor) - actionShuffleAll.setColor(textColor) + actionShuffleAll.backgroundTintList = ColorStateList.valueOf(textColor) + ColorStateList.valueOf(MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(textColor))).apply { + actionShuffleAll.setTextColor(this) + actionShuffleAll.iconTint = this + } findViewById(R.id.root).setBackgroundColor(ThemeStore.primaryColor(this)) } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/GenreDetailsActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/GenreDetailsActivity.kt index 34682418..60bdfe95 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/GenreDetailsActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/GenreDetailsActivity.kt @@ -1,5 +1,6 @@ package code.name.monkey.retromusic.ui.activities +import android.content.res.ColorStateList import android.graphics.Color import android.os.Bundle import android.view.Menu @@ -10,6 +11,7 @@ import androidx.recyclerview.widget.LinearLayoutManager 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.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.helper.MusicPlayerRemote @@ -59,7 +61,7 @@ class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), GenreDetailsContrac setUpToolBar() setupRecyclerView() - actionShuffle.setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(songAdapter!!.dataSet, true) } + actionShuffleAll.setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(songAdapter!!.dataSet, true) } } private fun setUpToolBar() { @@ -74,7 +76,11 @@ class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), GenreDetailsContrac setSupportActionBar(this) ToolbarContentTintHelper.colorBackButton(this, ThemeStore.textColorSecondary(this@GenreDetailsActivity)) } - actionShuffle.setColor(ThemeStore.accentColor(this@GenreDetailsActivity)) + actionShuffleAll.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this)) + ColorStateList.valueOf(MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(ThemeStore.accentColor(this)))).apply { + actionShuffleAll.setTextColor(this) + actionShuffleAll.iconTint = this + } title = null } @@ -128,9 +134,9 @@ class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), GenreDetailsContrac override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) if (dy > 0) { - actionShuffle.setShowTitle(false) + actionShuffleAll.shrink(true) } else if (dy < 0) { - actionShuffle.setShowTitle(true) + actionShuffleAll.extend(true) } } }) diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/PlayingQueueActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/PlayingQueueActivity.kt index 7fbc75c7..cf385135 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/PlayingQueueActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/PlayingQueueActivity.kt @@ -1,9 +1,12 @@ package code.name.monkey.retromusic.ui.activities +import android.content.res.ColorStateList import android.os.Bundle import androidx.recyclerview.widget.LinearLayoutManager 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.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.helper.MusicPlayerRemote @@ -69,9 +72,9 @@ class PlayingQueueActivity : AbsMusicServiceActivity() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) if (dy > 0) { - clearQueue.setShowTitle(false) + clearQueue.shrink(true) } else if (dy < 0) { - clearQueue.setShowTitle(true) + clearQueue.extend(true) } } }) @@ -146,7 +149,12 @@ class PlayingQueueActivity : AbsMusicServiceActivity() { setSupportActionBar(toolbar) title = null toolbar.setNavigationOnClickListener { onBackPressed() } + ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.textColorSecondary(this)) - clearQueue.setColor(ThemeStore.accentColor(this)) + clearQueue.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this)) + ColorStateList.valueOf(MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(ThemeStore.accentColor(this)))).apply { + clearQueue.setTextColor(this) + clearQueue.iconTint = this + } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/PlaylistDetailActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/PlaylistDetailActivity.kt index 7fa70232..998eb81e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/PlaylistDetailActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/PlaylistDetailActivity.kt @@ -1,5 +1,6 @@ package code.name.monkey.retromusic.ui.activities +import android.content.res.ColorStateList import android.graphics.Color import android.os.Bundle import android.view.Menu @@ -9,6 +10,7 @@ import androidx.recyclerview.widget.LinearLayoutManager 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.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.helper.MusicPlayerRemote @@ -31,7 +33,7 @@ import com.afollestad.materialcab.MaterialCab import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils - +import kotlinx.android.synthetic.main.abs_playlists.* import kotlinx.android.synthetic.main.activity_playlist_detail.* import java.util.* @@ -102,13 +104,13 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) if (dy > 0) { - actionShuffle.setShowTitle(false) + actionShuffleAll.shrink(true) } else if (dy < 0) { - actionShuffle.setShowTitle(true) + actionShuffleAll.extend(true) } } }) - actionShuffle.setOnClickListener { + actionShuffleAll.setOnClickListener { if (adapter.dataSet.isEmpty()) { return@setOnClickListener } @@ -124,7 +126,12 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli private fun setUpToolBar() { bannerTitle.text = playlist!!.name bannerTitle.setTextColor(ThemeStore.textColorPrimary(this)) - actionShuffle.setColor(ThemeStore.accentColor(this)) + + actionShuffleAll.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this)) + ColorStateList.valueOf(MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(ThemeStore.accentColor(this)))).apply { + actionShuffleAll.setTextColor(this) + actionShuffleAll.iconTint = this + } val primaryColor = ThemeStore.primaryColor(this) toolbar!!.apply { diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/UserInfoActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/UserInfoActivity.kt index 6f480d00..5132d8ae 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/UserInfoActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/UserInfoActivity.kt @@ -1,25 +1,29 @@ package code.name.monkey.retromusic.ui.activities import android.app.Activity -import android.content.Context -import android.content.ContextWrapper -import android.content.Intent +import android.content.* 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 +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.MaterialUtil import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper +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.ui.activities.base.AbsBaseActivity import code.name.monkey.retromusic.util.Compressor import code.name.monkey.retromusic.util.ImageUtil +import code.name.monkey.retromusic.util.ImageUtil.getResizedBitmap import code.name.monkey.retromusic.util.PreferenceUtil import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.list.listItems @@ -46,8 +50,10 @@ class UserInfoActivity : AbsBaseActivity() { setupToolbar() bannerTitle.setTextColor(ThemeStore.textColorPrimary(this)) - nameContainer.boxStrokeColor = ThemeStore.accentColor(this) - name!!.setText(PreferenceUtil.getInstance().userName) + 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) @@ -57,7 +63,7 @@ class UserInfoActivity : AbsBaseActivity() { } userImage.setOnClickListener { MaterialDialog(this).show { - title(text = "Set a profile photo") + 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() @@ -70,12 +76,19 @@ class UserInfoActivity : AbsBaseActivity() { showBannerOptions() } next.setOnClickListener { - val nameString = name!!.text!!.toString().trim { it <= ' ' } + 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() } @@ -102,7 +115,6 @@ class UserInfoActivity : AbsBaseActivity() { } private fun showBannerOptions() { - MaterialDialog(this).show { title(R.string.select_banner_photo) listItems(items = listOf(getString(R.string.new_banner_photo), getString(R.string.remove_banner_photo))) @@ -150,21 +162,60 @@ class UserInfoActivity : AbsBaseActivity() { public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) - if (requestCode == PICK_IMAGE_REQUEST && resultCode == Activity.RESULT_OK && data != null && - data.data != null) { + if (resultCode == Activity.RESULT_OK) { + 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) + } + } + } + /*if (requestCode == PICK_IMAGE_REQUEST && resultCode == Activity.RESULT_OK && data != null && data.data != null) { + val picturePath = data.data + performCrop(picturePath) + } else if (requestCode == CROP_IMAGE_REQUEST && resultCode == Activity.RESULT_OK && data != null && data.data != null) { val uri = data.data try { val bitmap = ImageUtil.getResizedBitmap(Media.getBitmap(contentResolver, uri), PROFILE_ICON_SIZE) val profileImagePath = saveToInternalStorage(bitmap, USER_PROFILE) PreferenceUtil.getInstance().saveProfileImage(profileImagePath) loadImageFromStorage(profileImagePath) - } catch (e: IOException) { e.printStackTrace() } - - } - if (requestCode == PICK_BANNER_REQUEST && resultCode == Activity.RESULT_OK && data != null && + } else if (requestCode == PICK_BANNER_REQUEST && resultCode == Activity.RESULT_OK && data != null && data.data != null) { val uri = data.data try { @@ -176,6 +227,80 @@ class UserInfoActivity : AbsBaseActivity() { e.printStackTrace() } + }*/ + } + + + 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() } } @@ -225,7 +350,17 @@ class UserInfoActivity : AbsBaseActivity() { companion object { private const val PICK_IMAGE_REQUEST = 9002 - private const val PICK_BANNER_REQUEST = 9003 + 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/ui/activities/base/AbsSlidingMusicPanelActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsSlidingMusicPanelActivity.kt index c104c742..c1ec9306 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsSlidingMusicPanelActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsSlidingMusicPanelActivity.kt @@ -28,7 +28,6 @@ import code.name.monkey.retromusic.ui.fragments.player.material.MaterialFragment import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment import code.name.monkey.retromusic.ui.fragments.player.plain.PlainPlayerFragment import code.name.monkey.retromusic.ui.fragments.player.simple.SimplePlayerFragment -import code.name.monkey.retromusic.ui.fragments.player.slide.SlidePlayerFragment import code.name.monkey.retromusic.ui.fragments.player.tiny.TinyPlayerFragment import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.views.BottomNavigationBarTinted @@ -195,7 +194,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), Sliding MATERIAL -> MaterialFragment() COLOR -> ColorFragment() TINY -> TinyPlayerFragment() - SLIDE -> SlidePlayerFragment() + //SLIDE -> SlidePlayerFragment() else -> PlayerFragment() } // must implement AbsPlayerFragment supportFragmentManager.beginTransaction().replace(R.id.playerFragmentContainer, fragment).commit() @@ -262,7 +261,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), Sliding (currentNowPlayingScreen == NORMAL || currentNowPlayingScreen == FLAT)) { super.setLightNavigationBar(true) super.setLightStatusbar(isColorLight) - } else if (currentNowPlayingScreen == FULL || (currentNowPlayingScreen == SLIDE) || currentNowPlayingScreen == CARD || + } else if (currentNowPlayingScreen == FULL || currentNowPlayingScreen == CARD || currentNowPlayingScreen == FIT || /*currentNowPlayingScreen == NowPlayingScreen.CLASSIC ||*/ currentNowPlayingScreen == BLUR || currentNowPlayingScreen == BLUR_CARD) { super.setLightStatusbar(false) @@ -307,321 +306,4 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), Sliding } } -} -/*import android.animation.ArgbEvaluator -import android.animation.ValueAnimator -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.PersistableBundle -import android.view.View -import android.view.ViewGroup -import android.view.ViewTreeObserver -import androidx.annotation.FloatRange -import androidx.annotation.LayoutRes -import androidx.appcompat.app.AppCompatActivity -import androidx.fragment.app.Fragment -import code.name.monkey.appthemehelper.ThemeStore -import code.name.monkey.appthemehelper.util.ColorUtil -import code.name.monkey.retromusic.R -import code.name.monkey.retromusic.helper.MusicPlayerRemote -import code.name.monkey.retromusic.ui.fragments.MiniPlayerFragment -import code.name.monkey.retromusic.ui.fragments.NowPlayingScreen -import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment -import code.name.monkey.retromusic.ui.fragments.player.adaptive.AdaptiveFragment -import code.name.monkey.retromusic.ui.fragments.player.blur.BlurPlayerFragment -import code.name.monkey.retromusic.ui.fragments.player.card.CardFragment -import code.name.monkey.retromusic.ui.fragments.player.cardblur.CardBlurFragment -import code.name.monkey.retromusic.ui.fragments.player.color.ColorFragment -import code.name.monkey.retromusic.ui.fragments.player.fit.FitFragment -import code.name.monkey.retromusic.ui.fragments.player.flat.FlatPlayerFragment -import code.name.monkey.retromusic.ui.fragments.player.full.FullPlayerFragment -import code.name.monkey.retromusic.ui.fragments.player.material.MaterialFragment -import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment -import code.name.monkey.retromusic.ui.fragments.player.plain.PlainPlayerFragment -import code.name.monkey.retromusic.ui.fragments.player.simple.SimplePlayerFragment -import code.name.monkey.retromusic.ui.fragments.player.classic.ClassicPlayerFragment -import code.name.monkey.retromusic.util.PreferenceUtil -import code.name.monkey.retromusic.views.BottomNavigationBarTinted -import com.sothree.slidinguppanel.SlidingUpPanelLayout -import com.sothree.slidinguppanel.SlidingUpPanelLayout.PanelState -import kotlinx.android.synthetic.main.sliding_music_panel_layout.* - -abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), SlidingUpPanelLayout.PanelSlideListener, AbsPlayerFragment.Callbacks { - - - private var miniPlayerFragment: MiniPlayerFragment? = null - private var playerFragment: AbsPlayerFragment? = null - private var currentNowPlayingScreen: NowPlayingScreen? = null - private var navigationbarColor: Int = 0 - private var taskColor: Int = 0 - private var lightStatusbar: Boolean = false - private var lightNavigationBar: Boolean = false - private var navigationBarColorAnimator: ValueAnimator? = null - private val argbEvaluator = ArgbEvaluator() - - val panelState: SlidingUpPanelLayout.PanelState? - get() = slidingLayout.panelState - - private val isOneOfTheseThemes: Boolean - get() = (currentNowPlayingScreen == NowPlayingScreen.ADAPTIVE) - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(createContentView()) - - - chooseFragmentForTheme() - setupSlidingUpPanel() - } - - fun setBottomBarVisibility(gone: Int) { - bottomNavigationView.visibility = gone - hideBottomBar(false) - } - - protected abstract fun createContentView(): View - - override fun onServiceConnected() { - super.onServiceConnected() - if (!MusicPlayerRemote.playingQueue.isEmpty()) { - slidingLayout.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { - override fun onGlobalLayout() { - slidingLayout.viewTreeObserver.removeOnGlobalLayoutListener(this) - hideBottomBar(false) - } - }) - } // don't call hideBottomBar(true) here as it causes a bug with the SlidingUpPanelLayout - } - - override fun onQueueChanged() { - super.onQueueChanged() - hideBottomBar(MusicPlayerRemote.playingQueue.isEmpty()) - } - - fun hideBottomBar(hide: Boolean) { - val heightOfBar = resources.getDimensionPixelSize(R.dimen.mini_player_height) - val heightOfBarWithTabs = resources.getDimensionPixelSize(R.dimen.mini_player_height_expanded) - - if (hide) { - slidingLayout.panelHeight = 0 - collapsePanel() - } else { - if (!MusicPlayerRemote.playingQueue.isEmpty()) { - slidingLayout.panelHeight = if (bottomNavigationView.visibility == View.VISIBLE) heightOfBarWithTabs else heightOfBar - } - } - } - - protected fun wrapSlidingMusicPanel(@LayoutRes resId: Int): View { - @SuppressLint("InflateParams") - val slidingMusicPanelLayout = layoutInflater.inflate(R.layout.sliding_music_panel_layout, null) - val contentContainer = slidingMusicPanelLayout.findViewById(R.id.mainContentFrame) - layoutInflater.inflate(resId, contentContainer) - return slidingMusicPanelLayout - } - - override fun onBackPressed() { - if (!handleBackPress()) - super.onBackPressed() - } - - open fun handleBackPress(): Boolean { - if (slidingLayout.panelHeight != 0 && playerFragment!!.onBackPressed()) - return true - if (panelState == SlidingUpPanelLayout.PanelState.EXPANDED) { - collapsePanel() - return true - } - return false - } - - fun toggleBottomNavigationView(toggle: Boolean) { - bottomNavigationView.visibility = if (toggle) View.GONE else View.VISIBLE - } - - fun getBottomNavigationView(): BottomNavigationBarTinted { - return bottomNavigationView - } - - private fun setupSlidingUpPanel() { - slidingLayout.viewTreeObserver - .addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { - override fun onGlobalLayout() { - slidingLayout.viewTreeObserver.removeOnGlobalLayoutListener(this) - - if (panelState == PanelState.EXPANDED) { - onPanelSlide(slidingLayout, 1f) - onPanelExpanded() - } else if (panelState == PanelState.COLLAPSED) { - onPanelCollapsed() - } else { - playerFragment!!.onHide() - } - } - }) - - slidingLayout.addPanelSlideListener(this) - - } - - override fun onPanelSlide(panel: View?, slideOffset: Float) { - - setMiniPlayerAlphaProgress(slideOffset) - } - - override fun onPanelStateChanged(panel: View, previousState: PanelState, newState: PanelState) { - when (newState) { - SlidingUpPanelLayout.PanelState.COLLAPSED -> onPanelCollapsed() - SlidingUpPanelLayout.PanelState.EXPANDED -> onPanelExpanded() - SlidingUpPanelLayout.PanelState.ANCHORED -> collapsePanel() // this fixes a bug where the panel would get stuck for some reason - else -> { - } - } - } - - open fun onPanelCollapsed() { - // restore values - super.setLightStatusbar(lightStatusbar) - super.setTaskDescriptionColor(taskColor) - super.setNavigationbarColor(navigationbarColor) - super.setLightNavigationBar(lightNavigationBar) - - - playerFragment!!.setMenuVisibility(false) - playerFragment!!.userVisibleHint = false - playerFragment!!.onHide() - } - - open fun onPanelExpanded() { - val playerFragmentColor = playerFragment!!.paletteColor - super.setTaskDescriptionColor(playerFragmentColor) - - playerFragment!!.setMenuVisibility(true) - playerFragment!!.userVisibleHint = true - playerFragment!!.onShow() - onPaletteColorChanged() - } - - private fun setMiniPlayerAlphaProgress(@FloatRange(from = 0.0, to = 1.0) progress: Float) { - if (miniPlayerFragment!!.view == null) return - val alpha = 1 - progress - miniPlayerFragment!!.view!!.alpha = alpha - // necessary to make the views below clickable - miniPlayerFragment!!.view!!.visibility = if (alpha == 0f) View.GONE else View.VISIBLE - - bottomNavigationView.translationY = progress * 500 - bottomNavigationView.alpha = alpha - } - - private fun chooseFragmentForTheme() { - currentNowPlayingScreen = PreferenceUtil.getInstance().nowPlayingScreen - - val fragment: Fragment = when (currentNowPlayingScreen) { - NowPlayingScreen.BLUR -> BlurPlayerFragment() - NowPlayingScreen.ADAPTIVE -> AdaptiveFragment() - NowPlayingScreen.NORMAL -> PlayerFragment() - NowPlayingScreen.CARD -> CardFragment() - NowPlayingScreen.BLUR_CARD -> CardBlurFragment() - NowPlayingScreen.FIT -> FitFragment() - NowPlayingScreen.FLAT -> FlatPlayerFragment() - NowPlayingScreen.FULL -> FullPlayerFragment() - NowPlayingScreen.PLAIN -> PlainPlayerFragment() - NowPlayingScreen.SIMPLE -> SimplePlayerFragment() - NowPlayingScreen.MATERIAL -> MaterialFragment() - NowPlayingScreen.COLOR -> ColorFragment() - NowPlayingScreen.CLASSIC -> ClassicPlayerFragment() - else -> PlayerFragment() - } // must implement AbsPlayerFragment - supportFragmentManager.beginTransaction().replace(R.id.playerFragmentContainer, fragment).commit() - supportFragmentManager.executePendingTransactions() - - playerFragment = supportFragmentManager.findFragmentById(R.id.playerFragmentContainer) as AbsPlayerFragment - miniPlayerFragment = supportFragmentManager.findFragmentById(R.id.miniPlayerFragment) as MiniPlayerFragment - miniPlayerFragment!!.view!!.setOnClickListener { expandPanel() } - - } - - override fun onResume() { - super.onResume() - if (currentNowPlayingScreen != PreferenceUtil.getInstance().nowPlayingScreen) { - postRecreate() - } - } - - private fun collapsePanel() { - slidingLayout.panelState = PanelState.COLLAPSED - } - - fun expandPanel() { - slidingLayout.panelState = PanelState.EXPANDED - } - - - override fun onPaletteColorChanged() { - if (panelState == PanelState.EXPANDED) { - val paletteColor = playerFragment!!.paletteColor - super.setTaskDescriptionColor(paletteColor) - - val isColorLight = ColorUtil.isColorLight(paletteColor) - if (PreferenceUtil.getInstance().adaptiveColor && - (currentNowPlayingScreen == NowPlayingScreen.NORMAL || currentNowPlayingScreen == NowPlayingScreen.FLAT)) { - super.setLightNavigationBar(true) - super.setLightStatusbar(isColorLight) - } else if (currentNowPlayingScreen == NowPlayingScreen.FULL || currentNowPlayingScreen == NowPlayingScreen.CARD || - currentNowPlayingScreen == NowPlayingScreen.FIT || currentNowPlayingScreen == NowPlayingScreen.CLASSIC|| - currentNowPlayingScreen == NowPlayingScreen.BLUR || currentNowPlayingScreen == NowPlayingScreen.BLUR_CARD) { - super.setLightStatusbar(false) - super.setLightNavigationBar(true) - } else if (currentNowPlayingScreen == NowPlayingScreen.COLOR) { - super.setNavigationbarColor(paletteColor) - super.setLightNavigationBar(isColorLight) - super.setLightStatusbar(isColorLight) - } else { - super.setLightStatusbar(ColorUtil.isColorLight(ThemeStore.primaryColor(this))) - super.setLightNavigationBar(true) - } - } - } - - override fun setLightStatusbar(enabled: Boolean) { - lightStatusbar = enabled - if (panelState == PanelState.COLLAPSED) { - super.setLightStatusbar(enabled) - } - } - - override fun setLightNavigationBar(enabled: Boolean) { - lightNavigationBar = enabled - if (panelState == PanelState.COLLAPSED) { - super.setLightNavigationBar(enabled) - } - } - - override fun setNavigationbarColor(color: Int) { - navigationbarColor = color - if (panelState == PanelState.COLLAPSED) { - if (navigationBarColorAnimator != null) navigationBarColorAnimator!!.cancel() - super.setNavigationbarColor(color) - } - } - - override fun setTaskDescriptionColor(color: Int) { - taskColor = color - if (panelState == PanelState.COLLAPSED) { - super.setTaskDescriptionColor(color) - } - } - - override fun onDestroy() { - super.onDestroy() - if (navigationBarColorAnimator != null) navigationBarColorAnimator!!.cancel() // just in case - } - - companion object { - - val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName - } - fun setAntiDragView( antiDragView:View ) { - slidingLayout.setAntiDragView(antiDragView); - } -}*/ +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/tageditor/AbsTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/tageditor/AbsTagEditorActivity.kt index 2465420b..6acbb320 100755 --- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/tageditor/AbsTagEditorActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/tageditor/AbsTagEditorActivity.kt @@ -3,6 +3,7 @@ package code.name.monkey.retromusic.ui.activities.tageditor import android.app.Activity import android.app.SearchManager import android.content.Intent +import android.content.res.ColorStateList import android.graphics.Bitmap import android.graphics.BitmapFactory import android.net.Uri @@ -12,12 +13,15 @@ import android.view.MenuItem import android.view.View import android.view.animation.OvershootInterpolator import code.name.monkey.appthemehelper.ThemeStore +import code.name.monkey.appthemehelper.util.ColorUtil +import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity import code.name.monkey.retromusic.util.RetroUtil import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.list.listItems +import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton import kotlinx.android.synthetic.main.activity_album_tag_editor.* import org.jaudiotagger.audio.AudioFile import org.jaudiotagger.audio.AudioFileIO @@ -32,6 +36,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() { private var paletteColorPrimary: Int = 0 private var isInNoImageMode: Boolean = false private var songPaths: List? = null + lateinit var saveFab: ExtendedFloatingActionButton protected val show: MaterialDialog get() = MaterialDialog(this@AbsTagEditorActivity).show { @@ -169,7 +174,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() { super.onCreate(savedInstanceState) setContentView(contentViewLayout) - + saveFab = findViewById(R.id.saveTags) getIntentExtras() songPaths = getSongPaths() @@ -206,9 +211,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() { private fun startImagePicker() { val intent = Intent(Intent.ACTION_GET_CONTENT) intent.type = "image/*" - startActivityForResult( - Intent.createChooser(intent, getString(R.string.pick_from_local_storage)), - REQUEST_CODE_SELECT_IMAGE) + startActivityForResult(Intent.createChooser(intent, getString(R.string.pick_from_local_storage)), REQUEST_CODE_SELECT_IMAGE) } protected abstract fun loadCurrentImage() @@ -220,8 +223,11 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() { protected abstract fun deleteImage() private fun setUpFab() { - saveFab.setColor(ThemeStore.accentColor(this)) - saveFab.setShowTitle(true) + saveFab.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this)) + ColorStateList.valueOf(MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(ThemeStore.accentColor(this)))).apply { + saveFab.setTextColor(this) + saveFab.iconTint = this + } saveFab.apply { scaleX = 0f scaleY = 0f diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/tageditor/AlbumTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/tageditor/AlbumTagEditorActivity.kt index 67ec710f..cc9c02d7 100755 --- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/tageditor/AlbumTagEditorActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/tageditor/AlbumTagEditorActivity.kt @@ -14,6 +14,7 @@ import android.widget.Toast import androidx.core.content.ContextCompat import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.util.ATHUtil +import code.name.monkey.appthemehelper.util.MaterialUtil import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.retromusic.R @@ -89,6 +90,12 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher { private fun setUpViews() { fillViewsWithFileTags() + + MaterialUtil.setTint(yearContainer, false) + MaterialUtil.setTint(genreContainer, false) + MaterialUtil.setTint(albumTitleContainer, false) + MaterialUtil.setTint(albumArtistContainer, false) + albumText.addTextChangedListener(this) albumArtistText.addTextChangedListener(this) genreTitle.addTextChangedListener(this) diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/tageditor/SongTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/tageditor/SongTagEditorActivity.kt index 705feaed..81627036 100755 --- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/tageditor/SongTagEditorActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/tageditor/SongTagEditorActivity.kt @@ -6,6 +6,7 @@ import android.text.Editable import android.text.TextWatcher import androidx.core.content.ContextCompat import code.name.monkey.appthemehelper.ThemeStore +import code.name.monkey.appthemehelper.util.MaterialUtil import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.loaders.SongLoader @@ -43,6 +44,16 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher { private fun setUpViews() { fillViewsWithFileTags() + MaterialUtil.setTint(songTextContainer) + MaterialUtil.setTint(composerContainer, false) + MaterialUtil.setTint(albumTextContainer, false) + MaterialUtil.setTint(artistContainer, false) + MaterialUtil.setTint(albumArtistContainer, false) + MaterialUtil.setTint(yearContainer, false) + MaterialUtil.setTint(genreContainer, false) + MaterialUtil.setTint(trackNumberContainer, false) + MaterialUtil.setTint(lyricsContainer, false) + albumText.addTextChangedListener(this) songText.addTextChangedListener(this) albumText.addTextChangedListener(this) diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/adapter/ContributorAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/ui/adapter/ContributorAdapter.kt index 5c87da26..74e2fb02 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/adapter/ContributorAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/adapter/ContributorAdapter.kt @@ -4,12 +4,13 @@ import android.app.Activity import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import code.name.monkey.retromusic.R +import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.model.Contributor -import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.util.RetroUtil.openUrl -import code.name.monkey.retromusic.views.NetworkImageView +import code.name.monkey.retromusic.views.CircularImageView class ContributorAdapter(private var contributors: List) : RecyclerView.Adapter() { @@ -20,29 +21,28 @@ class ContributorAdapter(private var contributors: List) : Recycler override fun onBindViewHolder(holder: ViewHolder, position: Int) { val contributor = contributors[position] holder.bindData(contributor) + holder.itemView.setOnClickListener { + openUrl(it!!.context as Activity, contributors[position].link) + } } override fun getItemCount(): Int { return contributors.size } - inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) { + inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val title: TextView = itemView.findViewById(R.id.title) + val text: TextView = itemView.findViewById(R.id.text) + val image: CircularImageView = itemView.findViewById(R.id.image) internal fun bindData(contributor: Contributor) { - if (title != null) { - title!!.text = contributor.name - } - if (text != null) { - text!!.text = contributor.summary - } - if (image is NetworkImageView) { - (image as NetworkImageView).setImageUrl(contributor.profileImage) - } - } - - override fun onClick(v: View?) { - super.onClick(v) - openUrl(v!!.context as Activity, contributors[adapterPosition].link) + title.text = contributor.name + text.text = contributor.summary + GlideApp.with(image.context) + .load(contributor.profileImage) + .error(R.drawable.ic_person_flat) + .placeholder(R.drawable.ic_person_flat) + .into(image) } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/adapter/HomeAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/ui/adapter/HomeAdapter.kt index 951e6477..a7fdf581 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/adapter/HomeAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/adapter/HomeAdapter.kt @@ -31,7 +31,7 @@ import code.name.monkey.retromusic.views.MetalRecyclerViewPager import com.google.android.material.floatingactionbutton.FloatingActionButton -class HomeAdapter(private val activity: AppCompatActivity, private val homes: List, private val displayMetrics: DisplayMetrics) : RecyclerView.Adapter() { +class HomeAdapter(private val activity: AppCompatActivity, private var homes: List, private val displayMetrics: DisplayMetrics) : RecyclerView.Adapter() { override fun getItemViewType(position: Int): Int { @@ -81,6 +81,11 @@ class HomeAdapter(private val activity: AppCompatActivity, private val homes: Li return homes.size } + fun swapData(finalList: List) { + homes = finalList + notifyDataSetChanged() + } + companion object { @IntDef(SUGGESTIONS, RECENT_ALBUMS, TOP_ALBUMS, RECENT_ARTISTS, TOP_ARTISTS, GENRES, PLAYLISTS) diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/NowPlayingScreen.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/NowPlayingScreen.kt index f9fe46d5..f26b1156 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/NowPlayingScreen.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/NowPlayingScreen.kt @@ -22,6 +22,6 @@ enum class NowPlayingScreen constructor(@param:StringRes @field:StringRes PLAIN(R.string.plain, R.drawable.np_plain, 3), TINY(R.string.tiny, R.drawable.np_tiny, 7), SIMPLE(R.string.simple, R.drawable.np_simple, 8), - SLIDE(R.string.slide, R.drawable.np_slide, 13) + //SLIDE(R.string.slide, R.drawable.np_slide, 13) } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsLibraryPagerRecyclerViewFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsLibraryPagerRecyclerViewFragment.kt index a64b7f8d..ee93dd03 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsLibraryPagerRecyclerViewFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsLibraryPagerRecyclerViewFragment.kt @@ -10,6 +10,7 @@ import androidx.recyclerview.widget.RecyclerView import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.retromusic.R import code.name.monkey.retromusic.helper.MusicPlayerRemote +import code.name.monkey.retromusic.util.DensityUtil import code.name.monkey.retromusic.util.ViewUtil import com.google.android.material.appbar.AppBarLayout import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView @@ -64,10 +65,10 @@ abstract class AbsLibraryPagerRecyclerViewFragment, private fun checkForPadding() { val height = if (MusicPlayerRemote.playingQueue.isEmpty()) - resources.getDimensionPixelSize(R.dimen.mini_player_height) + DensityUtil.dip2px(context!!, 52f) else 0 - recyclerView.setPadding(0, 0, 0, height) + recyclerView.setPadding(0, 0, 0, (height * 2.3).toInt()) } private fun initLayoutManager() { diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsMusicServiceFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsMusicServiceFragment.kt index 48778ec9..6487572b 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsMusicServiceFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsMusicServiceFragment.kt @@ -16,14 +16,13 @@ open class AbsMusicServiceFragment : Fragment(), MusicServiceEventListener { var playerActivity: AbsMusicServiceActivity? = null private set - override fun onAttach(context: Context?) { + override fun onAttach(context: Context) { super.onAttach(context) try { playerActivity = context as AbsMusicServiceActivity? } catch (e: ClassCastException) { - throw RuntimeException(context!!.javaClass.simpleName + " must be an instance of " + AbsMusicServiceActivity::class.java.simpleName) + throw RuntimeException(context.javaClass.simpleName + " must be an instance of " + AbsMusicServiceActivity::class.java.simpleName) } - } override fun onDetach() { diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsPlayerFragment.kt index 41dad326..96f3e393 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsPlayerFragment.kt @@ -8,39 +8,38 @@ import android.media.MediaMetadataRetriever import android.os.AsyncTask import android.os.Bundle import android.provider.MediaStore +import android.text.TextUtils import android.view.MenuItem import android.view.View import android.widget.Toast import androidx.appcompat.widget.Toolbar import code.name.monkey.appthemehelper.ThemeStore - import code.name.monkey.retromusic.R import code.name.monkey.retromusic.dialogs.* import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.interfaces.PaletteColorHolder import code.name.monkey.retromusic.model.Song +import code.name.monkey.retromusic.model.lyrics.Lyrics import code.name.monkey.retromusic.ui.activities.tageditor.AbsTagEditorActivity import code.name.monkey.retromusic.ui.activities.tageditor.SongTagEditorActivity import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment -import code.name.monkey.retromusic.util.MusicUtil -import code.name.monkey.retromusic.util.NavigationUtil -import code.name.monkey.retromusic.util.PreferenceUtil -import code.name.monkey.retromusic.util.RetroUtil +import code.name.monkey.retromusic.util.* import code.name.monkey.retromusic.views.FitSystemWindowsLayout - +import java.io.FileNotFoundException abstract class AbsPlayerFragment : AbsMusicServiceFragment(), Toolbar.OnMenuItemClickListener, PaletteColorHolder, PlayerAlbumCoverFragment.Callbacks { var callbacks: Callbacks? = null private set private var updateIsFavoriteTask: AsyncTask<*, *, *>? = null + private var updateLyricsAsyncTask: AsyncTask<*, *, *>? = null + private var playerAlbumCoverFragment: PlayerAlbumCoverFragment? = null - - override fun onAttach(context: Context?) { + override fun onAttach(context: Context) { super.onAttach(context) try { callbacks = context as Callbacks? } catch (e: ClassCastException) { - throw RuntimeException(context!!.javaClass.simpleName + " must implement " + Callbacks::class.java.simpleName) + throw RuntimeException(context.javaClass.simpleName + " must implement " + Callbacks::class.java.simpleName) } } @@ -158,16 +157,21 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(), Toolbar.OnMenuItem override fun onServiceConnected() { updateIsFavorite() + updateLyrics() } override fun onPlayingMetaChanged() { updateIsFavorite() + updateLyrics() } override fun onDestroyView() { if (updateIsFavoriteTask != null && !updateIsFavoriteTask!!.isCancelled) { updateIsFavoriteTask!!.cancel(true) } + if (updateLyricsAsyncTask != null && !updateLyricsAsyncTask!!.isCancelled) { + updateLyricsAsyncTask!!.cancel(true) + } super.onDestroyView() } @@ -202,16 +206,58 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(), Toolbar.OnMenuItem }.execute(MusicPlayerRemote.currentSong) } + @SuppressLint("StaticFieldLeak") + private fun updateLyrics() { + if (updateLyricsAsyncTask != null) updateLyricsAsyncTask!!.cancel(false) + + updateLyricsAsyncTask = object : AsyncTask() { + override fun onPreExecute() { + super.onPreExecute() + setLyrics(null) + } + + override fun doInBackground(vararg params: Song): Lyrics? { + try { + var data: String? = LyricUtil.getStringFromFile(params[0].title, params[0].artistName) + return if (TextUtils.isEmpty(data)) { + data = MusicUtil.getLyrics(params[0]) + return if (TextUtils.isEmpty(data)) { + null + } else { + Lyrics.parse(params[0], data) + } + } else Lyrics.parse(params[0], data!!) + } catch (err: FileNotFoundException) { + return null + } + } + + override fun onPostExecute(l: Lyrics?) { + setLyrics(l) + } + + override fun onCancelled(s: Lyrics?) { + onPostExecute(null) + } + }.execute(MusicPlayerRemote.currentSong) + } + + open fun setLyrics(l: Lyrics?) { + + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) view.setBackgroundColor(ThemeStore.primaryColor(activity!!)) if (PreferenceUtil.getInstance().fullScreenMode && view.findViewById(R.id.status_bar) != null) { view.findViewById(R.id.status_bar).visibility = View.GONE } + playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment? + playerAlbumCoverFragment?.setCallbacks(this) } fun setSafeArea(safeArea: View) { - val layout = safeArea.findViewById(code.name.monkey.retromusic.R.id.safeArea) + val layout = safeArea.findViewById(R.id.safeArea) if (layout != null) { layout.isFit = !PreferenceUtil.getInstance().fullScreenMode } @@ -224,6 +270,7 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(), Toolbar.OnMenuItem companion object { val TAG: String = AbsPlayerFragment::class.java.simpleName + const val VISIBILITY_ANIM_DURATION: Long = 300 } protected fun getUpNextAndQueueTime(): String { diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/GenreFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/GenreFragment.kt index 2d8725ca..a31c151a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/GenreFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/GenreFragment.kt @@ -72,10 +72,9 @@ class GenreFragment : AbsLibraryPagerRecyclerViewFragment RetroUtil.convertDpToPixel(52f, context).toInt() + else -> RetroUtil.convertDpToPixel(0f, context).toInt() + } + + (recyclerView.layoutParams as ViewGroup.MarginLayoutParams).bottomMargin = (marginSpan * 2.3f).toInt() } private fun setupToolbar() { @@ -210,10 +224,22 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba } + override fun onServiceConnected() { + super.onServiceConnected() + checkPadding() + } + + override fun onQueueChanged() { + super.onQueueChanged() + checkPadding() + } + + private lateinit var homeAdapter: HomeAdapter + override fun showData(list: ArrayList) { val finalList = list.sortedWith(compareBy { it.priority }) + homeAdapter.swapData(finalList) recyclerView.apply { - val homeAdapter = HomeAdapter(mainActivity, finalList, displayMetrics) layoutManager = LinearLayoutManager(mainActivity) adapter = homeAdapter } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/PlayerAlbumCoverFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/PlayerAlbumCoverFragment.kt index 482cabb5..73b16d5d 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/PlayerAlbumCoverFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/PlayerAlbumCoverFragment.kt @@ -4,9 +4,13 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.TextView import androidx.viewpager.widget.ViewPager -import code.name.monkey.retromusic.R import code.name.monkey.retromusic.helper.MusicPlayerRemote +import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper +import code.name.monkey.retromusic.model.lyrics.AbsSynchronizedLyrics +import code.name.monkey.retromusic.model.lyrics.Lyrics import code.name.monkey.retromusic.transform.CarousalPagerTransformer import code.name.monkey.retromusic.transform.ParallaxPagerTransformer import code.name.monkey.retromusic.ui.adapter.album.AlbumCoverPagerAdapter @@ -17,6 +21,10 @@ import kotlinx.android.synthetic.main.fragment_player_album_cover.* class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChangeListener { + + + + private var callbacks: Callbacks? = null private var currentPosition: Int = 0 private val colorReceiver = object : AlbumCoverPagerAdapter.AlbumCoverFragment.ColorReceiver { @@ -28,7 +36,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan } fun removeSlideEffect() { - val transformer = ParallaxPagerTransformer(R.id.player_image) + val transformer = ParallaxPagerTransformer(code.name.monkey.retromusic.R.id.player_image) transformer.setSpeed(0.3f) viewPager.setPageTransformer(true, transformer) @@ -36,11 +44,13 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.fragment_player_album_cover, container, false) + return inflater.inflate(code.name.monkey.retromusic.R.layout.fragment_player_album_cover, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + viewPager.addOnPageChangeListener(this) //noinspection ConstantConditions if (PreferenceUtil.getInstance().carouselEffect() && @@ -55,10 +65,13 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan viewPager.offscreenPageLimit = 2 viewPager.setPageTransformer(true, PreferenceUtil.getInstance().albumCoverTransform) } + + } override fun onDestroyView() { super.onDestroyView() + viewPager.removeOnPageChangeListener(this) } @@ -125,7 +138,11 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan } + + companion object { val TAG: String = PlayerAlbumCoverFragment::class.java.simpleName + + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/classic/ClassicPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/classic/ClassicPlayerFragment.kt index 78e82107..6e6d1bf0 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/classic/ClassicPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/classic/ClassicPlayerFragment.kt @@ -113,7 +113,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Call private lateinit var wrappedAdapter: RecyclerView.Adapter<*> private lateinit var recyclerViewDragDropManager: RecyclerViewDragDropManager - private var lyrics: Lyrics? = null + private var lyricsClassic: Lyrics? = null private lateinit var impl: Impl @@ -335,7 +335,7 @@ class PortraitImpl(private val fragment: ClassicPlayerFragment) : BaseImpl(fragm return true } code.name.monkey.retromusic.R.id.action_share -> { - SongShareDialog.create(song).show(fragment.fragmentManager, "SONG_SHARE_DIALOG") + SongShareDialog.create(song).show(fragment.fragmentManager!!, "SONG_SHARE_DIALOG") return true } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/color/ColorFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/color/ColorFragment.kt index cebed514..511f82e0 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/color/ColorFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/color/ColorFragment.kt @@ -58,7 +58,7 @@ class ColorFragment : AbsPlayerFragment() { private var valueAnimator: ValueAnimator? = null private var updateLyricsAsyncTask: AsyncTask<*, *, *>? = null - private var lyrics: Lyrics? = null + private var lyricsColor: Lyrics? = null override fun onShow() { playbackControlsFragment!!.show() @@ -250,7 +250,7 @@ class ColorFragment : AbsPlayerFragment() { updateLyricsAsyncTask = object : AsyncTask() { override fun onPreExecute() { super.onPreExecute() - lyrics = null + lyricsColor = null playerToolbar.menu.removeItem(R.id.action_show_lyrics) } @@ -262,11 +262,11 @@ class ColorFragment : AbsPlayerFragment() { } override fun onPostExecute(l: Lyrics?) { - lyrics = l - if (lyrics == null) { + lyricsColor = l + if (lyricsColor == null) { lyricsView.setText(R.string.no_lyrics_found) } else { - lyricsView.text = lyrics!!.text + lyricsView.text = lyricsColor!!.text } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/full/FullPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/full/FullPlayerFragment.kt index d083519c..48d071b9 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/full/FullPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/full/FullPlayerFragment.kt @@ -5,6 +5,8 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.TextView import androidx.appcompat.widget.Toolbar import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.retromusic.R @@ -14,8 +16,11 @@ 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.loaders.ArtistLoader import code.name.monkey.retromusic.model.Song +import code.name.monkey.retromusic.model.lyrics.AbsSynchronizedLyrics +import code.name.monkey.retromusic.model.lyrics.Lyrics import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.util.NavigationUtil @@ -24,7 +29,85 @@ import io.reactivex.disposables.CompositeDisposable import io.reactivex.schedulers.Schedulers import kotlinx.android.synthetic.main.fragment_full.* -class FullPlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks { +class FullPlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks, MusicProgressViewUpdateHelper.Callback { + private lateinit var lyricsLayout: FrameLayout + private lateinit var lyricsLine1: TextView + private lateinit var lyricsLine2: TextView + + private var lyrics: Lyrics? = null + private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper + + override fun onUpdateProgressViews(progress: Int, total: Int) { + if (!isLyricsLayoutBound()) return + + if (!isLyricsLayoutVisible()) { + hideLyricsLayout() + return + } + + if (lyrics !is AbsSynchronizedLyrics) return + val synchronizedLyrics = lyrics as AbsSynchronizedLyrics + + lyricsLayout.visibility = View.VISIBLE + lyricsLayout.alpha = 1f + + val oldLine = lyricsLine2.text.toString() + val line = synchronizedLyrics.getLine(progress) + + if (oldLine != line || oldLine.isEmpty()) { + lyricsLine1.text = oldLine + lyricsLine2.text = line + + lyricsLine1.visibility = View.VISIBLE + lyricsLine2.visibility = View.VISIBLE + + lyricsLine2.measure(View.MeasureSpec.makeMeasureSpec(lyricsLine2.measuredWidth, View.MeasureSpec.EXACTLY), View.MeasureSpec.UNSPECIFIED) + val h: Float = lyricsLine2.measuredHeight.toFloat() + + lyricsLine1.alpha = 1f + lyricsLine1.translationY = 0f + lyricsLine1.animate().alpha(0f).translationY(-h).duration = VISIBILITY_ANIM_DURATION + + lyricsLine2.alpha = 0f + lyricsLine2.translationY = h + lyricsLine2.animate().alpha(1f).translationY(0f).duration = VISIBILITY_ANIM_DURATION + } + } + + private fun isLyricsLayoutVisible(): Boolean { + return lyrics != null && lyrics!!.isSynchronized && lyrics!!.isValid + } + + private fun isLyricsLayoutBound(): Boolean { + return lyricsLayout != null && lyricsLine1 != null && lyricsLine2 != null + } + + private fun hideLyricsLayout() { + lyricsLayout.animate().alpha(0f).setDuration( VISIBILITY_ANIM_DURATION).withEndAction(Runnable { + if (!isLyricsLayoutBound()) return@Runnable + lyricsLayout.visibility = View.GONE + lyricsLine1.text = null + lyricsLine2.text = null + }) + } + + override fun setLyrics(l: Lyrics?) { + lyrics = l + + if (!isLyricsLayoutBound()) return + + if (!isLyricsLayoutVisible()) { + hideLyricsLayout() + return + } + + lyricsLine1.text = null + lyricsLine2.text = null + + lyricsLayout.visibility = View.VISIBLE + lyricsLayout.animate().alpha(1f).duration = VISIBILITY_ANIM_DURATION + } + override fun playerToolbar(): Toolbar { return playerToolbar } @@ -48,11 +131,17 @@ class FullPlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbac override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + lyricsLayout = view.findViewById(R.id.player_lyrics) + lyricsLine1 = view.findViewById(R.id.player_lyrics_line1) + lyricsLine2 = view.findViewById(R.id.player_lyrics_line2) + setUpSubFragments() setUpPlayerToolbar() setupArtist() - nextSong.isSelected = true + + progressViewUpdateHelper = MusicProgressViewUpdateHelper(this, 500, 1000) + progressViewUpdateHelper.start() } private fun setupArtist() { @@ -118,6 +207,7 @@ class FullPlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbac override fun onDestroyView() { super.onDestroyView() + progressViewUpdateHelper.stop() compositeDisposable.dispose() } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/normal/PlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/normal/PlayerFragment.kt index a0791afa..7197a39f 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/normal/PlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/normal/PlayerFragment.kt @@ -69,21 +69,12 @@ class PlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks { lastColor = color callbacks!!.onPaletteColorChanged() - ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, code.name.monkey.retromusic.R.attr.iconColor), activity) + ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, R.attr.iconColor), activity) if (PreferenceUtil.getInstance().adaptiveColor) { colorize(color) } - - 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 getCutOff(): Int { @@ -105,7 +96,7 @@ class PlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(code.name.monkey.retromusic.R.layout.fragment_player, container, false) + return inflater.inflate(R.layout.fragment_player, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -113,12 +104,22 @@ class PlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks { 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(code.name.monkey.retromusic.R.id.playbackControlsFragment) as PlayerPlaybackControlsFragment - val playerAlbumCoverFragment = childFragmentManager.findFragmentById(code.name.monkey.retromusic.R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment - playerAlbumCoverFragment.setCallbacks(this) + playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as PlayerPlaybackControlsFragment + } private fun setUpPlayerToolbar() { @@ -126,7 +127,7 @@ class PlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks { playerToolbar.setNavigationOnClickListener { activity!!.onBackPressed() } playerToolbar.setOnMenuItemClickListener(this) - ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, code.name.monkey.retromusic.R.attr.iconColor), activity) + ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, R.attr.iconColor), activity) } override fun onServiceConnected() { @@ -144,7 +145,6 @@ class PlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks { companion object { - fun newInstance(): PlayerFragment { return PlayerFragment() } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/AbsSettingsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/AbsSettingsFragment.kt index 48a930d2..a30b276a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/AbsSettingsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/AbsSettingsFragment.kt @@ -71,10 +71,11 @@ abstract class AbsSettingsFragment : PreferenceFragmentCompat() { if (dialogFragment != null) { // The dialog was created (it was one of our custom Preferences), show the dialog for it dialogFragment.setTargetFragment(this, 0); - dialogFragment.show(this.fragmentManager, "android.support.v7.preference.PreferenceFragment.DIALOG"); + dialogFragment.show(this.fragmentManager!!, "android.support.v7.preference.PreferenceFragment.DIALOG"); } else { // Dialog creation could not be handled here. Try with the super method. super.onDisplayPreferenceDialog(preference); } + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/AudioSettings.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/AudioSettings.kt index 929eda46..8ecb9df6 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/AudioSettings.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/AudioSettings.kt @@ -1,12 +1,9 @@ package code.name.monkey.retromusic.ui.fragments.settings import android.content.Intent -import android.content.pm.PackageManager -import android.content.pm.ResolveInfo import android.media.audiofx.AudioEffect import android.os.Bundle import androidx.preference.Preference - import code.name.monkey.retromusic.R import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.PreferenceUtil @@ -17,7 +14,7 @@ import code.name.monkey.retromusic.util.PreferenceUtil class AudioSettings : AbsSettingsFragment() { override fun invalidateSettings() { - val findPreference = findPreference("equalizer") + val findPreference: Preference = findPreference("equalizer")!! if (!hasEqualizer() && PreferenceUtil.getInstance().selectedEqualizer != "retro") { findPreference.isEnabled = false findPreference.summary = resources.getString(R.string.no_equalizer) diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/ImageSettingFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/ImageSettingFragment.kt index ca871d74..b7ac3a8c 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/ImageSettingFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/ImageSettingFragment.kt @@ -2,6 +2,7 @@ package code.name.monkey.retromusic.ui.fragments.settings import android.os.Bundle import android.view.View +import androidx.preference.Preference import code.name.monkey.retromusic.R /** @@ -10,7 +11,7 @@ import code.name.monkey.retromusic.R class ImageSettingFragment : AbsSettingsFragment() { override fun invalidateSettings() { - val autoDownloadImagesPolicy = findPreference("auto_download_images_policy") + val autoDownloadImagesPolicy: Preference = findPreference("auto_download_images_policy")!! setSummary(autoDownloadImagesPolicy) autoDownloadImagesPolicy.setOnPreferenceChangeListener { _, o -> setSummary(autoDownloadImagesPolicy, o) @@ -25,7 +26,7 @@ class ImageSettingFragment : AbsSettingsFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val preference = findPreference("auto_download_images_policy") + val preference: Preference = findPreference("auto_download_images_policy")!! setSummary(preference) } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/NotificationSettingsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/NotificationSettingsFragment.kt index ae25ba13..fc3dfe4c 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/NotificationSettingsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/NotificationSettingsFragment.kt @@ -3,10 +3,8 @@ package code.name.monkey.retromusic.ui.fragments.settings import android.os.Build import android.os.Bundle import androidx.preference.TwoStatePreference - import code.name.monkey.retromusic.R import code.name.monkey.retromusic.helper.MusicPlayerRemote -import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.util.PreferenceUtil /** @@ -15,7 +13,7 @@ import code.name.monkey.retromusic.util.PreferenceUtil class NotificationSettingsFragment : AbsSettingsFragment() { override fun invalidateSettings() { - val classicNotification = findPreference("classic_notification") as TwoStatePreference + val classicNotification: TwoStatePreference = findPreference("classic_notification")!! if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { classicNotification.isVisible = false } else { diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/NowPlayingSettingsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/NowPlayingSettingsFragment.kt index d353055d..4888bcad 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/NowPlayingSettingsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/NowPlayingSettingsFragment.kt @@ -3,10 +3,10 @@ package code.name.monkey.retromusic.ui.fragments.settings import android.content.SharedPreferences import android.os.Bundle import android.view.View +import androidx.preference.Preference import androidx.preference.TwoStatePreference import code.name.monkey.retromusic.App import code.name.monkey.retromusic.R -import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil.* /** @@ -19,7 +19,7 @@ class NowPlayingSettingsFragment : AbsSettingsFragment(), SharedPreferences.OnSh updateNowPlayingScreenSummary() updateAlbumCoverStyleSummary() - val carouselEffect = findPreference("carousel_effect") as TwoStatePreference + val carouselEffect: TwoStatePreference = findPreference("carousel_effect")!! carouselEffect.setOnPreferenceChangeListener { _, newValue -> if (newValue as Boolean && !App.isProVersion) { showProToastAndNavigate(activity!!.getString(R.string.pref_title_toggle_carousel_effect)) @@ -34,17 +34,19 @@ class NowPlayingSettingsFragment : AbsSettingsFragment(), SharedPreferences.OnSh } private fun updateAlbumCoverStyleSummary() { - findPreference(ALBUM_COVER_STYLE).setSummary(getInstance().albumCoverStyle.titleRes) + val preference: Preference = findPreference(ALBUM_COVER_STYLE)!! + preference.setSummary(getInstance().albumCoverStyle.titleRes) } private fun updateNowPlayingScreenSummary() { - findPreference(NOW_PLAYING_SCREEN_ID).setSummary(getInstance().nowPlayingScreen.titleRes) + val preference: Preference = findPreference(NOW_PLAYING_SCREEN_ID)!! + preference.setSummary(getInstance().nowPlayingScreen.titleRes) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) getInstance().registerOnSharedPreferenceChangedListener(this) - val preference = findPreference("album_cover_transform") + val preference: Preference = findPreference("album_cover_transform")!! setSummary(preference) } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/OtherSettingsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/OtherSettingsFragment.kt index 2bda1f00..d76e9bc3 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/OtherSettingsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/OtherSettingsFragment.kt @@ -2,6 +2,7 @@ package code.name.monkey.retromusic.ui.fragments.settings import android.os.Bundle import android.view.View +import androidx.preference.Preference import code.name.monkey.retromusic.R @@ -22,7 +23,7 @@ class OtherSettingsFragment : AbsSettingsFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val preference = findPreference("last_added_interval") + val preference: Preference = findPreference("last_added_interval")!! setSummary(preference) } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/PersonaizeSettingsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/PersonaizeSettingsFragment.kt index a97beecc..b3ed43f7 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/PersonaizeSettingsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/PersonaizeSettingsFragment.kt @@ -3,6 +3,7 @@ package code.name.monkey.retromusic.ui.fragments.settings import android.content.SharedPreferences import android.os.Bundle import android.view.View +import androidx.preference.Preference import androidx.preference.TwoStatePreference import code.name.monkey.retromusic.App import code.name.monkey.retromusic.R @@ -12,7 +13,7 @@ import code.name.monkey.retromusic.util.PreferenceUtil class PersonaizeSettingsFragment : AbsSettingsFragment(), SharedPreferences.OnSharedPreferenceChangeListener { override fun invalidateSettings() { - val cornerWindow = findPreference("corner_window") as TwoStatePreference + val cornerWindow: TwoStatePreference = findPreference("corner_window")!! cornerWindow.setOnPreferenceChangeListener { _, newValue -> if (newValue as Boolean && !App.isProVersion) { showProToastAndNavigate(activity!!.getString(R.string.pref_title_round_corners)) @@ -23,7 +24,7 @@ class PersonaizeSettingsFragment : AbsSettingsFragment(), SharedPreferences.OnSh } - val toggleFullScreen = findPreference("toggle_full_screen") as TwoStatePreference + val toggleFullScreen: TwoStatePreference = findPreference("toggle_full_screen")!! toggleFullScreen.setOnPreferenceChangeListener { _, _ -> activity!!.recreate() true @@ -40,14 +41,14 @@ class PersonaizeSettingsFragment : AbsSettingsFragment(), SharedPreferences.OnSh super.onViewCreated(view, savedInstanceState) PreferenceUtil.getInstance().registerOnSharedPreferenceChangedListener(this) - var preference = findPreference("album_grid_style") - setSummary(preference) + var preference: Preference? = findPreference("album_grid_style") + setSummary(preference!!) preference = findPreference("artist_grid_style") - setSummary(preference) + setSummary(preference!!) preference = findPreference("home_artist_grid_style") - setSummary(preference) + setSummary(preference!!) preference = findPreference("tab_text_mode") - setSummary(preference) + setSummary(preference!!) } override fun onDestroyView() { diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/ThemeSettingsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/ThemeSettingsFragment.kt index 409449e9..11f50405 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/ThemeSettingsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/ThemeSettingsFragment.kt @@ -5,6 +5,7 @@ import android.graphics.Color.BLUE import android.os.Build import android.os.Bundle import androidx.core.content.ContextCompat +import androidx.preference.Preference import androidx.preference.TwoStatePreference import code.name.monkey.appthemehelper.* import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEColorPreference @@ -25,7 +26,7 @@ import com.afollestad.materialdialogs.color.colorChooser class ThemeSettingsFragment : AbsSettingsFragment() { override fun invalidateSettings() { - val primaryColorPref = findPreference("primary_color") as ATEColorPreference + val primaryColorPref: ATEColorPreference = findPreference("primary_color")!! primaryColorPref.isVisible = PreferenceUtil.getInstance().generalTheme == code.name.monkey.retromusic.R.style.Theme_RetroMusic_Color val primaryColor = ThemeStore.primaryColor(activity!!) primaryColorPref.setColor(primaryColor, ColorUtil.darkenColor(primaryColor)) @@ -49,7 +50,7 @@ class ThemeSettingsFragment : AbsSettingsFragment() { true } - val generalTheme = findPreference("general_theme") + val generalTheme: Preference = findPreference("general_theme")!! setSummary(generalTheme) generalTheme.setOnPreferenceChangeListener { _, newValue -> val theme = newValue as String @@ -85,7 +86,7 @@ class ThemeSettingsFragment : AbsSettingsFragment() { true } - val accentColorPref = findPreference("accent_color") as ATEColorPreference + val accentColorPref: ATEColorPreference = findPreference("accent_color")!! val accentColor = ThemeStore.accentColor(activity!!) accentColorPref.setColor(accentColor, ColorUtil.darkenColor(accentColor)) @@ -103,7 +104,7 @@ class ThemeSettingsFragment : AbsSettingsFragment() { return@setOnPreferenceClickListener true } - val colorAppShortcuts = findPreference("should_color_app_shortcuts") as TwoStatePreference + val colorAppShortcuts: TwoStatePreference = findPreference("should_color_app_shortcuts")!! if (!VersionUtils.hasNougatMR()) { colorAppShortcuts.isVisible = false } else { diff --git a/app/src/main/java/code/name/monkey/retromusic/util/ImagePicker.java b/app/src/main/java/code/name/monkey/retromusic/util/ImagePicker.java new file mode 100644 index 00000000..b7bc2dba --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/util/ImagePicker.java @@ -0,0 +1,202 @@ +/* + * 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.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ResolveInfo; +import android.content.res.AssetFileDescriptor; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Matrix; +import android.media.ExifInterface; +import android.net.Uri; +import android.provider.DocumentsContract; +import android.provider.MediaStore; +import android.util.Log; + +import androidx.annotation.Nullable; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.List; + +import code.name.monkey.retromusic.App; + +/** + * Author: Mario Velasco Casquero + * Date: 08/09/2015 + * Email: m3ario@gmail.com + */ +public class ImagePicker { + private static final int DEFAULT_MIN_WIDTH_QUALITY = 400; // min pixels + private static final String TAG = "ImagePicker"; + private static final String TEMP_IMAGE_NAME = "tempImage"; + public static int minWidthQuality = DEFAULT_MIN_WIDTH_QUALITY; + + + + private static List addIntentsToList(Context context, List list, Intent intent) { + List resInfo = context.getPackageManager().queryIntentActivities(intent, 0); + for (ResolveInfo resolveInfo : resInfo) { + String packageName = resolveInfo.activityInfo.packageName; + Intent targetedIntent = new Intent(intent); + targetedIntent.setPackage(packageName); + list.add(targetedIntent); + Log.d(TAG, "Intent: " + intent.getAction() + " package: " + packageName); + } + return list; + } + + + public static Bitmap getImageFromResult(Context context, int resultCode, + Intent imageReturnedIntent) { + Log.d(TAG, "getImageFromResult, resultCode: " + resultCode); + Bitmap bm = null; + File imageFile = getTempFile(context); + if (resultCode == Activity.RESULT_OK) { + Uri selectedImage; + boolean isCamera = (imageReturnedIntent == null || + imageReturnedIntent.getData() == null || + imageReturnedIntent.getData().toString().contains(imageFile.toString())); + if (isCamera) { /** CAMERA **/ + selectedImage = Uri.fromFile(imageFile); + } else { /** ALBUM **/ + selectedImage = imageReturnedIntent.getData(); + } + Log.d(TAG, "selectedImage: " + selectedImage); + + bm = getImageResized(context, selectedImage); + int rotation = getRotation(context, selectedImage, isCamera); + bm = rotate(bm, rotation); + } + return bm; + } + + + private static File getTempFile(Context context) { + File imageFile = new File(context.getExternalCacheDir(), TEMP_IMAGE_NAME); + imageFile.getParentFile().mkdirs(); + return imageFile; + } + + private static Bitmap decodeBitmap(Context context, Uri theUri, int sampleSize) { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inSampleSize = sampleSize; + + AssetFileDescriptor fileDescriptor = null; + try { + fileDescriptor = context.getContentResolver().openAssetFileDescriptor(theUri, "r"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + Bitmap actuallyUsableBitmap = BitmapFactory.decodeFileDescriptor( + fileDescriptor.getFileDescriptor(), null, options); + + Log.d(TAG, options.inSampleSize + " sample method bitmap ... " + + actuallyUsableBitmap.getWidth() + " " + actuallyUsableBitmap.getHeight()); + + return actuallyUsableBitmap; + } + + /** + * Resize to avoid using too much memory loading big images (e.g.: 2560*1920) + **/ + private static Bitmap getImageResized(Context context, Uri selectedImage) { + Bitmap bm = null; + int[] sampleSizes = new int[]{5, 3, 2, 1}; + int i = 0; + do { + bm = decodeBitmap(context, selectedImage, sampleSizes[i]); + Log.d(TAG, "resizer: new bitmap width = " + bm.getWidth()); + i++; + } while (bm.getWidth() < minWidthQuality && i < sampleSizes.length); + return bm; + } + + + private static int getRotation(Context context, Uri imageUri, boolean isCamera) { + int rotation; + if (isCamera) { + rotation = getRotationFromCamera(context, imageUri); + } else { + rotation = getRotationFromGallery(context, imageUri); + } + Log.d(TAG, "Image rotation: " + rotation); + return rotation; + } + + private static int getRotationFromCamera(Context context, Uri imageFile) { + int rotate = 0; + try { + + context.getContentResolver().notifyChange(imageFile, null); + ExifInterface exif = new ExifInterface(imageFile.getPath()); + int orientation = exif.getAttributeInt( + ExifInterface.TAG_ORIENTATION, + ExifInterface.ORIENTATION_NORMAL); + + switch (orientation) { + case ExifInterface.ORIENTATION_ROTATE_270: + rotate = 270; + break; + case ExifInterface.ORIENTATION_ROTATE_180: + rotate = 180; + break; + case ExifInterface.ORIENTATION_ROTATE_90: + rotate = 90; + break; + } + } catch (Exception e) { + e.printStackTrace(); + } + return rotate; + } + + public static int getRotationFromGallery(Context context, Uri imageUri) { + int result = 0; + String[] columns = {MediaStore.Images.Media.ORIENTATION}; + Cursor cursor = null; + try { + cursor = context.getContentResolver().query(imageUri, columns, null, null, null); + if (cursor != null && cursor.moveToFirst()) { + int orientationColumnIndex = cursor.getColumnIndex(columns[0]); + result = cursor.getInt(orientationColumnIndex); + } + } catch (Exception e) { + //Do nothing + } finally { + if (cursor != null) { + cursor.close(); + } + }//End of try-catch block + return result; + } + + + private static Bitmap rotate(Bitmap bm, int rotation) { + if (rotation != 0) { + Matrix matrix = new Matrix(); + matrix.postRotate(rotation); + Bitmap bmOut = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); + return bmOut; + } + return bm; + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java index c5f0b05e..0163668b 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java +++ b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java @@ -21,15 +21,16 @@ import android.content.SharedPreferences.Editor; import android.content.res.TypedArray; import android.preference.PreferenceManager; +import androidx.annotation.LayoutRes; +import androidx.annotation.NonNull; +import androidx.annotation.StyleRes; +import androidx.viewpager.widget.ViewPager; + import com.google.android.material.bottomnavigation.LabelVisibilityMode; import java.io.File; import java.util.Objects; -import androidx.annotation.LayoutRes; -import androidx.annotation.NonNull; -import androidx.annotation.StyleRes; -import androidx.viewpager.widget.ViewPager; import code.name.monkey.retromusic.App; import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.helper.SortOrder; @@ -38,8 +39,8 @@ import code.name.monkey.retromusic.transform.DepthTransformation; import code.name.monkey.retromusic.transform.HingeTransformation; import code.name.monkey.retromusic.transform.HorizontalFlipTransformation; import code.name.monkey.retromusic.transform.NormalPageTransformer; -import code.name.monkey.retromusic.transform.VerticalStackTransformer; import code.name.monkey.retromusic.transform.VerticalFlipTransformation; +import code.name.monkey.retromusic.transform.VerticalStackTransformer; import code.name.monkey.retromusic.ui.activities.MainActivity; import code.name.monkey.retromusic.ui.fragments.AlbumCoverStyle; import code.name.monkey.retromusic.ui.fragments.NowPlayingScreen; @@ -61,6 +62,7 @@ public final class PreferenceUtil { public static final String GENERAL_THEME = "general_theme"; public static final String CIRCULAR_ALBUM_ART = "circular_album_art"; public static final String USER_NAME = "user_name"; + public static final String USER_BIO = "user_bio"; public static final String TOGGLE_FULL_SCREEN = "toggle_full_screen"; public static final String TOGGLE_VOLUME = "toggle_volume"; public static final String TOGGLE_TAB_TITLES = "toggle_tab_titles"; @@ -154,6 +156,14 @@ public final class PreferenceUtil { } } + public String getUserBio() { + return mPreferences.getString(USER_BIO, ""); + } + + public void setUserBio(String bio) { + mPreferences.edit().putString(USER_BIO, bio).apply(); + } + public int getFilterLength() { return mPreferences.getInt(FILTER_SONG, 20); } diff --git a/app/src/main/java/code/name/monkey/retromusic/views/CollapsingFAB.java b/app/src/main/java/code/name/monkey/retromusic/views/CollapsingFAB.java deleted file mode 100644 index a78596e9..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/views/CollapsingFAB.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2019 Hemanth Savarala. - * - * Licensed under the GNU General Public License v3 - * - * This is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by - * the Free Software Foundation either version 3 of the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - */ - -package code.name.monkey.retromusic.views; - -import android.content.Context; -import android.content.res.ColorStateList; -import android.content.res.TypedArray; -import android.graphics.Color; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.View; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.TextView; - -import com.google.android.material.card.MaterialCardView; - -import androidx.annotation.ColorInt; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.transition.AutoTransition; -import androidx.transition.TransitionManager; -import code.name.monkey.appthemehelper.util.ColorUtil; -import code.name.monkey.appthemehelper.util.MaterialValueHelper; -import code.name.monkey.retromusic.R; - -public class CollapsingFAB extends FrameLayout { - @ColorInt - int color = Color.WHITE; - - String title; - Drawable icon; - - boolean showTitle; - - ImageView shuffleIcon; - TextView textView; - MaterialCardView cardView; - - public CollapsingFAB(@NonNull Context context) { - this(context, null); - } - - public CollapsingFAB(@NonNull Context context, @Nullable AttributeSet attrs) { - this(context, attrs, 0); - } - - public CollapsingFAB(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - TypedArray attributes = getContext().obtainStyledAttributes(attrs, R.styleable.CollapsingFAB, 0, 0); - icon = attributes.getDrawable(R.styleable.CollapsingFAB_setIcon); - color = attributes.getColor(R.styleable.CollapsingFAB_shuffleBackgroundColor, 0); - showTitle = attributes.getBoolean(R.styleable.CollapsingFAB_showTitle, false); - title = attributes.getString(R.styleable.CollapsingFAB_setText); - - View view = inflate(context, R.layout.collapsing_floating_action_button, this); - shuffleIcon = view.findViewById(R.id.icon); - shuffleIcon.setImageDrawable(icon); - - textView = view.findViewById(R.id.shuffle_text); - textView.setText(title); - textView.setVisibility(showTitle ? VISIBLE : GONE); - cardView = view.findViewById(R.id.container); - attributes.recycle(); - } - - public void setShowTitle(boolean showTitle) { - this.showTitle = showTitle; - TransitionManager.beginDelayedTransition(this, new AutoTransition()); - textView.setVisibility(showTitle ? VISIBLE : GONE); - invalidate(); - requestLayout(); - } - - public void setColor(int color) { - this.color = color; - int textColor = MaterialValueHelper.INSTANCE.getPrimaryTextColor(getContext(), ColorUtil.INSTANCE.isColorLight(color)); - shuffleIcon.setColorFilter(textColor); - textView.setTextColor(textColor); - cardView.setCardBackgroundColor(ColorStateList.valueOf(color)); - postInvalidate(); - } -} diff --git a/app/src/main/java/code/name/monkey/retromusic/views/LollipopFixedWebView.java b/app/src/main/java/code/name/monkey/retromusic/views/LollipopFixedWebView.java new file mode 100644 index 00000000..b599977f --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/views/LollipopFixedWebView.java @@ -0,0 +1,49 @@ +/* + * 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.annotation.TargetApi; +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.util.AttributeSet; +import android.webkit.WebView; + +public class LollipopFixedWebView extends WebView { + public LollipopFixedWebView(Context context) { + super(getFixedContext(context)); + } + + public LollipopFixedWebView(Context context, AttributeSet attrs) { + super(getFixedContext(context), attrs); + } + + public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr) { + super(getFixedContext(context), attrs, defStyleAttr); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(getFixedContext(context), attrs, defStyleAttr, defStyleRes); + } + + public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, boolean privateBrowsing) { + super(getFixedContext(context), attrs, defStyleAttr, privateBrowsing); + } + + public static Context getFixedContext(Context context) { + return context.createConfigurationContext(new Configuration()); + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/views/NetworkImageView.java b/app/src/main/java/code/name/monkey/retromusic/views/NetworkImageView.java index 1266fa76..1e7c137e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/views/NetworkImageView.java +++ b/app/src/main/java/code/name/monkey/retromusic/views/NetworkImageView.java @@ -18,6 +18,9 @@ import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.glide.GlideApp; @@ -26,26 +29,26 @@ import code.name.monkey.retromusic.glide.GlideApp; */ public class NetworkImageView extends CircularImageView { - public NetworkImageView(Context context) { + public NetworkImageView(@NonNull Context context) { super(context); init(context, null); } - public NetworkImageView(Context context, AttributeSet attrs) { + public NetworkImageView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(context, attrs); } - public NetworkImageView(Context context, AttributeSet attrs, int defStyleAttr) { + public NetworkImageView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs); } - public void setImageUrl(String imageUrl) { + public void setImageUrl(@NonNull String imageUrl) { setImageUrl(getContext(), imageUrl); } - public void setImageUrl(Context context, String imageUrl) { + public void setImageUrl(@NonNull Context context, @NonNull String imageUrl) { GlideApp.with(context) .load(imageUrl) .error(R.drawable.ic_person_flat) diff --git a/app/src/main/java/code/name/monkey/retromusic/views/OptionMenuItemView.java b/app/src/main/java/code/name/monkey/retromusic/views/OptionMenuItemView.java new file mode 100644 index 00000000..3051585f --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/views/OptionMenuItemView.java @@ -0,0 +1,70 @@ +/* + * 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.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.widget.FrameLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +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; + +/** + * Created by hemanths on 3/23/19 + */ +public class OptionMenuItemView extends FrameLayout { + + public OptionMenuItemView(@NonNull Context context) { + this(context, null); + } + + public OptionMenuItemView(@NonNull Context context, @Nullable AttributeSet attrs) { + this(context, attrs, -1); + } + + public OptionMenuItemView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + this(context, attrs, defStyleAttr, -1); + } + + public OptionMenuItemView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + inflate(context, R.layout.item_option_menu, this); + + setBackgroundTintList(ColorStateList.valueOf(ThemeStore.Companion.accentColor(context))); + + TextView textView = findViewById(R.id.title); + textView.setTextColor(MaterialValueHelper.INSTANCE.getPrimaryTextColor(context, ColorUtil.INSTANCE.isColorLight(ThemeStore.Companion.primaryColor(context)))); + IconImageView iconImageView = findViewById(R.id.icon); + + TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.OptionMenuItemView, 0, 0); + + String title = attributes.getString(R.styleable.OptionMenuItemView_optionTitle); + textView.setText(title); + + Drawable icon = attributes.getDrawable(R.styleable.OptionMenuItemView_optionIcon); + iconImageView.setImageDrawable(icon); + + attributes.recycle(); + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_fab.xml b/app/src/main/res/drawable/bg_fab.xml new file mode 100644 index 00000000..43331b4e --- /dev/null +++ b/app/src/main/res/drawable/bg_fab.xml @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_delete_white_24dp.xml b/app/src/main/res/drawable/ic_delete_white_24dp.xml index 600e1ea3..16ab5789 100644 --- a/app/src/main/res/drawable/ic_delete_white_24dp.xml +++ b/app/src/main/res/drawable/ic_delete_white_24dp.xml @@ -4,9 +4,7 @@ android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> - - + android:pathData="M9,3V4H4V6H5V19A2,2 0 0,0 7,21H17A2,2 0 0,0 19,19V6H20V4H15V3H9M7,6H17V19H7V6M9,8V17H11V8H9M13,8V17H15V8H13Z" /> \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_grid_size_white_24dp.xml b/app/src/main/res/drawable/ic_grid_size_white_24dp.xml new file mode 100644 index 00000000..5fc1dad3 --- /dev/null +++ b/app/src/main/res/drawable/ic_grid_size_white_24dp.xml @@ -0,0 +1,23 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-land/activity_album.xml b/app/src/main/res/layout-land/activity_album.xml index 5f71e8be..2c5219c3 100644 --- a/app/src/main/res/layout-land/activity_album.xml +++ b/app/src/main/res/layout-land/activity_album.xml @@ -98,16 +98,15 @@ - + android:layout_gravity="bottom|end" + android:layout_margin="16dp" + android:text="@string/action_shuffle_all" + app:icon="@drawable/ic_clear_all_black_24dp" /> diff --git a/app/src/main/res/layout-land/activity_album_tag_editor.xml b/app/src/main/res/layout-land/activity_album_tag_editor.xml index 406af10b..1cf47696 100644 --- a/app/src/main/res/layout-land/activity_album_tag_editor.xml +++ b/app/src/main/res/layout-land/activity_album_tag_editor.xml @@ -23,7 +23,6 @@ app:navigationIcon="@drawable/ic_keyboard_backspace_black_24dp" tools:ignore="UnusedAttribute"> - - + android:layout_height="match_parent"> - + + android:padding="16dp"> + android:maxLines="1" /> + android:maxLines="1" /> + android:maxLines="1" /> + android:maxLines="1" /> @@ -191,13 +151,14 @@ - + android:layout_margin="16dp" + android:gravity="center" + android:text="@string/save" + app:icon="@drawable/ic_save_white_24dp" + app:iconGravity="textStart" /> diff --git a/app/src/main/res/layout-land/activity_artist_details.xml b/app/src/main/res/layout-land/activity_artist_details.xml index ed5b6104..b755d210 100644 --- a/app/src/main/res/layout-land/activity_artist_details.xml +++ b/app/src/main/res/layout-land/activity_artist_details.xml @@ -96,15 +96,12 @@ android:layout_width="match_parent" android:layout_height="72dp" android:background="@drawable/shadow_down_strong" /> - - + android:layout_gravity="bottom|end" + android:layout_margin="16dp" + android:text="@string/action_shuffle_all" + app:icon="@drawable/ic_clear_all_black_24dp" /> diff --git a/app/src/main/res/layout-xlarge-land/activity_album.xml b/app/src/main/res/layout-xlarge-land/activity_album.xml index 2d57c747..7e9b8d2c 100644 --- a/app/src/main/res/layout-xlarge-land/activity_album.xml +++ b/app/src/main/res/layout-xlarge-land/activity_album.xml @@ -123,16 +123,14 @@ - + android:layout_gravity="bottom|end" + android:layout_margin="16dp" + android:text="@string/action_shuffle_all" + app:icon="@drawable/ic_clear_all_black_24dp" /> - + android:layout_gravity="bottom|end" + android:layout_margin="16dp" + android:text="@string/action_shuffle_all" + app:icon="@drawable/ic_clear_all_black_24dp" /> + diff --git a/app/src/main/res/layout-xlarge/activity_album.xml b/app/src/main/res/layout-xlarge/activity_album.xml index d8d9a7bd..ded7bf56 100644 --- a/app/src/main/res/layout-xlarge/activity_album.xml +++ b/app/src/main/res/layout-xlarge/activity_album.xml @@ -130,15 +130,13 @@ android:layout_height="72dp" android:background="@drawable/shadow_down_strong" /> - - + android:layout_gravity="bottom|end" + android:layout_margin="16dp" + android:text="@string/action_shuffle_all" + app:icon="@drawable/ic_clear_all_black_24dp" /> \ No newline at end of file diff --git a/app/src/main/res/layout-xlarge/activity_artist_details.xml b/app/src/main/res/layout-xlarge/activity_artist_details.xml index 5e03afe4..21db36f3 100644 --- a/app/src/main/res/layout-xlarge/activity_artist_details.xml +++ b/app/src/main/res/layout-xlarge/activity_artist_details.xml @@ -97,14 +97,12 @@ - + android:layout_gravity="bottom|end" + android:layout_margin="16dp" + android:text="@string/action_shuffle_all" + app:icon="@drawable/ic_clear_all_black_24dp" /> diff --git a/app/src/main/res/layout-xlarge/activity_user_info.xml b/app/src/main/res/layout-xlarge/activity_user_info.xml index cead85a4..d0068684 100644 --- a/app/src/main/res/layout-xlarge/activity_user_info.xml +++ b/app/src/main/res/layout-xlarge/activity_user_info.xml @@ -26,10 +26,10 @@ @@ -100,21 +100,18 @@ + + + + + + + + diff --git a/app/src/main/res/layout/abs_playlists.xml b/app/src/main/res/layout/abs_playlists.xml index 8e64d5d6..82a7967a 100644 --- a/app/src/main/res/layout/abs_playlists.xml +++ b/app/src/main/res/layout/abs_playlists.xml @@ -3,6 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" + android:paddingBottom="12dp" android:orientation="vertical"> - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_album.xml b/app/src/main/res/layout/activity_album.xml index 78b5fe79..4699a975 100755 --- a/app/src/main/res/layout/activity_album.xml +++ b/app/src/main/res/layout/activity_album.xml @@ -114,16 +114,12 @@ - - - + android:layout_gravity="bottom|end" + android:layout_margin="16dp" + android:text="@string/action_shuffle_all" + app:icon="@drawable/ic_clear_all_black_24dp" /> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_album_tag_editor.xml b/app/src/main/res/layout/activity_album_tag_editor.xml index af296371..a4b29837 100755 --- a/app/src/main/res/layout/activity_album_tag_editor.xml +++ b/app/src/main/res/layout/activity_album_tag_editor.xml @@ -42,6 +42,10 @@ android:layout_gravity="center" android:visibility="gone" /> + + android:padding="16dp"> + android:maxLines="1" /> + android:maxLines="1" /> + android:maxLines="1" /> + android:maxLines="1" /> - - + android:layout_gravity="bottom" + android:layout_margin="16dp" + android:gravity="center" + android:text="@string/save" + app:icon="@drawable/ic_save_white_24dp" + app:iconGravity="textStart" /> diff --git a/app/src/main/res/layout/activity_artist_details.xml b/app/src/main/res/layout/activity_artist_details.xml index 209b10f1..4f92c807 100755 --- a/app/src/main/res/layout/activity_artist_details.xml +++ b/app/src/main/res/layout/activity_artist_details.xml @@ -98,14 +98,13 @@ - + android:layout_gravity="bottom|end" + android:layout_margin="16dp" + android:text="@string/action_shuffle_all" + app:icon="@drawable/ic_clear_all_black_24dp" /> + diff --git a/app/src/main/res/layout/activity_playing_queue.xml b/app/src/main/res/layout/activity_playing_queue.xml index a9ebcc62..4ccb56c9 100755 --- a/app/src/main/res/layout/activity_playing_queue.xml +++ b/app/src/main/res/layout/activity_playing_queue.xml @@ -68,14 +68,14 @@ android:textColor="?android:textColorSecondary" android:visibility="gone" /> - + android:layout_margin="16dp" + android:text="@string/clear_playing_queue" + app:icon="@drawable/ic_clear_all_black_24dp" /> + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_playlist_detail.xml b/app/src/main/res/layout/activity_playlist_detail.xml index 8b8d02bf..83731e30 100644 --- a/app/src/main/res/layout/activity_playlist_detail.xml +++ b/app/src/main/res/layout/activity_playlist_detail.xml @@ -91,14 +91,13 @@ tools:visibility="visible" /> - - + android:layout_margin="16dp" + android:text="@string/action_shuffle_all" + app:icon="@drawable/ic_clear_all_black_24dp" /> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_song_tag_editor.xml b/app/src/main/res/layout/activity_song_tag_editor.xml index d94e2248..1e2437b3 100755 --- a/app/src/main/res/layout/activity_song_tag_editor.xml +++ b/app/src/main/res/layout/activity_song_tag_editor.xml @@ -72,25 +72,16 @@ android:layout_width="match_parent" android:layout_height="wrap_content" app:boxBackgroundMode="outline" - app:boxCollapsedPaddingTop="16dp" - app:boxCornerRadiusBottomEnd="8dp" - app:boxCornerRadiusBottomStart="8dp" - app:boxCornerRadiusTopEnd="8dp" - - app:boxCornerRadiusTopStart="8dp" - app:boxStrokeColor="?android:attr/textColorPrimary" - app:boxStrokeWidth="1dp" app:hintEnabled="true"> + tools:text="@string/song" /> + android:maxLines="1" /> + android:maxLines="1" /> @@ -169,23 +138,16 @@ android:gravity="center_vertical" android:hint="@string/album_artist" android:inputType="text|textCapWords" - android:maxLines="1" - android:padding="16dp" /> + android:maxLines="1" /> + android:maxLines="1" /> @@ -208,18 +169,12 @@ android:orientation="horizontal"> @@ -228,29 +183,21 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" - android:fontFamily="sans-serif" android:gravity="center_vertical" android:hint="@string/genre" - android:maxLines="1" - android:padding="16dp" /> + android:maxLines="1" /> @@ -259,28 +206,20 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" - android:fontFamily="sans-serif" android:gravity="center_vertical" android:hint="@string/year" android:inputType="text|number" - android:maxLines="1" - android:padding="16dp" /> + android:maxLines="1" /> @@ -292,24 +231,16 @@ android:gravity="center_vertical" android:hint="@string/track_hint" android:inputType="text|number" - android:maxLines="1" - android:padding="16dp" /> + android:maxLines="1" /> @@ -320,8 +251,7 @@ android:layout_gravity="center" android:gravity="center_vertical" android:hint="@string/lyrics" - android:inputType="textMultiLine" - android:padding="16dp" /> + android:inputType="textMultiLine" /> @@ -330,15 +260,16 @@ - + android:layout_gravity="bottom" + android:layout_margin="16dp" + android:gravity="center" + android:text="@string/save" + app:icon="@drawable/ic_save_white_24dp" + app:iconGravity="textStart" /> + + + + + + + diff --git a/app/src/main/res/layout/activity_whats_new.xml b/app/src/main/res/layout/activity_whats_new.xml index 56825cba..a263b2dc 100644 --- a/app/src/main/res/layout/activity_whats_new.xml +++ b/app/src/main/res/layout/activity_whats_new.xml @@ -28,7 +28,7 @@ - - + android:layout_height="wrap_content" + app:cardCornerRadius="8dp" + app:cardPreventCornerOverlap="false" + app:cardUseCompatPadding="true"> - - - - + android:layout_height="match_parent" + android:orientation="vertical"> - - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/card_other.xml b/app/src/main/res/layout/card_other.xml index 6950cef0..db8a1d19 100644 --- a/app/src/main/res/layout/card_other.xml +++ b/app/src/main/res/layout/card_other.xml @@ -1,20 +1,21 @@ - - - - + android:layout_height="wrap_content" + app:cardCornerRadius="8dp" + app:cardPreventCornerOverlap="false" + app:cardUseCompatPadding="true"> + android:layout_height="match_parent" + android:orientation="vertical"> + + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/card_retro_info.xml b/app/src/main/res/layout/card_retro_info.xml index 2aba0468..2a4d34a5 100644 --- a/app/src/main/res/layout/card_retro_info.xml +++ b/app/src/main/res/layout/card_retro_info.xml @@ -1,20 +1,21 @@ - - - + android:layout_height="wrap_content" + app:cardCornerRadius="8dp" + app:cardPreventCornerOverlap="false" + app:cardUseCompatPadding="true"> + - - \ No newline at end of file + + \ No newline at end of file diff --git a/app/src/main/res/layout/card_social.xml b/app/src/main/res/layout/card_social.xml index e535b1f1..fab0cf9b 100644 --- a/app/src/main/res/layout/card_social.xml +++ b/app/src/main/res/layout/card_social.xml @@ -1,20 +1,21 @@ - - - + android:layout_height="wrap_content" + app:cardCornerRadius="8dp" + app:cardPreventCornerOverlap="false" + app:cardUseCompatPadding="true"> + + android:text="@string/pinterest_page" /> @@ -88,16 +89,16 @@ + android:text="@string/instagram_page" /> @@ -130,16 +131,16 @@ android:paddingBottom="8dp"> + android:text="@string/twitter_page" /> @@ -172,15 +173,15 @@ android:paddingBottom="8dp"> + android:text="@string/discord_page" /> @@ -214,15 +215,15 @@ android:paddingBottom="8dp"> + android:text="@string/telegram_group" /> @@ -258,19 +259,18 @@ + android:text="@string/google_plus" /> - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/collapsing_floating_action_button.xml b/app/src/main/res/layout/collapsing_floating_action_button.xml index c29a7938..f86a77bb 100644 --- a/app/src/main/res/layout/collapsing_floating_action_button.xml +++ b/app/src/main/res/layout/collapsing_floating_action_button.xml @@ -4,8 +4,8 @@ xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="wrap_content" - android:layout_gravity="center" android:layout_height="wrap_content" + android:layout_gravity="center" app:cardCornerRadius="26dp" app:cardUseCompatPadding="true" tools:backgroundTint="@color/md_red_400"> @@ -26,6 +26,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fab_extended.xml b/app/src/main/res/layout/fab_extended.xml new file mode 100644 index 00000000..29a841a8 --- /dev/null +++ b/app/src/main/res/layout/fab_extended.xml @@ -0,0 +1,33 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_banner_home.xml b/app/src/main/res/layout/fragment_banner_home.xml index 8378ba66..6c28536e 100644 --- a/app/src/main/res/layout/fragment_banner_home.xml +++ b/app/src/main/res/layout/fragment_banner_home.xml @@ -108,6 +108,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:nestedScrollingEnabled="false" /> + diff --git a/app/src/main/res/layout/fragment_full.xml b/app/src/main/res/layout/fragment_full.xml index e55b8da7..f2b0ec48 100644 --- a/app/src/main/res/layout/fragment_full.xml +++ b/app/src/main/res/layout/fragment_full.xml @@ -114,5 +114,42 @@ app:srcCompat="@drawable/default_artist_art" /> + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_library.xml b/app/src/main/res/layout/fragment_library.xml index d867e4a8..52fb70d5 100644 --- a/app/src/main/res/layout/fragment_library.xml +++ b/app/src/main/res/layout/fragment_library.xml @@ -34,19 +34,18 @@ android:layout_height="wrap_content" app:layout_scrollFlags="scroll|enterAlways"> - + - + - + + + + android:orientation="horizontal"> @@ -36,7 +34,9 @@ - + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?rectSelector" + android:clickable="true" + android:focusable="true" + app:optionIcon="@drawable/ic_folder_white_24dp" + app:optionTitle="@string/folders" /> - + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?rectSelector" + android:clickable="true" + android:focusable="true" + app:optionIcon="@drawable/ic_equalizer_white_24dp" + app:optionTitle="@string/equalizer" /> - + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?rectSelector" + android:clickable="true" + android:focusable="true" + app:optionIcon="@drawable/ic_timer_white_24dp" + app:optionTitle="@string/action_sleep_timer" /> - + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?rectSelector" + android:clickable="true" + android:focusable="true" + app:optionIcon="@drawable/ic_share_white_24dp" + app:optionTitle="@string/action_share" /> - + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?rectSelector" + android:clickable="true" + android:focusable="true" + app:optionIcon="@drawable/ic_bug_report_white_24dp" + app:optionTitle="@string/report_bug" /> - + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?rectSelector" + android:clickable="true" + android:focusable="true" + app:optionIcon="@drawable/ic_help_white_24dp" + app:optionTitle="@string/action_about" /> - - - + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?rectSelector" + android:clickable="true" + android:focusable="true" + app:optionIcon="@drawable/ic_star_white_24dp" + app:optionTitle="@string/rate_app" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_material_playback_controls.xml b/app/src/main/res/layout/fragment_material_playback_controls.xml index 89e68194..28327c22 100644 --- a/app/src/main/res/layout/fragment_material_playback_controls.xml +++ b/app/src/main/res/layout/fragment_material_playback_controls.xml @@ -12,8 +12,6 @@ diff --git a/app/src/main/res/layout/fragment_plain_controls_fragment.xml b/app/src/main/res/layout/fragment_plain_controls_fragment.xml index 3865e23f..20f2af22 100644 --- a/app/src/main/res/layout/fragment_plain_controls_fragment.xml +++ b/app/src/main/res/layout/fragment_plain_controls_fragment.xml @@ -9,8 +9,6 @@ diff --git a/app/src/main/res/layout/fragment_plain_player.xml b/app/src/main/res/layout/fragment_plain_player.xml index 6f892235..9f8ad71c 100644 --- a/app/src/main/res/layout/fragment_plain_player.xml +++ b/app/src/main/res/layout/fragment_plain_player.xml @@ -86,7 +86,7 @@ - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_player_playback_controls.xml b/app/src/main/res/layout/fragment_player_playback_controls.xml index cd8cca83..b9e9c22d 100755 --- a/app/src/main/res/layout/fragment_player_playback_controls.xml +++ b/app/src/main/res/layout/fragment_player_playback_controls.xml @@ -9,10 +9,10 @@ tools:ignore="MissingPrefix"> + android:layout_height="28dp" + android:paddingStart="12dp" + android:paddingEnd="12dp"> + android:orientation="vertical"> - + app:civ_shadow="false" + app:srcCompat="@drawable/ic_person_flat" /> + android:layout_height="wrap_content" /> diff --git a/app/src/main/res/layout/item_option_menu.xml b/app/src/main/res/layout/item_option_menu.xml new file mode 100644 index 00000000..60a8286d --- /dev/null +++ b/app/src/main/res/layout/item_option_menu.xml @@ -0,0 +1,42 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/metal_section_recycler_view.xml b/app/src/main/res/layout/metal_section_recycler_view.xml index b74be8c6..9015aec3 100644 --- a/app/src/main/res/layout/metal_section_recycler_view.xml +++ b/app/src/main/res/layout/metal_section_recycler_view.xml @@ -3,7 +3,8 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical"> + android:orientation="vertical" + android:paddingBottom="12dp"> - - \ No newline at end of file diff --git a/app/src/main/res/layout/section_recycler_view.xml b/app/src/main/res/layout/section_recycler_view.xml index 9cdb344c..0f55d0c5 100644 --- a/app/src/main/res/layout/section_recycler_view.xml +++ b/app/src/main/res/layout/section_recycler_view.xml @@ -40,9 +40,4 @@ android:layout_height="wrap_content" android:nestedScrollingEnabled="false" /> - \ No newline at end of file diff --git a/app/src/main/res/layout/sliding_music_panel_layout.xml b/app/src/main/res/layout/sliding_music_panel_layout.xml index b4e0852c..c4fc58f7 100644 --- a/app/src/main/res/layout/sliding_music_panel_layout.xml +++ b/app/src/main/res/layout/sliding_music_panel_layout.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index cb9fa8a4..36b7b4ff 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -3,15 +3,11 @@ xmlns:tools="http://schemas.android.com/tools" tools:context=".DrawerActivity"> - - + android:icon="@drawable/ic_grid_size_white_24dp" + android:title="@string/action_grid_size" + app:showAsAction="ifRoom"> + android:icon="@drawable/ic_sort_white_24dp" + android:title="@string/action_sort_order" + app:showAsAction="ifRoom"> - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 7590d379..9e80d635 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -1,11 +1,6 @@ - - - - - - + @@ -58,4 +53,9 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 0fbc1ce7..e7bde8cd 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -59,5 +59,6 @@ http://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout 0dp 0dp 104dp - 28dp + 30dp + 56dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9bfcfe68..b4327aa9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -603,5 +603,8 @@ Next Song Last song Slide + Save + Pick image + Set a profile photo diff --git a/appthemehelper/build.gradle b/appthemehelper/build.gradle index bb2dc6a7..7276da13 100644 --- a/appthemehelper/build.gradle +++ b/appthemehelper/build.gradle @@ -28,9 +28,9 @@ android { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation 'androidx.appcompat:appcompat:1.0.2' - implementation 'com.google.android.material:material:1.0.0' - implementation 'androidx.preference:preference:1.0.0' + implementation 'androidx.appcompat:appcompat:1.1.0-alpha03' + implementation 'com.google.android.material:material:1.1.0-alpha04' + implementation 'androidx.preference:preference:1.1.0-alpha04' implementation 'androidx.cardview:cardview:1.0.0' // Used for the list preference classes implementation "com.afollestad.material-dialogs:core:$materialDialog" diff --git a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/views/ATEAccentTextView.kt b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/views/ATEAccentTextView.kt new file mode 100644 index 00000000..c15d4fb5 --- /dev/null +++ b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/views/ATEAccentTextView.kt @@ -0,0 +1,39 @@ +/* + * 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.appthemehelper.common.views + +import android.content.Context +import android.util.AttributeSet + +import androidx.appcompat.widget.AppCompatTextView +import code.name.monkey.appthemehelper.ThemeStore + +class ATEAccentTextView : AppCompatTextView { + constructor(context: Context) : super(context) { + init(context, null) + } + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { + init(context, attrs) + } + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { + init(context, attrs) + } + + private fun init(context: Context, attrs: AttributeSet?) { + setTextColor(ThemeStore.accentColor(context)) + } +} diff --git a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/views/ATEExtendedFloatingActionButton.kt b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/views/ATEExtendedFloatingActionButton.kt new file mode 100644 index 00000000..60766d23 --- /dev/null +++ b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/views/ATEExtendedFloatingActionButton.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.appthemehelper.common.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.ColorUtil +import code.name.monkey.appthemehelper.util.MaterialValueHelper +import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton + +class ATEExtendedFloatingActionButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = -1) : ExtendedFloatingActionButton(context, attrs, defStyleAttr) { + + init { + backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(context)) + setTextColor(ColorStateList.valueOf(MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(ThemeStore.accentColor(context))))) + } + +} diff --git a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/views/ATETextInputLayout.java b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/views/ATETextInputLayout.java index 278050a3..c1040c70 100644 --- a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/views/ATETextInputLayout.java +++ b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/common/views/ATETextInputLayout.java @@ -18,10 +18,11 @@ import android.content.Context; import android.content.res.ColorStateList; import android.util.AttributeSet; -import com.google.android.material.textfield.TextInputLayout; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; + +import com.google.android.material.textfield.TextInputLayout; + import code.name.monkey.appthemehelper.ThemeStore; /** @@ -38,14 +39,9 @@ public class ATETextInputLayout extends TextInputLayout { public ATETextInputLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - - setBoxBackgroundMode(BOX_BACKGROUND_OUTLINE); - setBoxStrokeColor(ThemeStore.Companion.textColorSecondary(context)); - final float scale = context.getResources().getDisplayMetrics().density; - int border = (int) (8 * scale + 0.5f); - setBoxCornerRadii(border, border, border, border); + setBoxBackgroundMode(BOX_BACKGROUND_FILLED); setHintAnimationEnabled(true); setHintEnabled(true); - + setBackgroundTintList(ColorStateList.valueOf(ThemeStore.Companion.accentColor(context))); } } diff --git a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/util/MaterialUtil.kt b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/util/MaterialUtil.kt index 1ab73ddd..d613029e 100644 --- a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/util/MaterialUtil.kt +++ b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/util/MaterialUtil.kt @@ -1,6 +1,11 @@ package code.name.monkey.appthemehelper.util import android.content.res.ColorStateList +import android.graphics.PorterDuff +import android.widget.EditText +import android.widget.TextView +import androidx.annotation.ColorInt +import androidx.core.content.ContextCompat import code.name.monkey.appthemehelper.ThemeStore import com.google.android.material.button.MaterialButton import com.google.android.material.textfield.TextInputLayout @@ -28,7 +33,7 @@ object MaterialUtil { } - fun setTint(textInputLayout: TextInputLayout, background: Boolean) { + fun setTint(textInputLayout: TextInputLayout, background: Boolean = true) { val context = textInputLayout.context val accentColor = ThemeStore.accentColor(context) val colorState = ColorStateList.valueOf(accentColor) @@ -39,6 +44,32 @@ object MaterialUtil { } else { textInputLayout.boxStrokeColor = accentColor textInputLayout.defaultHintTextColor = colorState + textInputLayout.isHintAnimationEnabled = true + } + } + + private fun setCursorPointerColor(view: EditText, @ColorInt color: Int) { + try { + //get the pointer resource id + var field = TextView::class.java.getDeclaredField("mTextSelectHandleRes") + field.isAccessible = true + val drawableResId = field.getInt(view) + + //get the editor + field = TextView::class.java.getDeclaredField("mEditor") + field.isAccessible = true + val editor = field.get(view) + + //tint drawable + val drawable = ContextCompat.getDrawable(view.context, drawableResId)!! + drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN) + + //set the drawable + field = editor.javaClass.getDeclaredField("mSelectHandleCenter") + field.isAccessible = true + field.set(editor, drawable) + + } catch (ex: Exception) { } } } diff --git a/build.gradle b/build.gradle index 81e93102..3fbfbf2c 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ buildscript { ext.kotlin_version = '1.3.21' ext { - supportLibVersion = '1.0.0' + supportLibVersion = '1.1.0-alpha05' firebase = "11.8.0" retrofit = "2.3.0" materialDialog = "2.0.0"