;
+}
-#-dontwarn
-#-ignorewarnings
+-keep class !android.support.v7.internal.view.menu.**,** {*;}
-#Jaudiotagger
--dontwarn org.jaudiotagger.**
--dontwarn org.jcodec.**
--keep class org.jaudiotagger.** { *; }
--keep class org.jcodec.** { *; }
+-dontwarn
+-ignorewarnings
--keepclassmembers enum * { *; }
--keepattributes *Annotation*, Signature, Exception
--keepnames class androidx.navigation.fragment.NavHostFragment
--keep class * extends androidx.fragment.app.Fragment{}
--keepnames class * extends android.os.Parcelable
--keepnames class * extends java.io.Serializable
--keep class code.name.monkey.retromusic.network.model.** { *; }
--keep class code.name.monkey.retromusic.model.** { *; }
--keep class com.google.android.material.bottomsheet.** { *; }
\ No newline at end of file
+# ------- FastScrollRecycleView START -------
+-keep class com.simplecityapps.recyclerview_fastscroll.views.FastScrollPopup { *; }
+# ------- FastScrollRecycleView END -------
+
+-keep public class android.support.design.widget.BottomNavigationView { *; }
+-keep public class android.support.design.internal.BottomNavigationMenuView { *; }
+-keep public class android.support.design.internal.BottomNavigationPresenter { *; }
+-keep public class android.support.design.internal.BottomNavigationItemView { *; }
+
+#-dontwarn android.support.v8.renderscript.*
+#-keepclassmembers class android.support.v8.renderscript.RenderScript {
+# native *** rsn*(...);
+# native *** n*(...);
+#}
+
+#-keep class org.jaudiotagger.** { *; }
\ No newline at end of file
diff --git a/app/src/debug/res/font/bold.ttf b/app/src/debug/res/font/bold.ttf
deleted file mode 100644
index 96619df92..000000000
Binary files a/app/src/debug/res/font/bold.ttf and /dev/null differ
diff --git a/app/src/debug/res/font/google_sans_bold.ttf b/app/src/debug/res/font/google_sans_bold.ttf
deleted file mode 100644
index 80497666e..000000000
Binary files a/app/src/debug/res/font/google_sans_bold.ttf and /dev/null differ
diff --git a/app/src/debug/res/font/google_sans_medium.ttf b/app/src/debug/res/font/google_sans_medium.ttf
deleted file mode 100644
index 1543660da..000000000
Binary files a/app/src/debug/res/font/google_sans_medium.ttf and /dev/null differ
diff --git a/app/src/debug/res/font/google_sans_regular.ttf b/app/src/debug/res/font/google_sans_regular.ttf
deleted file mode 100644
index ab605f9e2..000000000
Binary files a/app/src/debug/res/font/google_sans_regular.ttf and /dev/null differ
diff --git a/app/src/debug/res/font/medium.ttf b/app/src/debug/res/font/medium.ttf
deleted file mode 100644
index fd818d6f5..000000000
Binary files a/app/src/debug/res/font/medium.ttf and /dev/null differ
diff --git a/app/src/debug/res/font/regular.ttf b/app/src/debug/res/font/regular.ttf
deleted file mode 100644
index e2c69c3fb..000000000
Binary files a/app/src/debug/res/font/regular.ttf and /dev/null differ
diff --git a/app/src/debug/res/font/sans.xml b/app/src/debug/res/font/sans.xml
deleted file mode 100644
index 7bbc8513b..000000000
--- a/app/src/debug/res/font/sans.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/debug/res/values/bools.xml b/app/src/debug/res/values/bools.xml
deleted file mode 100644
index 7d3f0ee62..000000000
--- a/app/src/debug/res/values/bools.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- true
- false
-
\ No newline at end of file
diff --git a/app/src/debug/res/values/donottranslate.xml b/app/src/debug/res/values/donottranslate.xml
deleted file mode 100644
index 79e559838..000000000
--- a/app/src/debug/res/values/donottranslate.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- Metro Debug
-
\ No newline at end of file
diff --git a/app/src/debug/res/values/styles.xml b/app/src/debug/res/values/styles.xml
deleted file mode 100644
index f3761b219..000000000
--- a/app/src/debug/res/values/styles.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 14fbaaab7..5fa8503e1 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,57 +1,31 @@
+ package="code.name.monkey.retromusic">
-
-
-
-
-
-
-
-
+
+
+
+
-
-
+
-
-
+
+
+ android:theme="@style/Theme.RetroMusic.Light"
+ tools:replace="android:allowBackup">
+ android:name=".ui.activities.MainActivity"
+ android:label="@string/app_name">
@@ -62,6 +36,7 @@
+
@@ -98,7 +73,7 @@
-
+
@@ -121,102 +96,74 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+ android:name=".ui.activities.LockScreenActivity"
+ android:autoRemoveFromRecents="true"
+ android:launchMode="singleInstance"
+ android:screenOrientation="sensorPortrait"
+ android:showOnLockScreen="true" />
+
+
+
+
+
-
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
@@ -226,10 +173,9 @@
android:name="android.appwidget.provider"
android:resource="@xml/app_widget_big_info" />
-
@@ -241,7 +187,7 @@
@@ -251,21 +197,9 @@
android:name="android.appwidget.provider"
android:resource="@xml/app_widget_small_info" />
-
-
-
-
-
-
-
@@ -275,76 +209,36 @@
android:name="android.appwidget.provider"
android:resource="@xml/app_widget_card_info" />
-
+
-
+
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
+
-
-
+ android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/provider_paths" />
+
-
-
-
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/assets/fonts/circular_std_black.otf b/app/src/main/assets/fonts/circular_std_black.otf
new file mode 100755
index 000000000..c62b210c5
Binary files /dev/null and b/app/src/main/assets/fonts/circular_std_black.otf differ
diff --git a/app/src/main/assets/fonts/circular_std_book.otf b/app/src/main/assets/fonts/circular_std_book.otf
new file mode 100755
index 000000000..3a1f1ad82
Binary files /dev/null and b/app/src/main/assets/fonts/circular_std_book.otf differ
diff --git a/app/src/main/assets/fonts/product_sans_bold.ttf b/app/src/main/assets/fonts/product_sans_bold.ttf
new file mode 100755
index 000000000..d847195c7
Binary files /dev/null and b/app/src/main/assets/fonts/product_sans_bold.ttf differ
diff --git a/app/src/main/assets/fonts/product_sans_regular.ttf b/app/src/main/assets/fonts/product_sans_regular.ttf
new file mode 100755
index 000000000..c0442ee29
Binary files /dev/null and b/app/src/main/assets/fonts/product_sans_regular.ttf differ
diff --git a/app/src/main/assets/images/daksh.png b/app/src/main/assets/images/daksh.png
deleted file mode 100644
index 737f9066c..000000000
Binary files a/app/src/main/assets/images/daksh.png and /dev/null differ
diff --git a/app/src/main/assets/images/haythem.jpg b/app/src/main/assets/images/haythem.jpg
deleted file mode 100644
index c74527f1d..000000000
Binary files a/app/src/main/assets/images/haythem.jpg and /dev/null differ
diff --git a/app/src/main/assets/images/hemanth.jpg b/app/src/main/assets/images/hemanth.jpg
deleted file mode 100644
index b8f5e7805..000000000
Binary files a/app/src/main/assets/images/hemanth.jpg and /dev/null differ
diff --git a/app/src/main/assets/images/lenny.jpg b/app/src/main/assets/images/lenny.jpg
deleted file mode 100644
index 7f8025f08..000000000
Binary files a/app/src/main/assets/images/lenny.jpg and /dev/null differ
diff --git a/app/src/main/assets/images/milind.png b/app/src/main/assets/images/milind.png
deleted file mode 100644
index bbf9b8278..000000000
Binary files a/app/src/main/assets/images/milind.png and /dev/null differ
diff --git a/app/src/main/assets/images/pratham.jpg b/app/src/main/assets/images/pratham.jpg
deleted file mode 100644
index 7f05ad9d5..000000000
Binary files a/app/src/main/assets/images/pratham.jpg and /dev/null differ
diff --git a/app/src/main/assets/index.html b/app/src/main/assets/index.html
new file mode 100644
index 000000000..115106cb5
--- /dev/null
+++ b/app/src/main/assets/index.html
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Phonograph by Karim Abou Zeid
+ RxAndroid by RxAndroid authors
+ RxJava by RxJava authors
+ Material Dialogs by Aidan Michael Follestad
+ Calligraphy by RxJava authors
+ Android-Snowfall by JetRadar
+ Android Sliding Up Panel by The Umano Team
+ AOSP Support Libraries by AOSP contributors
+ Butter Knife by Jake Wharton
+ Glide by Sam Judd
+ Retrofit by Square team
+ Material Contextual Action Bar by Aidan Michael Follestad
+ OkHttp by Square team
+ CircleImageView by Henning Dodenhof
+ Transitions Everywhere by Henning Dodenhof
+ MaterialProgressBar by Zhang Hai
+ Android In-App Billing v3 Library by Henning Dodenhof
+ Advanced RecyclerView by Haruki Hasegawa
+ Android-ObservableScrollView by Soichiro Kashima
+ BottomNavigationViewEx by Ittianyu
+ Swipe-Button by EBANX Team
+ Font used(CIRCULAR STD BOOK FONT) by NIELSON CAETANO
+ Icons by Austin Andrews
+ Croller by Harjot Oberai
+ Material Design City Wallpaper
+
+
+
diff --git a/app/src/main/assets/license.html b/app/src/main/assets/license.html
deleted file mode 100644
index 2fd8ba5ed..000000000
--- a/app/src/main/assets/license.html
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
-
-
-
-
-
-
- Phonograph by
- Karim Abou Zeid
-AOSP Support Libraries by AOSP contributors
- Glide by Sam Judd
- Retrofit by Square team
-
- OkHttp by Square team
-Koin by Arnaud Giuliani
- Material Dialogs and Cab
- by Aidan Michael Follestad
-
- Material Contextual Action Bar by Aidan Michael Follestad
- Advanced RecyclerView by Haruki Hasegawa
-Custom Activity on Crash by Eduard Ereza Martínez
-
-NanoHttpd by NanoHttpd Team
-Circular Seekbar by Tankery
-jAudioTagger by Kanedias
-Android Fast Scroll by Zhang Hai
-Image Picker by Dhaval Patel
-Material Intro by Jan Heinrich Reimer
-Slidr by Drew Heavner
-FadingEdgeLayout by bosphere
-KeyboardVisibilityEvent by Yasuhiro SHIMIZU
-android-snowfall by Jetradar Mobile
-Insetter by Chris Banes
- Icons by Austin Andrews
- Material Design City Wallpaper
-
-
-
diff --git a/app/src/main/assets/retro-changelog.html b/app/src/main/assets/retro-changelog.html
deleted file mode 100644
index b6b1c411a..000000000
--- a/app/src/main/assets/retro-changelog.html
+++ /dev/null
@@ -1,466 +0,0 @@
-
-
-
-
-
-
-
-
-
-
March 30, 2023
-
v6.1.0
-
What's New
-
- App now targets Android 13, support for Granular media permissions, Photo picker, Per-app language preferences & Predictive back gesture
-
-
Fixed
-
- Fixed playlist reordering crash
- Other minor bugs fixes and improvements
-
-
-
-
March 13, 2023
-
v6.0.4
-
What's New
-
- Minor redesign in Playlist details screen
- Updated translations
-
-
Fixed
-
- Fixed file popup menu actions in Folders tab
- Fixed playlist image loading
- Fixed blurry album art in Android 13
- Minor bug fixes and improvements
-
-
-
-
July 10, 2022
-
v6.0.3Beta
-
Fixed
-
- Migrated icons to Material symbols
-
-
-
-
June 21, 2022
-
v6.0.2Beta
-
Fixed
-
- Minor bug fixes and improvements
-
-
-
-
June 13, 2022
-
v6.0.1Beta
-
Fixed
-
- Fixed ChromeCast crash
- Fixed Slider crashes
- Fixed storage related crashes on Android 10
- Fixed CrossFade not working Fade Audio is not working
-
-
-
-
June 7, 2022
-
v6.0.0Beta
-
What's New
-
- Better Cast
- Mini player in settings screen
- Changed Seekbar with Sliders
- Added NavigationRailView for Landscape
- Show remaining time in Sleep timer dialog
-
-
Fixed
-
- Fixed Top/Recent Artists/Albums not updating (Wrong sort order)
- Fixed all Blacklist related crashes
- Fix restart button not working in crash activity
-
-
-
-
May 25, 2022
-
v5.8.5
-
What's New
-
- Display song images along in the artist and album details pages
- Removed the Internet permissions and all the associated features
-
-
Fixed
-
- Fixed crashing occurs during changing screen orientation
-
-
-
-
May 13, 2022
-
v5.8.4
-
What's New
-
- Added a toggle to enable/disable swipe down to dismiss mini player
-
-
Fixed
-
- Fixed Playback speed and pitch not working when CrossFade is enabled
- Fixed crash when adding folders to blacklist
- Fix bugs in MD3 theme
-
-
-
-
May 07, 2022
-
v5.8.3
-
What's New
-
- Added a new MD3 now playing theme
- Swipe down to dismiss Mini player
- Add support for Just Black with Material You
-
-
Fixed
-
- Fixed sharing of files from SD Card
- Fix ChromeCast crash and bugs
- Fix Audio Crossfade
- Tried to fix incorrect song data in notification
-
-
-
-
April 8, 2022
-
v5.8.0
-
What's New
-
-
Fixed
-
- Fixed Classic Notification crash
- Fixed crash when clicking on Playlist in the Search Tab
- Fixed settings change not reflecting immediately
- Fixed shuffle
- Fixed Song duration not visible in Card & Blur card themes
- Fixed some Album skip styles
- Minor bug fixes & UI improvements
-
-
-
-
March 13, 2022
-
v5.7.3
-
What's New
-
- Added adaptive color in Material now playing theme
- Added an option to share crash report
- Added options to clear, pause history
-
-
Fixed
-
- Adapt Wallpaper accent for better readability
- Optimized search
- Made sleep timer precise
-
-
-
-
February 13, 2022
-
v5.7.2Beta
-
What's New
-
- Animated splash screen on Android 12 devices
-
-
Fixed
-
- Fixed crash when removing song from Playing queue
- Fixed lyrics editing crash
- Fixed shuffle button not working
- Fixed crash on song deletion
-
-
-
-
February 1, 2022
-
v5.7.1Beta
-
What's New
-
- Added option to disable changing song by swiping anywhere on the now playing screen
-
-
Fixed
-
- Fixed Playlist save on A11+
- Fixed Just Black theme
- Fixed some UI issues
-
-
Improved
-
- Improvements to search
-
-
-
-
January 25, 2022
-
v5.7.0Beta
-
What's New
-
- Added Android Auto
- Added accent color extraction on Android 8.1+ devices
- Added new Circle widget
- Added Collapsing appbar to library tabs with an option to switch back to simple appbar
-
- Added Search tab
- Added option to use circular play button
- Added lyrics editing on A11+ devices again
- Added Long Press to forward, rewind current song
- Added ability to set Playback speed and pitch
- Added option to show lyrics over Cover
- Added option to keep screen on when showing lyrics
- Added option to switch to Manrope font
-
-
Fixed
-
- Fixed Gapless Playback
- Fixed Shuffle FAB going behind Mini Player
- Fixed crashes on Pre-marshmallow devices
- Blacklisted songs can't be played after opening from outside the app
- Fixed various small bugs and some minor improvements
-
-
-
-
January 1, 2021
-
v5.6.1
-
Fixed
-
- Fixed artist covers not updating and showing album cover images.
- Fixed FAB's not visible (Shuffle, Save, etc.)
- Fixed a crash when a Song is deleted in Artist Details
- Fixed Snowfall effect
- Fixed empty notification when queue is cleared
-
-
-
-
December 25, 2021
-
v5.6.0Beta
-
What's New
-
- Added Artwork editing for songs
- Circle theme has album art now
- Upgraded tag editor library, we should support reading tags of more formats now e.g.
- opus.
-
- Added Snowfall effect
- Crossfade effect for background when Song is changed for Blur, Blur card themes
- Album art is hidden when Show lyrics is enabled
- Added fastscroll in Playlists tab
- Added Chooser to choose what to restore
- Hide BottomNavigation when only one tab is selected in Library Categories(This was
- already there but when changing screens it was getting visible)
-
-
-
Fixed
-
- Fixed Ringtone crash
- Fixed blank album cover bug
- Fixed bottom navigation visible in Playing Queue
- Fixed lockscreen dragging glitch
- Fixed incorrect colors when no cover art is available
- Fixed favorite not updating when song is changed
- Fixed playlist not getting created & playlist creation crash with same name
- Fixed a bug in "Plain" Now playing theme where onClick event is consumed by the views
- behind the bottom sheet
-
-
-
-
-
December 6, 2021
-
v5.4.2Beta
-
Fixed
-
-
-
-
December 1, 2021
-
v5.4.1Beta
-
What's New
-
- Added file selection from system file picker for restore
- Added Grid size selection for Playlists
-
-
Improved
-
- Enable Material You by default on Android 12
- Reworked Grid Style saving
- Improved Playlist preview images
- UI improvements
-
-
Improved
-
- Fixed File deletion on Android 10
- Fixed Sleep Timer crash
- Fixed Bottom Toolbar not clickable in now playing when Shuffle is clicked
- Fixed Album Artist sort order
- Fixed a crash when clicking the "Clear All" button in the Blacklist folder selection
-
- Fixed Continuous crashes on A12 when the song ends
- Fixed New Music Mix multiple clicks crash
-
-
-
-
November 22, 2021
-
v5.4.0Beta
-
What's New
-
- Material You
- Going Edge-to-Edge
- Added Backup & restore
-
-
Improved
-
- Improved Animations
- Improved Crossfade
-
-
-
-
September 06, 2021
-
v5.0.0
-
What's New
-
- Added ability to Remember last tab
- Added Whitelisting songs
- You can now browse SDCard from Folders Tab
-
-
-
-
August 22, 2021
-
v4.4.0Beta
-
What's New
-
- Added Crossfade
- Multi-select in Album and Artist Details
- Albums now show Album Artists instead of artist of first song
-
-
Fixed
-
- Fixed Playlist Preview Images
-
-
-
-
August 11, 2021
-
v4.2.30Beta
-
What's New
-
- Revamped Playlist Tab
- Revamped Genres Tab
- Added support for embedded Synced Lyrics
- Added animated icons
-
-
Fixed
-
- Fixed Language Switching
- Fixed some reported bugs
-
-
-
-
July 18, 2021
-
v4.2.020Beta
-
What's New
-
- Added ChromeCast Support
- Added Lyrics Editor for Normal and Synced Lyrics
- Added Ripple Animation for Color Theme
- Added Drag to seek in Tiny Theme
- Added Playlist Order
- Added Search Filters
- Added Audio Fade
- Synced Lyrics in all Themes
- Swipe anywhere to change song
-
-
Improved
-
- Fixed Navigate by Album Artist
- Changed New Music Mix Actions
- Improved Animations
- And some minor bug fixes and improvements
-
-
-
-
October 12, 2020
-
v4.0.10
-
What's New
-
- Re-built from scratch using MVVM Architecture and JetPack Components
- New Material Design icon
- Implemented a custom database for playlists
- Added new Material Design motions
- Bug fixes & performance improvements
- Revamped Home tab UI
- Android 11 support
- And more!
-
-
-
-
April 30, 2020
-
v3.5.110Beta
-
What's New
-
- Changed profile form image to icon
- New what's new screen
- Added In-App language changer, where you can select language
-
-
Improved
-
- Improved loading of Songs, Albums, Artists, Genres, Playlists
-
-
-
\ No newline at end of file
diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png
deleted file mode 100644
index aa6e4ae9a..000000000
Binary files a/app/src/main/ic_launcher-playstore.png and /dev/null differ
diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png
index 7e7647db5..ed5e3a831 100644
Binary files a/app/src/main/ic_launcher-web.png and b/app/src/main/ic_launcher-web.png differ
diff --git a/app/src/main/java/code/name/monkey/retromusic/App.kt b/app/src/main/java/code/name/monkey/retromusic/App.kt
deleted file mode 100644
index 93dfe4d96..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/App.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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
-
-import android.app.Application
-import androidx.preference.PreferenceManager
-import cat.ereza.customactivityoncrash.config.CaocConfig
-import code.name.monkey.appthemehelper.ThemeStore
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.activities.ErrorActivity
-import code.name.monkey.retromusic.activities.MainActivity
-import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
-import code.name.monkey.retromusic.helper.WallpaperAccentManager
-import org.koin.android.ext.koin.androidContext
-import org.koin.core.context.startKoin
-
-class App : Application() {
-
- private val wallpaperAccentManager = WallpaperAccentManager(this)
-
- override fun onCreate() {
- super.onCreate()
- instance = this
-
- startKoin {
- androidContext(this@App)
- modules(appModules)
- }
- // default theme
- if (!ThemeStore.isConfigured(this, 3)) {
- ThemeStore.editTheme(this)
- .accentColorRes(code.name.monkey.appthemehelper.R.color.md_deep_purple_A200)
- .coloredNavigationBar(true)
- .commit()
- }
- wallpaperAccentManager.init()
-
- if (VersionUtils.hasNougatMR())
- DynamicShortcutManager(this).initDynamicShortcuts()
-
- // setting Error activity
- CaocConfig.Builder.create().errorActivity(ErrorActivity::class.java)
- .restartActivity(MainActivity::class.java).apply()
-
- // Set Default values for now playing preferences
- // This will reduce startup time for now playing settings fragment as Preference listener of AbsSlidingMusicPanelActivity won't be called
- PreferenceManager.setDefaultValues(this, R.xml.pref_now_playing_screen, false)
- }
-
- override fun onTerminate() {
- super.onTerminate()
- wallpaperAccentManager.release()
- }
-
- companion object {
- private var instance: App? = null
-
- fun getContext(): App {
- return instance!!
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/Constants.java b/app/src/main/java/code/name/monkey/retromusic/Constants.java
new file mode 100644
index 000000000..c8485a4df
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/Constants.java
@@ -0,0 +1,44 @@
+package code.name.monkey.retromusic;
+
+public class Constants {
+
+ public static final String DISCORD_LINK = "https://discord.gg/qTecXXn";
+
+ public static final String RETRO_MUSIC_PACKAGE_NAME = "code.name.monkey.retromusic";
+ public static final String MUSIC_PACKAGE_NAME = "com.android.music";
+ public static final String ACTION_TOGGLE_PAUSE = RETRO_MUSIC_PACKAGE_NAME + ".togglepause";
+ public static final String ACTION_PLAY = RETRO_MUSIC_PACKAGE_NAME + ".play";
+ public static final String ACTION_PLAY_PLAYLIST = RETRO_MUSIC_PACKAGE_NAME + ".play.playlist";
+ public static final String ACTION_PAUSE = RETRO_MUSIC_PACKAGE_NAME + ".pause";
+ public static final String ACTION_STOP = RETRO_MUSIC_PACKAGE_NAME + ".stop";
+ public static final String ACTION_SKIP = RETRO_MUSIC_PACKAGE_NAME + ".skip";
+ public static final String ACTION_REWIND = RETRO_MUSIC_PACKAGE_NAME + ".rewind";
+ public static final String ACTION_QUIT = RETRO_MUSIC_PACKAGE_NAME + ".quitservice";
+ public static final String INTENT_EXTRA_PLAYLIST =
+ RETRO_MUSIC_PACKAGE_NAME + "intentextra.playlist";
+ public static final String INTENT_EXTRA_SHUFFLE_MODE =
+ RETRO_MUSIC_PACKAGE_NAME + ".intentextra.shufflemode";
+ public static final String APP_WIDGET_UPDATE = RETRO_MUSIC_PACKAGE_NAME + ".appwidgetupdate";
+ public static final String EXTRA_APP_WIDGET_NAME = RETRO_MUSIC_PACKAGE_NAME + "app_widget_name";
+ // do not change these three strings as it will break support with other apps (e.g. last.fm scrobbling)
+ public static final String META_CHANGED = RETRO_MUSIC_PACKAGE_NAME + ".metachanged";
+ public static final String QUEUE_CHANGED = RETRO_MUSIC_PACKAGE_NAME + ".queuechanged";
+ public static final String PLAY_STATE_CHANGED = RETRO_MUSIC_PACKAGE_NAME + ".playstatechanged";
+ public static final String REPEAT_MODE_CHANGED = RETRO_MUSIC_PACKAGE_NAME + ".repeatmodechanged";
+ public static final String SHUFFLE_MODE_CHANGED =
+ RETRO_MUSIC_PACKAGE_NAME + ".shufflemodechanged";
+ public static final String MEDIA_STORE_CHANGED = RETRO_MUSIC_PACKAGE_NAME + ".mediastorechanged";
+ public static final String RATE_ON_GOOGLE_PLAY = "https://play.google.com/store/apps/details?id=code.name.monkey.retromusic";
+ public static final String PAYPAL_ME_URL = "https://www.paypal.me/h4h14";
+ public static final String GOOGLE_PLUS_COMMUNITY = "https://plus.google.com/communities/110811566242871492162";
+ public static final String TRANSLATE = "http://monkeycodeapp.oneskyapp.com/collaboration/project?id=238534";
+ public static final String GITHUB_PROJECT = "https://github.com/h4h13/RetroMusicPlayer";
+ public static final String BASE_API_URL_KUGOU = "http://lyrics.kugou.com/";
+ public static final String TELEGRAM_CHANGE_LOG = "https://t.me/retromusiclog";
+ public static final String USER_PROFILE = "profile.jpg";
+ public static final String USER_BANNER = "banner.jpg";
+ public static final String APP_INSTAGRAM_LINK = "https://www.instagram.com/retromusicapp/";
+ public static final String APP_TELEGRAM_LINK = "https://t.me/retromusicapp/";
+ public static final String APP_TWITTER_LINK = "https://twitter.com/retromusicapp";
+ public static final String FAQ_LINK = "https://github.com/h4h13/RetroMusicPlayer/blob/master/FAQ.md";
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/Constants.kt b/app/src/main/java/code/name/monkey/retromusic/Constants.kt
deleted file mode 100644
index 31032f62b..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/Constants.kt
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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
-
-import android.provider.BaseColumns
-import android.provider.MediaStore
-
-object Constants {
- const val TRANSLATE = "https://crowdin.com/project/retromusicplayer"
- const val GITHUB_PROJECT = "https://github.com/MuntashirAkon/Metro"
- const val TELEGRAM_CHANGE_LOG = "https://t.me/AppManagerChannel"
- const val USER_PROFILE = "profile.jpg"
- const val USER_BANNER = "banner.jpg"
- const val FAQ_LINK = "https://github.com/MuntashirAkon/Metro/blob/master/FAQ.md"
-
- const val IS_MUSIC =
- MediaStore.Audio.AudioColumns.IS_MUSIC + "=1" + " AND " + MediaStore.Audio.AudioColumns.TITLE + " != ''"
-
- const val DATA = "_data"
-
- @Suppress("Deprecation")
- val baseProjection = arrayOf(
- BaseColumns._ID, // 0
- MediaStore.Audio.AudioColumns.TITLE, // 1
- MediaStore.Audio.AudioColumns.TRACK, // 2
- MediaStore.Audio.AudioColumns.YEAR, // 3
- MediaStore.Audio.AudioColumns.DURATION, // 4
- DATA, // 5
- MediaStore.Audio.AudioColumns.DATE_MODIFIED, // 6
- MediaStore.Audio.AudioColumns.ALBUM_ID, // 7
- MediaStore.Audio.AudioColumns.ALBUM, // 8
- MediaStore.Audio.AudioColumns.ARTIST_ID, // 9
- MediaStore.Audio.AudioColumns.ARTIST, // 10
- MediaStore.Audio.AudioColumns.COMPOSER, // 11
- ALBUM_ARTIST // 12
- )
- const val NUMBER_OF_TOP_TRACKS = 99
-}
-
-const val EXTRA_PLAYLIST_TYPE = "type"
-const val EXTRA_GENRE = "extra_genre"
-const val EXTRA_PLAYLIST = "extra_playlist"
-const val EXTRA_PLAYLIST_ID = "extra_playlist_id"
-const val EXTRA_ALBUM_ID = "extra_album_id"
-const val EXTRA_ARTIST_ID = "extra_artist_id"
-const val EXTRA_SONG = "extra_songs"
-const val EXTRA_PLAYLISTS = "extra_playlists"
-const val LIBRARY_CATEGORIES = "library_categories"
-const val EXTRA_SONG_INFO = "extra_song_info"
-const val DESATURATED_COLOR = "desaturated_color"
-const val BLACK_THEME = "black_theme"
-const val KEEP_SCREEN_ON = "keep_screen_on"
-const val TOGGLE_HOME_BANNER = "toggle_home_banner"
-const val NOW_PLAYING_SCREEN_ID = "now_playing_screen_id"
-const val CAROUSEL_EFFECT = "carousel_effect"
-const val COLORED_NOTIFICATION = "colored_notification"
-const val CLASSIC_NOTIFICATION = "classic_notification"
-const val GAP_LESS_PLAYBACK = "gapless_playback"
-const val ALBUM_ART_ON_LOCK_SCREEN = "album_art_on_lock_screen"
-const val BLURRED_ALBUM_ART = "blurred_album_art"
-const val NEW_BLUR_AMOUNT = "new_blur_amount"
-const val TOGGLE_HEADSET = "toggle_headset"
-const val GENERAL_THEME = "general_theme"
-const val ACCENT_COLOR = "accent_color"
-const val SHOULD_COLOR_APP_SHORTCUTS = "should_color_app_shortcuts"
-const val CIRCULAR_ALBUM_ART = "circular_album_art"
-const val USER_NAME = "user_name"
-const val TOGGLE_FULL_SCREEN = "toggle_full_screen"
-const val TOGGLE_VOLUME = "toggle_volume"
-const val ADAPTIVE_COLOR_APP = "adaptive_color_app"
-const val HOME_ARTIST_GRID_STYLE = "home_artist_grid_style"
-const val HOME_ALBUM_GRID_STYLE = "home_album_grid_style"
-const val TOGGLE_ADD_CONTROLS = "toggle_add_controls"
-const val ALBUM_COVER_STYLE = "album_cover_style_id"
-const val ALBUM_COVER_TRANSFORM = "album_cover_transform"
-const val TAB_TEXT_MODE = "tab_text_mode"
-const val LANGUAGE_NAME = "language_name"
-const val LOCALE_AUTO_STORE_ENABLED = "locale_auto_store_enabled"
-const val SLEEP_TIMER_FINISH_SONG = "sleep_timer_finish_song"
-const val ALBUM_GRID_STYLE = "album_grid_style_home"
-const val ARTIST_GRID_STYLE = "artist_grid_style_home"
-const val SAF_SDCARD_URI = "saf_sdcard_uri"
-const val SONG_SORT_ORDER = "song_sort_order"
-const val SONG_GRID_SIZE = "song_grid_size"
-const val GENRE_SORT_ORDER = "genre_sort_order"
-const val BLUETOOTH_PLAYBACK = "bluetooth_playback"
-const val INITIALIZED_BLACKLIST = "initialized_blacklist"
-const val ARTIST_SORT_ORDER = "artist_sort_order"
-const val ARTIST_ALBUM_SORT_ORDER = "artist_album_sort_order"
-const val ALBUM_SORT_ORDER = "album_sort_order"
-const val PLAYLIST_SORT_ORDER = "playlist_sort_order"
-const val ALBUM_SONG_SORT_ORDER = "album_song_sort_order"
-const val ARTIST_SONG_SORT_ORDER = "artist_song_sort_order"
-const val ALBUM_GRID_SIZE = "album_grid_size"
-const val ALBUM_GRID_SIZE_LAND = "album_grid_size_land"
-const val SONG_GRID_SIZE_LAND = "song_grid_size_land"
-const val ARTIST_GRID_SIZE = "artist_grid_size"
-const val ARTIST_GRID_SIZE_LAND = "artist_grid_size_land"
-const val PLAYLIST_GRID_SIZE = "playlist_grid_size"
-const val PLAYLIST_GRID_SIZE_LAND = "playlist_grid_size_land"
-const val COLORED_APP_SHORTCUTS = "colored_app_shortcuts"
-const val LAST_ADDED_CUTOFF = "last_added_interval"
-const val LAST_SLEEP_TIMER_VALUE = "last_sleep_timer_value"
-const val NEXT_SLEEP_TIMER_ELAPSED_REALTIME = "next_sleep_timer_elapsed_real_time"
-const val IGNORE_MEDIA_STORE_ARTWORK = "ignore_media_store_artwork"
-const val LAST_CHANGELOG_VERSION = "last_changelog_version"
-const val START_DIRECTORY = "start_directory"
-const val RECENTLY_PLAYED_CUTOFF = "recently_played_interval"
-const val LOCK_SCREEN = "lock_screen"
-const val ALBUM_ARTISTS_ONLY = "album_artists_only"
-const val ALBUM_ARTIST = "album_artist"
-const val ALBUM_DETAIL_SONG_SORT_ORDER = "album_detail_song_sort_order"
-const val ARTIST_DETAIL_SONG_SORT_ORDER = "artist_detail_song_sort_order"
-const val LYRICS_OPTIONS = "lyrics_tab_position"
-const val CHOOSE_EQUALIZER = "choose_equalizer"
-const val EQUALIZER = "equalizer"
-const val SONG_GRID_STYLE = "song_grid_style"
-const val PAUSE_ON_ZERO_VOLUME = "pause_on_zero_volume"
-const val FILTER_SONG = "filter_song"
-const val EXPAND_NOW_PLAYING_PANEL = "expand_now_playing_panel"
-const val EXTRA_ARTIST_NAME = "extra_artist_name"
-const val TOGGLE_SUGGESTIONS = "toggle_suggestions"
-const val AUDIO_FADE_DURATION = "audio_fade_duration"
-const val CROSS_FADE_DURATION = "cross_fade_duration"
-const val SHOW_LYRICS = "show_lyrics"
-const val REMEMBER_LAST_TAB = "remember_last_tab"
-const val LAST_USED_TAB = "last_used_tab"
-const val WHITELIST_MUSIC = "whitelist_music"
-const val MATERIAL_YOU = "material_you"
-const val SNOWFALL = "snowfall"
-const val LYRICS_TYPE = "lyrics_type"
-const val PLAYBACK_SPEED = "playback_speed"
-const val PLAYBACK_PITCH = "playback_pitch"
-const val CUSTOM_FONT = "custom_font"
-const val APPBAR_MODE = "appbar_mode"
-const val WALLPAPER_ACCENT = "wallpaper_accent"
-const val SCREEN_ON_LYRICS = "screen_on_lyrics"
-const val CIRCLE_PLAY_BUTTON = "circle_play_button"
-const val SWIPE_ANYWHERE_NOW_PLAYING = "swipe_anywhere_now_playing"
-const val PAUSE_HISTORY = "pause_history"
-const val MANAGE_AUDIO_FOCUS = "manage_audio_focus"
-const val SWIPE_DOWN_DISMISS = "swipe_to_dismiss"
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/HomeSection.kt b/app/src/main/java/code/name/monkey/retromusic/HomeSection.kt
deleted file mode 100644
index 4f1273a03..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/HomeSection.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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
-
-import androidx.annotation.IntDef
-
-@IntDef(
- RECENT_ALBUMS,
- TOP_ALBUMS,
- RECENT_ARTISTS,
- TOP_ARTISTS,
- SUGGESTIONS,
- FAVOURITES,
- GENRES,
- PLAYLISTS
-)
-@Retention(AnnotationRetention.SOURCE)
-annotation class HomeSection
-
-const val RECENT_ALBUMS = 3
-const val TOP_ALBUMS = 1
-const val RECENT_ARTISTS = 2
-const val TOP_ARTISTS = 0
-const val SUGGESTIONS = 5
-const val FAVOURITES = 4
-const val GENRES = 6
-const val PLAYLISTS = 7
-const val HISTORY_PLAYLIST = 8
-const val LAST_ADDED_PLAYLIST = 9
-const val TOP_PLAYED_PLAYLIST = 10
diff --git a/app/src/main/java/code/name/monkey/retromusic/Injection.java b/app/src/main/java/code/name/monkey/retromusic/Injection.java
new file mode 100644
index 000000000..4fe94a74c
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/Injection.java
@@ -0,0 +1,23 @@
+package code.name.monkey.retromusic;
+
+import code.name.monkey.retromusic.providers.RepositoryImpl;
+import code.name.monkey.retromusic.providers.interfaces.Repository;
+import code.name.monkey.retromusic.rest.KogouClient;
+import code.name.monkey.retromusic.rest.service.KuGouApiService;
+import code.name.monkey.retromusic.util.schedulers.BaseSchedulerProvider;
+import code.name.monkey.retromusic.util.schedulers.SchedulerProvider;
+
+public class Injection {
+
+ public static Repository provideRepository() {
+ return RepositoryImpl.getInstance();
+ }
+
+ public static BaseSchedulerProvider provideSchedulerProvider() {
+ return SchedulerProvider.getInstance();
+ }
+
+ public static KuGouApiService provideKuGouApiService() {
+ return new KogouClient().getApiService();
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/MainModule.kt b/app/src/main/java/code/name/monkey/retromusic/MainModule.kt
deleted file mode 100644
index d88f8a760..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/MainModule.kt
+++ /dev/null
@@ -1,156 +0,0 @@
-package code.name.monkey.retromusic
-
-import androidx.room.Room
-import code.name.monkey.retromusic.auto.AutoMusicProvider
-import code.name.monkey.retromusic.db.MIGRATION_23_24
-import code.name.monkey.retromusic.db.RetroDatabase
-import code.name.monkey.retromusic.fragments.LibraryViewModel
-import code.name.monkey.retromusic.fragments.albums.AlbumDetailsViewModel
-import code.name.monkey.retromusic.fragments.artists.ArtistDetailsViewModel
-import code.name.monkey.retromusic.fragments.genres.GenreDetailsViewModel
-import code.name.monkey.retromusic.fragments.playlists.PlaylistDetailsViewModel
-import code.name.monkey.retromusic.model.Genre
-import code.name.monkey.retromusic.repository.*
-import org.koin.android.ext.koin.androidContext
-import org.koin.androidx.viewmodel.dsl.viewModel
-import org.koin.dsl.bind
-import org.koin.dsl.module
-
-private val roomModule = module {
-
- single {
- Room.databaseBuilder(androidContext(), RetroDatabase::class.java, "playlist.db")
- .addMigrations(MIGRATION_23_24)
- .build()
- }
-
- factory {
- get().playlistDao()
- }
-
- factory {
- get().playCountDao()
- }
-
- factory {
- get().historyDao()
- }
-
- single {
- RealRoomRepository(get(), get(), get())
- } bind RoomRepository::class
-}
-private val autoModule = module {
- single {
- AutoMusicProvider(
- androidContext(),
- get(),
- get(),
- get(),
- get(),
- get(),
- get()
- )
- }
-}
-private val mainModule = module {
- single {
- androidContext().contentResolver
- }
-}
-private val dataModule = module {
- single {
- RealRepository(
- get(),
- get(),
- get(),
- get(),
- get(),
- get(),
- get(),
- get(),
- get(),
- get(),
- )
- } bind Repository::class
-
- single {
- RealSongRepository(get())
- } bind SongRepository::class
-
- single {
- RealGenreRepository(get(), get())
- } bind GenreRepository::class
-
- single {
- RealAlbumRepository(get())
- } bind AlbumRepository::class
-
- single {
- RealArtistRepository(get(), get())
- } bind ArtistRepository::class
-
- single {
- RealPlaylistRepository(get())
- } bind PlaylistRepository::class
-
- single {
- RealTopPlayedRepository(get(), get(), get(), get())
- } bind TopPlayedRepository::class
-
- single {
- RealLastAddedRepository(
- get(),
- get(),
- get()
- )
- } bind LastAddedRepository::class
-
- single {
- RealSearchRepository(
- get(),
- get(),
- get(),
- get(),
- get()
- )
- }
-}
-
-private val viewModules = module {
-
- viewModel {
- LibraryViewModel(get())
- }
-
- viewModel { (albumId: Long) ->
- AlbumDetailsViewModel(
- get(),
- albumId
- )
- }
-
- viewModel { (artistId: Long?, artistName: String?) ->
- ArtistDetailsViewModel(
- get(),
- artistId,
- artistName
- )
- }
-
- viewModel { (playlistId: Long) ->
- PlaylistDetailsViewModel(
- get(),
- playlistId
- )
- }
-
- viewModel { (genre: Genre) ->
- GenreDetailsViewModel(
- get(),
- genre
- )
- }
-}
-
-val appModules = listOf(mainModule, dataModule, autoModule, viewModules, roomModule)
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/RetroApplication.java b/app/src/main/java/code/name/monkey/retromusic/RetroApplication.java
new file mode 100644
index 000000000..cc2abeef8
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/RetroApplication.java
@@ -0,0 +1,77 @@
+package code.name.monkey.retromusic;
+
+import android.os.Build;
+import android.support.annotation.NonNull;
+import android.support.multidex.MultiDexApplication;
+import code.name.monkey.appthemehelper.ThemeStore;
+import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager;
+import com.anjlab.android.iab.v3.BillingProcessor;
+import com.anjlab.android.iab.v3.TransactionDetails;
+import uk.co.chrisjenx.calligraphy.CalligraphyConfig;
+
+public class RetroApplication extends MultiDexApplication {
+
+ public static final String PRO_VERSION_PRODUCT_ID = "pro_version";
+
+ private static RetroApplication app;
+
+ private BillingProcessor billingProcessor;
+
+ public static RetroApplication getInstance() {
+ return app;
+ }
+
+ public static boolean isProVersion() {
+ return BuildConfig.DEBUG || app.billingProcessor.isPurchased(PRO_VERSION_PRODUCT_ID);
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ app = this;
+
+ // default theme
+ if (!ThemeStore.isConfigured(this, 1)) {
+ ThemeStore.editTheme(this)
+ .accentColorRes(R.color.md_green_A200)
+ .commit();
+ }
+
+ CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
+ .setDefaultFontPath("fonts/circular_std_book.otf")
+ .setFontAttrId(R.attr.fontPath)
+ .build()
+ );
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
+ new DynamicShortcutManager(this).initDynamicShortcuts();
+ }
+
+ // automatically restores purchases
+ billingProcessor = new BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSE_KEY,
+ new BillingProcessor.IBillingHandler() {
+ @Override
+ public void onProductPurchased(@NonNull String productId, TransactionDetails details) {
+ }
+
+ @Override
+ public void onPurchaseHistoryRestored() {
+ //Toast.makeText(App.this, R.string.restored_previous_purchase_please_restart, Toast.LENGTH_LONG).show();
+ }
+
+ @Override
+ public void onBillingError(int errorCode, Throwable error) {
+ }
+
+ @Override
+ public void onBillingInitialized() {
+ }
+ });
+ }
+
+ @Override
+ public void onTerminate() {
+ super.onTerminate();
+ billingProcessor.release();
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt
deleted file mode 100644
index af3890d22..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.activities
-
-import android.content.Intent
-import android.graphics.Color
-import android.graphics.PorterDuff
-import android.os.Bundle
-import androidx.lifecycle.lifecycleScope
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
-import code.name.monkey.retromusic.databinding.ActivityDriveModeBinding
-import code.name.monkey.retromusic.db.toSongEntity
-import code.name.monkey.retromusic.extensions.accentColor
-import code.name.monkey.retromusic.extensions.drawAboveSystemBars
-import code.name.monkey.retromusic.glide.BlurTransformation
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
-import code.name.monkey.retromusic.helper.MusicPlayerRemote
-import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
-import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper.Callback
-import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.repository.RealRepository
-import code.name.monkey.retromusic.service.MusicService
-import code.name.monkey.retromusic.util.MusicUtil
-import com.bumptech.glide.Glide
-import com.google.android.material.slider.Slider
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
-import org.koin.android.ext.android.inject
-
-
-/**
- * Created by hemanths on 2020-02-02.
- */
-
-class DriveModeActivity : AbsMusicServiceActivity(), Callback {
-
- private lateinit var binding: ActivityDriveModeBinding
- private var lastPlaybackControlsColor: Int = Color.GRAY
- private var lastDisabledPlaybackControlsColor: Int = Color.GRAY
- private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
- private val repository: RealRepository by inject()
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- binding = ActivityDriveModeBinding.inflate(layoutInflater)
- setContentView(binding.root)
- setUpMusicControllers()
-
- progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
- lastPlaybackControlsColor = accentColor()
- binding.close.setOnClickListener {
- onBackPressedDispatcher.onBackPressed()
- }
- binding.repeatButton.drawAboveSystemBars()
- }
-
- private fun setUpMusicControllers() {
- setUpPlayPauseFab()
- setUpPrevNext()
- setUpRepeatButton()
- setUpShuffleButton()
- setUpProgressSlider()
- setupFavouriteToggle()
- }
-
- private fun setupFavouriteToggle() {
- binding.songFavourite.setOnClickListener {
- toggleFavorite(MusicPlayerRemote.currentSong)
- }
- }
-
- private fun toggleFavorite(song: Song) {
- lifecycleScope.launch(Dispatchers.IO) {
- val playlist = repository.favoritePlaylist()
- val songEntity = song.toSongEntity(playlist.playListId)
- val isFavorite = repository.isSongFavorite(song.id)
- if (isFavorite) {
- repository.removeSongFromPlaylist(songEntity)
- } else {
- repository.insertSongs(listOf(song.toSongEntity(playlist.playListId)))
- }
- sendBroadcast(Intent(MusicService.FAVORITE_STATE_CHANGED))
- }
- }
-
- private fun updateFavorite() {
- lifecycleScope.launch(Dispatchers.IO) {
- val isFavorite: Boolean =
- repository.isSongFavorite(MusicPlayerRemote.currentSong.id)
- withContext(Dispatchers.Main) {
- binding.songFavourite.setImageResource(if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border)
- }
- }
- }
-
- private fun setUpProgressSlider() {
- binding.progressSlider.addOnChangeListener { _: Slider, progress: Float, fromUser: Boolean ->
- if (fromUser) {
- MusicPlayerRemote.seekTo(progress.toInt())
- onUpdateProgressViews(
- MusicPlayerRemote.songProgressMillis,
- MusicPlayerRemote.songDurationMillis
- )
- }
- }
- }
-
- override fun onPause() {
- super.onPause()
- progressViewUpdateHelper.stop()
- }
-
- override fun onResume() {
- super.onResume()
- progressViewUpdateHelper.start()
- }
-
- private fun setUpPrevNext() {
- binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
- binding.previousButton.setOnClickListener { MusicPlayerRemote.back() }
- }
-
- private fun setUpShuffleButton() {
- binding.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
- }
-
- private fun setUpRepeatButton() {
- binding.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
- }
-
- private fun setUpPlayPauseFab() {
- binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
- }
-
- override fun onRepeatModeChanged() {
- super.onRepeatModeChanged()
- updateRepeatState()
- }
-
- override fun onShuffleModeChanged() {
- super.onShuffleModeChanged()
- updateShuffleState()
- }
-
- override fun onPlayStateChanged() {
- super.onPlayStateChanged()
- updatePlayPauseDrawableState()
- }
-
- override fun onServiceConnected() {
- super.onServiceConnected()
- updatePlayPauseDrawableState()
- updateSong()
- updateRepeatState()
- updateShuffleState()
- updateFavorite()
- }
-
- private fun updatePlayPauseDrawableState() {
- if (MusicPlayerRemote.isPlaying) {
- binding.playPauseButton.setImageResource(R.drawable.ic_pause)
- } else {
- binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow)
- }
- }
-
- fun updateShuffleState() {
- when (MusicPlayerRemote.shuffleMode) {
- MusicService.SHUFFLE_MODE_SHUFFLE -> binding.shuffleButton.setColorFilter(
- lastPlaybackControlsColor,
- PorterDuff.Mode.SRC_IN
- )
-
- else -> binding.shuffleButton.setColorFilter(
- lastDisabledPlaybackControlsColor,
- PorterDuff.Mode.SRC_IN
- )
- }
- }
-
- private fun updateRepeatState() {
- when (MusicPlayerRemote.repeatMode) {
- MusicService.REPEAT_MODE_NONE -> {
- binding.repeatButton.setImageResource(R.drawable.ic_repeat)
- binding.repeatButton.setColorFilter(
- lastDisabledPlaybackControlsColor,
- PorterDuff.Mode.SRC_IN
- )
- }
-
- MusicService.REPEAT_MODE_ALL -> {
- binding.repeatButton.setImageResource(R.drawable.ic_repeat)
- binding.repeatButton.setColorFilter(
- lastPlaybackControlsColor,
- PorterDuff.Mode.SRC_IN
- )
- }
-
- MusicService.REPEAT_MODE_THIS -> {
- binding.repeatButton.setImageResource(R.drawable.ic_repeat_one)
- binding.repeatButton.setColorFilter(
- lastPlaybackControlsColor,
- PorterDuff.Mode.SRC_IN
- )
- }
- }
- }
-
- override fun onPlayingMetaChanged() {
- super.onPlayingMetaChanged()
- updateSong()
- updateFavorite()
- }
-
- override fun onFavoriteStateChanged() {
- super.onFavoriteStateChanged()
- updateFavorite()
- }
-
- private fun updateSong() {
- val song = MusicPlayerRemote.currentSong
-
- binding.songTitle.text = song.title
- binding.songText.text = song.artistName
-
- Glide.with(this)
- .load(RetroGlideExtension.getSongModel(song))
- .songCoverOptions(song)
- .transform(BlurTransformation.Builder(this).build())
- .into(binding.image)
- }
-
- override fun onUpdateProgressViews(progress: Int, total: Int) {
- binding.progressSlider.run {
- valueTo = total.toFloat()
- value = progress.toFloat().coerceIn(valueFrom, valueTo)
- }
-
- binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
- binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/ErrorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/ErrorActivity.kt
deleted file mode 100644
index 6823b80f8..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/ErrorActivity.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-package code.name.monkey.retromusic.activities
-
-import android.os.Bundle
-import android.widget.Button
-import android.widget.ImageView
-import androidx.appcompat.app.AppCompatActivity
-import cat.ereza.customactivityoncrash.CustomActivityOnCrash
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.util.FileUtils.createFile
-import code.name.monkey.retromusic.util.Share.shareFile
-import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import java.text.DateFormat
-import java.text.SimpleDateFormat
-import java.util.*
-
-class ErrorActivity : AppCompatActivity() {
- private val dayFormat: DateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
- private val reportPrefix = "bug_report-"
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(cat.ereza.customactivityoncrash.R.layout.customactivityoncrash_default_error_activity)
-
- val restartButton =
- findViewById(cat.ereza.customactivityoncrash.R.id.customactivityoncrash_error_activity_restart_button)
-
- val config = CustomActivityOnCrash.getConfigFromIntent(intent)
- if (config == null) {
- finish()
- return
- }
- restartButton.setText(cat.ereza.customactivityoncrash.R.string.customactivityoncrash_error_activity_restart_app)
- restartButton.setOnClickListener {
- CustomActivityOnCrash.restartApplication(
- this@ErrorActivity,
- config
- )
- }
- val moreInfoButton =
- findViewById(cat.ereza.customactivityoncrash.R.id.customactivityoncrash_error_activity_more_info_button)
-
- moreInfoButton.setOnClickListener { //We retrieve all the error data and show it
- MaterialAlertDialogBuilder(this@ErrorActivity)
- .setTitle(cat.ereza.customactivityoncrash.R.string.customactivityoncrash_error_activity_error_details_title)
- .setMessage(
- CustomActivityOnCrash.getAllErrorDetailsFromIntent(
- this@ErrorActivity,
- intent
- )
- )
- .setPositiveButton(
- cat.ereza.customactivityoncrash.R.string.customactivityoncrash_error_activity_error_details_close,
- null
- )
- .setNeutralButton(
- R.string.customactivityoncrash_error_activity_error_details_share
- ) { _, _ ->
-
- val bugReport = createFile(
- context = this,
- "Bug Report",
- "$reportPrefix${dayFormat.format(Date())}",
- CustomActivityOnCrash.getAllErrorDetailsFromIntent(
- this@ErrorActivity,
- intent
- ), ".txt"
- )
- shareFile(this, bugReport, "text/*")
- }
- .show()
- }
- val errorActivityDrawableId = config.errorDrawable
- val errorImageView =
- findViewById(cat.ereza.customactivityoncrash.R.id.customactivityoncrash_error_activity_image)
- if (errorActivityDrawableId != null) {
- errorImageView.setImageResource(
- errorActivityDrawableId
- )
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/LicenseActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/LicenseActivity.kt
deleted file mode 100644
index e41352dae..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/LicenseActivity.kt
+++ /dev/null
@@ -1,94 +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.activities
-
-import android.graphics.Color
-import android.os.Bundle
-import android.view.MenuItem
-import code.name.monkey.appthemehelper.util.ATHUtil.isWindowBackgroundDark
-import code.name.monkey.appthemehelper.util.ColorUtil.lightenColor
-import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
-import code.name.monkey.retromusic.activities.base.AbsThemeActivity
-import code.name.monkey.retromusic.databinding.ActivityLicenseBinding
-import code.name.monkey.retromusic.extensions.accentColor
-import code.name.monkey.retromusic.extensions.drawAboveSystemBars
-import code.name.monkey.retromusic.extensions.surfaceColor
-import java.io.BufferedReader
-import java.io.InputStreamReader
-import java.nio.charset.StandardCharsets
-
-/** Created by hemanths on 2019-09-27. */
-class LicenseActivity : AbsThemeActivity() {
- private lateinit var binding: ActivityLicenseBinding
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- binding = ActivityLicenseBinding.inflate(layoutInflater)
- setContentView(binding.root)
- setSupportActionBar(binding.toolbar)
- ToolbarContentTintHelper.colorBackButton(binding.toolbar)
- try {
- val buf = StringBuilder()
- val json = assets.open("license.html")
- BufferedReader(InputStreamReader(json, StandardCharsets.UTF_8)).use { br ->
- var str: String?
- while (br.readLine().also { str = it } != null) {
- buf.append(str)
- }
- }
-
- // Inject color values for WebView body background and links
- val isDark = isWindowBackgroundDark(this)
- val backgroundColor = colorToCSS(
- surfaceColor(Color.parseColor(if (isDark) "#424242" else "#ffffff"))
- )
- val contentColor = colorToCSS(Color.parseColor(if (isDark) "#ffffff" else "#000000"))
- val changeLog = buf.toString()
- .replace(
- "{style-placeholder}", String.format(
- "body { background-color: %s; color: %s; }", backgroundColor, contentColor
- )
- )
- .replace("{link-color}", colorToCSS(accentColor()))
- .replace(
- "{link-color-active}",
- colorToCSS(
- lightenColor(accentColor())
- )
- )
- binding.license.loadData(changeLog, "text/html", "UTF-8")
- } catch (e: Throwable) {
- binding.license.loadData(
- "Unable to load " + e.localizedMessage + "
", "text/html", "UTF-8"
- )
- }
- binding.license.drawAboveSystemBars()
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- if (item.itemId == android.R.id.home) {
- onBackPressedDispatcher.onBackPressed()
- return true
- }
- return super.onOptionsItemSelected(item)
- }
-
- private fun colorToCSS(color: Int): String {
- return String.format(
- "rgb(%d, %d, %d)",
- Color.red(color),
- Color.green(color),
- Color.blue(color)
- ) // on API 29, WebView doesn't load with hex colors
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/LockScreenActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/LockScreenActivity.kt
deleted file mode 100644
index 3ac219871..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/LockScreenActivity.kt
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.activities
-
-import android.app.KeyguardManager
-import android.os.Bundle
-import android.view.WindowManager
-import androidx.core.content.getSystemService
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
-import code.name.monkey.retromusic.databinding.ActivityLockScreenBinding
-import code.name.monkey.retromusic.extensions.hideStatusBar
-import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
-import code.name.monkey.retromusic.extensions.whichFragment
-import code.name.monkey.retromusic.fragments.player.lockscreen.LockScreenControlsFragment
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
-import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
-import code.name.monkey.retromusic.helper.MusicPlayerRemote
-import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
-import com.bumptech.glide.Glide
-import com.r0adkll.slidr.Slidr
-import com.r0adkll.slidr.model.SlidrConfig
-import com.r0adkll.slidr.model.SlidrListener
-import com.r0adkll.slidr.model.SlidrPosition
-
-class LockScreenActivity : AbsMusicServiceActivity() {
- private lateinit var binding: ActivityLockScreenBinding
- private var fragment: LockScreenControlsFragment? = null
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- lockScreenInit()
- binding = ActivityLockScreenBinding.inflate(layoutInflater)
- setContentView(binding.root)
- hideStatusBar()
- setTaskDescriptionColorAuto()
-
- val config = SlidrConfig.Builder().listener(object : SlidrListener {
- override fun onSlideStateChanged(state: Int) {
- }
-
- override fun onSlideChange(percent: Float) {
- }
-
- override fun onSlideOpened() {
- }
-
- override fun onSlideClosed(): Boolean {
- if (VersionUtils.hasOreo()) {
- val keyguardManager =
- getSystemService()
- keyguardManager?.requestDismissKeyguard(this@LockScreenActivity, null)
- }
- finish()
- return true
- }
- }).position(SlidrPosition.BOTTOM).build()
-
- Slidr.attach(this, config)
-
- fragment = whichFragment(R.id.playback_controls_fragment)
-
- binding.slide.apply {
- translationY = 100f
- alpha = 0f
- animate().translationY(0f).alpha(1f).setDuration(1500).start()
- }
- }
-
- @Suppress("Deprecation")
- private fun lockScreenInit() {
- if (VersionUtils.hasOreoMR1()) {
- setShowWhenLocked(true)
- //setTurnScreenOn(true)
- } else {
- window.addFlags(
- WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
- // or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
- )
- }
- }
-
- override fun onPlayingMetaChanged() {
- super.onPlayingMetaChanged()
- updateSongs()
- }
-
- override fun onServiceConnected() {
- super.onServiceConnected()
- updateSongs()
- }
-
- private fun updateSongs() {
- val song = MusicPlayerRemote.currentSong
- Glide.with(this)
- .asBitmapPalette()
- .songCoverOptions(song)
- .load(RetroGlideExtension.getSongModel(song))
- .dontAnimate()
- .into(object : RetroMusicColoredTarget(binding.image) {
- override fun onColorReady(colors: MediaNotificationProcessor) {
- fragment?.setColor(colors)
- }
- })
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt
deleted file mode 100644
index e9cb29abe..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.activities
-
-import android.content.Intent
-import android.net.Uri
-import android.os.Bundle
-import android.provider.MediaStore
-import androidx.lifecycle.lifecycleScope
-import androidx.navigation.contains
-import androidx.navigation.ui.setupWithNavController
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
-import code.name.monkey.retromusic.extensions.*
-import code.name.monkey.retromusic.helper.MusicPlayerRemote
-import code.name.monkey.retromusic.helper.SearchQueryHelper.getSongs
-import code.name.monkey.retromusic.interfaces.IScrollHelper
-import code.name.monkey.retromusic.model.CategoryInfo
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.repository.PlaylistSongsLoader
-import code.name.monkey.retromusic.service.MusicService
-import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.logE
-import kotlinx.coroutines.Dispatchers.IO
-import kotlinx.coroutines.launch
-import org.koin.android.ext.android.get
-
-class MainActivity : AbsSlidingMusicPanelActivity() {
- companion object {
- const val TAG = "MainActivity"
- const val EXPAND_PANEL = "expand_panel"
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setTaskDescriptionColorAuto()
- hideStatusBar()
- updateTabs()
-
- setupNavigationController()
-
- WhatsNewFragment.showChangeLog(this)
- }
-
- private fun setupNavigationController() {
- val navController = findNavController(R.id.fragment_container)
- val navInflater = navController.navInflater
- val navGraph = navInflater.inflate(R.navigation.main_graph)
-
- val categoryInfo: CategoryInfo = PreferenceUtil.libraryCategory.first { it.visible }
- if (categoryInfo.visible) {
- if (!navGraph.contains(PreferenceUtil.lastTab)) PreferenceUtil.lastTab =
- categoryInfo.category.id
- navGraph.setStartDestination(
- if (PreferenceUtil.rememberLastTab) {
- PreferenceUtil.lastTab.let {
- if (it == 0) {
- categoryInfo.category.id
- } else {
- it
- }
- }
- } else categoryInfo.category.id
- )
- }
- navController.graph = navGraph
- navigationView.setupWithNavController(navController)
- // Scroll Fragment to top
- navigationView.setOnItemReselectedListener {
- currentFragment(R.id.fragment_container).apply {
- if (this is IScrollHelper) {
- scrollToTop()
- }
- }
- }
- navController.addOnDestinationChangedListener { _, destination, _ ->
- if (destination.id == navGraph.startDestinationId) {
- currentFragment(R.id.fragment_container)?.enterTransition = null
- }
- when (destination.id) {
- R.id.action_home, R.id.action_song, R.id.action_album, R.id.action_artist, R.id.action_folder, R.id.action_playlist, R.id.action_genre, R.id.action_search -> {
- // Save the last tab
- if (PreferenceUtil.rememberLastTab) {
- saveTab(destination.id)
- }
- // Show Bottom Navigation Bar
- setBottomNavVisibility(visible = true, animate = true)
- }
- R.id.playing_queue_fragment -> {
- setBottomNavVisibility(visible = false, hideBottomSheet = true)
- }
- else -> setBottomNavVisibility(
- visible = false,
- animate = true
- ) // Hide Bottom Navigation Bar
- }
- }
- }
-
- private fun saveTab(id: Int) {
- if (PreferenceUtil.libraryCategory.firstOrNull { it.category.id == id }?.visible == true) {
- PreferenceUtil.lastTab = id
- }
- }
-
- override fun onSupportNavigateUp(): Boolean =
- findNavController(R.id.fragment_container).navigateUp()
-
- override fun onNewIntent(intent: Intent?) {
- super.onNewIntent(intent)
- val expand = intent?.extra(EXPAND_PANEL)?.value ?: false
- if (expand && PreferenceUtil.isExpandPanel) {
- fromNotification = true
- slidingPanel.bringToFront()
- expandPanel()
- intent?.removeExtra(EXPAND_PANEL)
- }
- }
-
- override fun onServiceConnected() {
- super.onServiceConnected()
- intent ?: return
- handlePlaybackIntent(intent)
- }
-
- private fun handlePlaybackIntent(intent: Intent) {
- lifecycleScope.launch(IO) {
- val uri: Uri? = intent.data
- val mimeType: String? = intent.type
- var handled = false
- if (intent.action != null &&
- intent.action == MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
- ) {
- val songs: List = getSongs(intent.extras!!)
- if (MusicPlayerRemote.shuffleMode == MusicService.SHUFFLE_MODE_SHUFFLE) {
- MusicPlayerRemote.openAndShuffleQueue(songs, true)
- } else {
- MusicPlayerRemote.openQueue(songs, 0, true)
- }
- handled = true
- }
- if (uri != null && uri.toString().isNotEmpty()) {
- MusicPlayerRemote.playFromUri(this@MainActivity, uri)
- handled = true
- } else if (MediaStore.Audio.Playlists.CONTENT_TYPE == mimeType) {
- val id = parseLongFromIntent(intent, "playlistId", "playlist")
- if (id >= 0L) {
- val position: Int = intent.getIntExtra("position", 0)
- val songs: List = PlaylistSongsLoader.getPlaylistSongList(get(), id)
- MusicPlayerRemote.openQueue(songs, position, true)
- handled = true
- }
- } else if (MediaStore.Audio.Albums.CONTENT_TYPE == mimeType) {
- val id = parseLongFromIntent(intent, "albumId", "album")
- if (id >= 0L) {
- val position: Int = intent.getIntExtra("position", 0)
- val songs = libraryViewModel.albumById(id).songs
- MusicPlayerRemote.openQueue(
- songs,
- position,
- true
- )
- handled = true
- }
- } else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) {
- val id = parseLongFromIntent(intent, "artistId", "artist")
- if (id >= 0L) {
- val position: Int = intent.getIntExtra("position", 0)
- val songs: List = libraryViewModel.artistById(id).songs
- MusicPlayerRemote.openQueue(
- songs,
- position,
- true
- )
- handled = true
- }
- }
- if (handled) {
- setIntent(Intent())
- }
- }
- }
-
- private fun parseLongFromIntent(
- intent: Intent,
- longKey: String,
- stringKey: String,
- ): Long {
- var id = intent.getLongExtra(longKey, -1)
- if (id < 0) {
- val idString = intent.getStringExtra(stringKey)
- if (idString != null) {
- try {
- id = idString.toLong()
- } catch (e: NumberFormatException) {
- logE(e)
- }
- }
- }
- return id
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/PermissionActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/PermissionActivity.kt
deleted file mode 100644
index 5cb64cf93..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/PermissionActivity.kt
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.activities
-
-import android.Manifest.permission.BLUETOOTH_CONNECT
-import android.content.Intent
-import android.content.pm.PackageManager
-import android.content.res.ColorStateList
-import android.os.Build
-import android.os.Bundle
-import android.provider.Settings
-import androidx.activity.OnBackPressedCallback
-import androidx.annotation.RequiresApi
-import androidx.core.app.ActivityCompat
-import androidx.core.net.toUri
-import androidx.core.text.parseAsHtml
-import androidx.core.view.isVisible
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
-import code.name.monkey.retromusic.databinding.ActivityPermissionBinding
-import code.name.monkey.retromusic.extensions.*
-
-class PermissionActivity : AbsMusicServiceActivity() {
- private lateinit var binding: ActivityPermissionBinding
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- binding = ActivityPermissionBinding.inflate(layoutInflater)
- setContentView(binding.root)
- setStatusBarColorAuto()
- setTaskDescriptionColorAuto()
- setupTitle()
-
- binding.storagePermission.setButtonClick {
- requestPermissions()
- }
- if (VersionUtils.hasMarshmallow()) {
- binding.audioPermission.show()
- binding.audioPermission.setButtonClick {
- if (!hasAudioPermission()) {
- val intent = Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS)
- intent.data = ("package:" + applicationContext.packageName).toUri()
- startActivity(intent)
- }
- }
- }
-
- if (VersionUtils.hasS()) {
- binding.bluetoothPermission.show()
- binding.bluetoothPermission.setButtonClick {
- ActivityCompat.requestPermissions(
- this,
- arrayOf(BLUETOOTH_CONNECT),
- BLUETOOTH_PERMISSION_REQUEST
- )
- }
- } else {
- binding.audioPermission.setNumber("2")
- }
-
- binding.finish.accentBackgroundColor()
- binding.finish.setOnClickListener {
- if (hasPermissions()) {
- startActivity(
- Intent(this, MainActivity::class.java).addFlags(
- Intent.FLAG_ACTIVITY_NEW_TASK or
- Intent.FLAG_ACTIVITY_CLEAR_TASK
- )
- )
- finish()
- }
- }
- onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
- override fun handleOnBackPressed() {
- finishAffinity()
- remove()
- }
- })
- }
-
- private fun setupTitle() {
- val appName =
- getString(
- R.string.message_welcome,
- "Metro "
- )
- .parseAsHtml()
- binding.appNameText.text = appName
- }
-
- override fun onResume() {
- super.onResume()
- binding.finish.isEnabled = hasStoragePermission()
- if (hasStoragePermission()) {
- binding.storagePermission.checkImage.isVisible = true
- binding.storagePermission.checkImage.imageTintList =
- ColorStateList.valueOf(accentColor())
- }
- if (VersionUtils.hasMarshmallow()) {
- if (hasAudioPermission()) {
- binding.audioPermission.checkImage.isVisible = true
- binding.audioPermission.checkImage.imageTintList =
- ColorStateList.valueOf(accentColor())
- }
- }
- if (VersionUtils.hasS()) {
- if (hasBluetoothPermission()) {
- binding.bluetoothPermission.checkImage.isVisible = true
- binding.bluetoothPermission.checkImage.imageTintList =
- ColorStateList.valueOf(accentColor())
- }
- }
- }
-
- private fun hasStoragePermission(): Boolean {
- return hasPermissions()
- }
-
- @RequiresApi(Build.VERSION_CODES.S)
- private fun hasBluetoothPermission(): Boolean {
- return ActivityCompat.checkSelfPermission(
- this,
- BLUETOOTH_CONNECT
- ) == PackageManager.PERMISSION_GRANTED
- }
-
- @RequiresApi(Build.VERSION_CODES.M)
- private fun hasAudioPermission(): Boolean {
- return Settings.System.canWrite(this)
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/ShareInstagramStory.kt b/app/src/main/java/code/name/monkey/retromusic/activities/ShareInstagramStory.kt
deleted file mode 100644
index 546c9d794..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/ShareInstagramStory.kt
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.activities
-
-import android.content.res.ColorStateList
-import android.graphics.Bitmap
-import android.graphics.Color
-import android.graphics.drawable.GradientDrawable
-import android.os.Bundle
-import android.provider.MediaStore.Images.Media
-import android.view.MenuItem
-import androidx.core.net.toUri
-import androidx.core.os.BundleCompat
-import androidx.core.view.drawToBitmap
-import code.name.monkey.appthemehelper.util.ColorUtil
-import code.name.monkey.appthemehelper.util.MaterialValueHelper
-import code.name.monkey.retromusic.activities.base.AbsThemeActivity
-import code.name.monkey.retromusic.databinding.ActivityShareInstagramBinding
-import code.name.monkey.retromusic.extensions.accentColor
-import code.name.monkey.retromusic.extensions.setStatusBarColor
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
-import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.util.Share
-import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
-import com.bumptech.glide.Glide
-
-/**
- * Created by hemanths on 2020-02-02.
- */
-
-class ShareInstagramStory : AbsThemeActivity() {
-
- private lateinit var binding: ActivityShareInstagramBinding
-
- companion object {
- const val EXTRA_SONG = "extra_song"
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- if (item.itemId == android.R.id.home) {
- onBackPressedDispatcher.onBackPressed()
- return true
- }
- return super.onOptionsItemSelected(item)
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- binding = ActivityShareInstagramBinding.inflate(layoutInflater)
- setContentView(binding.root)
- setStatusBarColor(Color.TRANSPARENT)
-
- binding.toolbar.setBackgroundColor(Color.TRANSPARENT)
- setSupportActionBar(binding.toolbar)
-
- val song = intent.extras?.let { BundleCompat.getParcelable(it, EXTRA_SONG, Song::class.java) }
- song?.let { songFinal ->
- Glide.with(this)
- .asBitmapPalette()
- .songCoverOptions(songFinal)
- .load(RetroGlideExtension.getSongModel(songFinal))
- .into(object : RetroMusicColoredTarget(binding.image) {
- override fun onColorReady(colors: MediaNotificationProcessor) {
- setColors(colors.backgroundColor)
- }
- })
-
- binding.shareTitle.text = songFinal.title
- binding.shareText.text = songFinal.artistName
- binding.shareButton.setOnClickListener {
- val path: String = Media.insertImage(
- contentResolver,
- binding.mainContent.drawToBitmap(Bitmap.Config.ARGB_8888),
- "Design", null
- )
- Share.shareStoryToSocial(
- this@ShareInstagramStory,
- path.toUri()
- )
- }
- }
- binding.shareButton.setTextColor(
- MaterialValueHelper.getPrimaryTextColor(
- this,
- ColorUtil.isColorLight(accentColor())
- )
- )
- binding.shareButton.backgroundTintList =
- ColorStateList.valueOf(accentColor())
- }
-
- private fun setColors(color: Int) {
- binding.mainContent.background =
- GradientDrawable(
- GradientDrawable.Orientation.TOP_BOTTOM,
- intArrayOf(color, Color.BLACK)
- )
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/WhatsNewFragment.kt b/app/src/main/java/code/name/monkey/retromusic/activities/WhatsNewFragment.kt
deleted file mode 100644
index 48b39ed35..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/WhatsNewFragment.kt
+++ /dev/null
@@ -1,153 +0,0 @@
-package code.name.monkey.retromusic.activities
-
-import android.content.Context
-import android.content.Intent
-import android.content.pm.PackageManager
-import android.graphics.Color
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.webkit.WebResourceRequest
-import android.webkit.WebView
-import android.webkit.WebViewClient
-import androidx.core.content.pm.PackageInfoCompat
-import androidx.core.widget.NestedScrollView
-import androidx.fragment.app.FragmentActivity
-import code.name.monkey.appthemehelper.util.ATHUtil.isWindowBackgroundDark
-import code.name.monkey.appthemehelper.util.ColorUtil.isColorLight
-import code.name.monkey.appthemehelper.util.ColorUtil.lightenColor
-import code.name.monkey.appthemehelper.util.MaterialValueHelper.getPrimaryTextColor
-import code.name.monkey.retromusic.BuildConfig
-import code.name.monkey.retromusic.Constants
-import code.name.monkey.retromusic.databinding.FragmentWhatsNewBinding
-import code.name.monkey.retromusic.extensions.accentColor
-import code.name.monkey.retromusic.extensions.openUrl
-import code.name.monkey.retromusic.util.PreferenceUtil.lastVersion
-import com.google.android.material.bottomsheet.BottomSheetDialogFragment
-import java.nio.charset.StandardCharsets
-import java.util.*
-
-class WhatsNewFragment : BottomSheetDialogFragment() {
- private var _binding: FragmentWhatsNewBinding? = null
- val binding get() = _binding!!
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- _binding = FragmentWhatsNewBinding.inflate(inflater, container, false)
- return binding.root
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- try {
- val buf = StringBuilder()
- val stream = requireContext().assets.open("retro-changelog.html")
- stream.reader(StandardCharsets.UTF_8).buffered().use { br ->
- var str: String?
- while (br.readLine().also { str = it } != null) {
- buf.append(str)
- }
- }
-
- // Inject color values for WebView body background and links
- val isDark = isWindowBackgroundDark(requireContext())
- val accentColor = accentColor()
- binding.webView.setBackgroundColor(0)
- val contentColor = colorToCSS(Color.parseColor(if (isDark) "#ffffff" else "#000000"))
- val textColor = colorToCSS(Color.parseColor(if (isDark) "#60FFFFFF" else "#80000000"))
- val accentColorString = colorToCSS(accentColor())
- val cardBackgroundColor =
- colorToCSS(Color.parseColor(if (isDark) "#353535" else "#ffffff"))
- val accentTextColor = colorToCSS(
- getPrimaryTextColor(
- requireContext(), isColorLight(accentColor)
- )
- )
- val changeLog = buf.toString()
- .replace(
- "{style-placeholder}",
- "body { color: $contentColor; } li {color: $textColor;} h3 {color: $accentColorString;} .tag {background-color: $accentColorString; color: $accentTextColor; } div{background-color: $cardBackgroundColor;}"
- )
- .replace("{link-color}", colorToCSS(accentColor()))
- .replace(
- "{link-color-active}",
- colorToCSS(
- lightenColor(accentColor())
- )
- )
- binding.webView.loadData(changeLog, "text/html", "UTF-8")
- binding.webView.webViewClient = object : WebViewClient() {
- override fun shouldOverrideUrlLoading(
- view: WebView?,
- request: WebResourceRequest?
- ): Boolean {
- val url = request?.url ?: return false
- //you can do checks here e.g. url.host equals to target one
- startActivity(Intent(Intent.ACTION_VIEW, url))
- return true
- }
- }
- } catch (e: Throwable) {
- binding.webView.loadData(
- "Unable to load " + e.localizedMessage + "
", "text/html", "UTF-8"
- )
- }
- setChangelogRead(requireContext())
- binding.tgFab.setOnClickListener {
- openUrl(Constants.TELEGRAM_CHANGE_LOG)
- }
- binding.tgFab.accentColor()
- binding.tgFab.shrink()
- binding.container.setOnScrollChangeListener { _: NestedScrollView?, _: Int, scrollY: Int, _: Int, oldScrollY: Int ->
- val dy = scrollY - oldScrollY
- if (dy > 0) {
- binding.tgFab.shrink()
- } else if (dy < 0) {
- binding.tgFab.extend()
- }
- }
- }
-
- override fun onDestroy() {
- super.onDestroy()
- _binding = null
- }
-
- companion object {
-
- const val TAG = "WhatsNewFragment"
- private fun colorToCSS(color: Int): String {
- return String.format(
- Locale.getDefault(),
- "rgba(%d, %d, %d, %d)",
- Color.red(color),
- Color.green(color),
- Color.blue(color),
- Color.alpha(color)
- ) // on API 29, WebView doesn't load with hex colors
- }
-
- private fun setChangelogRead(context: Context) {
- try {
- val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
- val currentVersion = PackageInfoCompat.getLongVersionCode(pInfo)
- lastVersion = currentVersion
- } catch (e: PackageManager.NameNotFoundException) {
- e.printStackTrace()
- }
- }
-
- fun showChangeLog(activity: FragmentActivity) {
- val pInfo = activity.packageManager.getPackageInfo(activity.packageName, 0)
- val currentVersion = PackageInfoCompat.getLongVersionCode(pInfo)
- if (currentVersion > lastVersion && !BuildConfig.DEBUG) {
- val changelogBottomSheet = WhatsNewFragment()
- changelogBottomSheet.show(activity.supportFragmentManager, TAG)
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsBaseActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsBaseActivity.kt
deleted file mode 100644
index 1e0c110d5..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsBaseActivity.kt
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.activities.base
-
-import android.Manifest
-import android.content.Intent
-import android.content.pm.PackageManager
-import android.graphics.Rect
-import android.media.AudioManager
-import android.net.Uri
-import android.os.Bundle
-import android.provider.Settings
-import android.view.KeyEvent
-import android.view.MotionEvent
-import android.view.View
-import android.view.inputmethod.InputMethodManager
-import android.widget.EditText
-import androidx.core.app.ActivityCompat
-import androidx.core.content.getSystemService
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.extensions.accentColor
-import code.name.monkey.retromusic.extensions.rootView
-import code.name.monkey.retromusic.util.logD
-import com.google.android.material.snackbar.Snackbar
-
-abstract class AbsBaseActivity : AbsThemeActivity() {
- private var hadPermissions: Boolean = false
- private lateinit var permissions: Array
- private var permissionDeniedMessage: String? = null
-
- open fun getPermissionsToRequest(): Array {
- return arrayOf()
- }
-
- protected fun setPermissionDeniedMessage(message: String) {
- permissionDeniedMessage = message
- }
-
- fun getPermissionDeniedMessage(): String {
- return if (permissionDeniedMessage == null) getString(R.string.permissions_denied) else permissionDeniedMessage!!
- }
-
- private val snackBarContainer: View
- get() = rootView
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- volumeControlStream = AudioManager.STREAM_MUSIC
- permissions = getPermissionsToRequest()
- hadPermissions = hasPermissions()
- permissionDeniedMessage = null
- }
-
- override fun onResume() {
- super.onResume()
- val hasPermissions = hasPermissions()
- if (hasPermissions != hadPermissions) {
- hadPermissions = hasPermissions
- if (VersionUtils.hasMarshmallow()) {
- onHasPermissionsChanged(hasPermissions)
- }
- }
- }
-
- protected open fun onHasPermissionsChanged(hasPermissions: Boolean) {
- // implemented by sub classes
- logD(hasPermissions)
- }
-
- override fun dispatchKeyEvent(event: KeyEvent): Boolean {
- if (event.keyCode == KeyEvent.KEYCODE_MENU && event.action == KeyEvent.ACTION_UP) {
- showOverflowMenu()
- return true
- }
- return super.dispatchKeyEvent(event)
- }
-
- private fun showOverflowMenu() {
- }
-
- protected open fun requestPermissions() {
- ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST)
- }
-
- protected fun hasPermissions(): Boolean {
- for (permission in permissions) {
- if (ActivityCompat.checkSelfPermission(this,
- permission) != PackageManager.PERMISSION_GRANTED
- ) {
- return false
- }
- }
- return true
- }
-
- override fun onRequestPermissionsResult(
- requestCode: Int,
- permissions: Array,
- grantResults: IntArray,
- ) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults)
- if (requestCode == PERMISSION_REQUEST) {
- for (grantResult in grantResults) {
- if (grantResult != PackageManager.PERMISSION_GRANTED) {
- if (ActivityCompat.shouldShowRequestPermissionRationale(
- this@AbsBaseActivity, Manifest.permission.READ_EXTERNAL_STORAGE,
- ) || ActivityCompat.shouldShowRequestPermissionRationale(
- this@AbsBaseActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE,
- )
- ) {
- // User has deny from permission dialog
- Snackbar.make(
- snackBarContainer,
- permissionDeniedMessage!!,
- Snackbar.LENGTH_SHORT
- )
- .setAction(R.string.action_grant) { requestPermissions() }
- .setActionTextColor(accentColor()).show()
- } else {
- // User has deny permission and checked never show permission dialog so you can redirect to Application settings page
- Snackbar.make(
- snackBarContainer,
- permissionDeniedMessage!!,
- Snackbar.LENGTH_INDEFINITE
- )
- .setAction(R.string.action_settings) {
- val intent = Intent()
- intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
- val uri = Uri.fromParts(
- "package",
- this@AbsBaseActivity.packageName,
- null
- )
- intent.data = uri
- startActivity(intent)
- }.setActionTextColor(accentColor()).show()
- }
- return
- }
- }
- hadPermissions = true
- onHasPermissionsChanged(true)
- } else if (requestCode == BLUETOOTH_PERMISSION_REQUEST) {
- for (grantResult in grantResults) {
- if (grantResult != PackageManager.PERMISSION_GRANTED) {
- if (ActivityCompat.shouldShowRequestPermissionRationale(
- this@AbsBaseActivity, Manifest.permission.BLUETOOTH_CONNECT
- )
- ) {
- // User has deny from permission dialog
- Snackbar.make(
- snackBarContainer,
- R.string.permission_bluetooth_denied,
- Snackbar.LENGTH_SHORT
- )
- .setAction(R.string.action_grant) {
- ActivityCompat.requestPermissions(this,
- arrayOf(Manifest.permission.BLUETOOTH_CONNECT),
- BLUETOOTH_PERMISSION_REQUEST)
- }
- .setActionTextColor(accentColor()).show()
- }
- }
- }
- }
- }
-
- companion object {
- const val PERMISSION_REQUEST = 100
- const val BLUETOOTH_PERMISSION_REQUEST = 101
- }
-
- // this lets keyboard close when clicked in background
- override fun dispatchTouchEvent(event: MotionEvent): Boolean {
- if (event.action == MotionEvent.ACTION_DOWN) {
- val v = currentFocus
- if (v is EditText) {
- val outRect = Rect()
- v.getGlobalVisibleRect(outRect)
- if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) {
- v.clearFocus()
- getSystemService()?.hideSoftInputFromWindow(
- v.windowToken,
- 0
- )
- }
- }
- }
- return super.dispatchTouchEvent(event)
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsMusicServiceActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsMusicServiceActivity.kt
deleted file mode 100644
index f9f05c919..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsMusicServiceActivity.kt
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.activities.base
-
-import android.Manifest
-import android.content.*
-import android.os.Bundle
-import android.os.IBinder
-import androidx.core.content.ContextCompat
-import androidx.lifecycle.lifecycleScope
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.db.toPlayCount
-import code.name.monkey.retromusic.helper.MusicPlayerRemote
-import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener
-import code.name.monkey.retromusic.repository.RealRepository
-import code.name.monkey.retromusic.service.MusicService.Companion.FAVORITE_STATE_CHANGED
-import code.name.monkey.retromusic.service.MusicService.Companion.MEDIA_STORE_CHANGED
-import code.name.monkey.retromusic.service.MusicService.Companion.META_CHANGED
-import code.name.monkey.retromusic.service.MusicService.Companion.PLAY_STATE_CHANGED
-import code.name.monkey.retromusic.service.MusicService.Companion.QUEUE_CHANGED
-import code.name.monkey.retromusic.service.MusicService.Companion.REPEAT_MODE_CHANGED
-import code.name.monkey.retromusic.service.MusicService.Companion.SHUFFLE_MODE_CHANGED
-import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.logD
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import org.koin.android.ext.android.inject
-import java.lang.ref.WeakReference
-
-abstract class AbsMusicServiceActivity : AbsBaseActivity(), IMusicServiceEventListener {
-
- private val mMusicServiceEventListeners = ArrayList()
- private val repository: RealRepository by inject()
- private var serviceToken: MusicPlayerRemote.ServiceToken? = null
- private var musicStateReceiver: MusicStateReceiver? = null
- private var receiverRegistered: Boolean = false
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- serviceToken = MusicPlayerRemote.bindToService(this, object : ServiceConnection {
- override fun onServiceConnected(name: ComponentName, service: IBinder) {
- this@AbsMusicServiceActivity.onServiceConnected()
- }
-
- override fun onServiceDisconnected(name: ComponentName) {
- this@AbsMusicServiceActivity.onServiceDisconnected()
- }
- })
-
- setPermissionDeniedMessage(getString(R.string.permission_external_storage_denied))
- }
-
- override fun onDestroy() {
- super.onDestroy()
- MusicPlayerRemote.unbindFromService(serviceToken)
- if (receiverRegistered) {
- unregisterReceiver(musicStateReceiver)
- receiverRegistered = false
- }
- }
-
- fun addMusicServiceEventListener(listenerI: IMusicServiceEventListener?) {
- if (listenerI != null) {
- mMusicServiceEventListeners.add(listenerI)
- }
- }
-
- fun removeMusicServiceEventListener(listenerI: IMusicServiceEventListener?) {
- if (listenerI != null) {
- mMusicServiceEventListeners.remove(listenerI)
- }
- }
-
- override fun onServiceConnected() {
- if (!receiverRegistered) {
- musicStateReceiver = MusicStateReceiver(this)
-
- val filter = IntentFilter()
- filter.addAction(PLAY_STATE_CHANGED)
- filter.addAction(SHUFFLE_MODE_CHANGED)
- filter.addAction(REPEAT_MODE_CHANGED)
- filter.addAction(META_CHANGED)
- filter.addAction(QUEUE_CHANGED)
- filter.addAction(MEDIA_STORE_CHANGED)
- filter.addAction(FAVORITE_STATE_CHANGED)
-
- ContextCompat.registerReceiver(this, musicStateReceiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED)
- receiverRegistered = true
- }
-
- for (listener in mMusicServiceEventListeners) {
- listener.onServiceConnected()
- }
- }
-
- override fun onServiceDisconnected() {
- if (receiverRegistered) {
- unregisterReceiver(musicStateReceiver)
- receiverRegistered = false
- }
-
- for (listener in mMusicServiceEventListeners) {
- listener.onServiceDisconnected()
- }
- }
-
- override fun onPlayingMetaChanged() {
- for (listener in mMusicServiceEventListeners) {
- listener.onPlayingMetaChanged()
- }
- lifecycleScope.launch(Dispatchers.IO) {
- if (!PreferenceUtil.pauseHistory) {
- repository.upsertSongInHistory(MusicPlayerRemote.currentSong)
- }
- val song = repository.findSongExistInPlayCount(MusicPlayerRemote.currentSong.id)
- ?.apply { playCount += 1 }
- ?: MusicPlayerRemote.currentSong.toPlayCount()
-
- repository.upsertSongInPlayCount(song)
- }
- }
-
- override fun onQueueChanged() {
- for (listener in mMusicServiceEventListeners) {
- listener.onQueueChanged()
- }
- }
-
- override fun onPlayStateChanged() {
- for (listener in mMusicServiceEventListeners) {
- listener.onPlayStateChanged()
- }
- }
-
- override fun onMediaStoreChanged() {
- for (listener in mMusicServiceEventListeners) {
- listener.onMediaStoreChanged()
- }
- }
-
- override fun onRepeatModeChanged() {
- for (listener in mMusicServiceEventListeners) {
- listener.onRepeatModeChanged()
- }
- }
-
- override fun onShuffleModeChanged() {
- for (listener in mMusicServiceEventListeners) {
- listener.onShuffleModeChanged()
- }
- }
-
- override fun onFavoriteStateChanged() {
- for (listener in mMusicServiceEventListeners) {
- listener.onFavoriteStateChanged()
- }
- }
-
- override fun onHasPermissionsChanged(hasPermissions: Boolean) {
- super.onHasPermissionsChanged(hasPermissions)
- val intent = Intent(MEDIA_STORE_CHANGED)
- intent.putExtra(
- "from_permissions_changed",
- true
- ) // just in case we need to know this at some point
- sendBroadcast(intent)
- logD("sendBroadcast $hasPermissions")
- }
-
- override fun getPermissionsToRequest(): Array {
- return mutableListOf().apply {
- if (VersionUtils.hasT()) {
- add(Manifest.permission.READ_MEDIA_AUDIO)
- add(Manifest.permission.POST_NOTIFICATIONS)
- } else {
- add(Manifest.permission.READ_EXTERNAL_STORAGE)
- }
- if (!VersionUtils.hasR()) {
- add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
- }
- }.toTypedArray()
- }
-
- private class MusicStateReceiver(activity: AbsMusicServiceActivity) : BroadcastReceiver() {
-
- private val reference: WeakReference = WeakReference(activity)
-
- override fun onReceive(context: Context, intent: Intent) {
- val action = intent.action
- val activity = reference.get()
- if (activity != null && action != null) {
- when (action) {
- FAVORITE_STATE_CHANGED -> activity.onFavoriteStateChanged()
- META_CHANGED -> activity.onPlayingMetaChanged()
- QUEUE_CHANGED -> activity.onQueueChanged()
- PLAY_STATE_CHANGED -> activity.onPlayStateChanged()
- REPEAT_MODE_CHANGED -> activity.onRepeatModeChanged()
- SHUFFLE_MODE_CHANGED -> activity.onShuffleModeChanged()
- MEDIA_STORE_CHANGED -> activity.onMediaStoreChanged()
- }
- }
- }
- }
-
- companion object {
- val TAG: String = AbsMusicServiceActivity::class.java.simpleName
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt
deleted file mode 100644
index 2a81ca9b4..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.activities.base
-
-import android.animation.ArgbEvaluator
-import android.animation.ValueAnimator
-import android.content.Intent
-import android.content.SharedPreferences
-import android.content.res.ColorStateList
-import android.graphics.Color
-import android.os.Bundle
-import android.view.View
-import android.view.ViewGroup
-import android.view.ViewTreeObserver
-import android.view.animation.PathInterpolator
-import android.widget.FrameLayout
-import androidx.activity.OnBackPressedCallback
-import androidx.core.animation.doOnEnd
-import androidx.core.view.*
-import androidx.fragment.app.commit
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.ADAPTIVE_COLOR_APP
-import code.name.monkey.retromusic.ALBUM_COVER_STYLE
-import code.name.monkey.retromusic.ALBUM_COVER_TRANSFORM
-import code.name.monkey.retromusic.CAROUSEL_EFFECT
-import code.name.monkey.retromusic.CIRCLE_PLAY_BUTTON
-import code.name.monkey.retromusic.EXTRA_SONG_INFO
-import code.name.monkey.retromusic.KEEP_SCREEN_ON
-import code.name.monkey.retromusic.LIBRARY_CATEGORIES
-import code.name.monkey.retromusic.NOW_PLAYING_SCREEN_ID
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.SCREEN_ON_LYRICS
-import code.name.monkey.retromusic.SWIPE_ANYWHERE_NOW_PLAYING
-import code.name.monkey.retromusic.SWIPE_DOWN_DISMISS
-import code.name.monkey.retromusic.TAB_TEXT_MODE
-import code.name.monkey.retromusic.TOGGLE_ADD_CONTROLS
-import code.name.monkey.retromusic.TOGGLE_FULL_SCREEN
-import code.name.monkey.retromusic.TOGGLE_VOLUME
-import code.name.monkey.retromusic.activities.PermissionActivity
-import code.name.monkey.retromusic.databinding.SlidingMusicPanelLayoutBinding
-import code.name.monkey.retromusic.extensions.*
-import code.name.monkey.retromusic.fragments.LibraryViewModel
-import code.name.monkey.retromusic.fragments.NowPlayingScreen
-import code.name.monkey.retromusic.fragments.NowPlayingScreen.*
-import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
-import code.name.monkey.retromusic.fragments.other.MiniPlayerFragment
-import code.name.monkey.retromusic.fragments.player.adaptive.AdaptiveFragment
-import code.name.monkey.retromusic.fragments.player.blur.BlurPlayerFragment
-import code.name.monkey.retromusic.fragments.player.card.CardFragment
-import code.name.monkey.retromusic.fragments.player.cardblur.CardBlurFragment
-import code.name.monkey.retromusic.fragments.player.circle.CirclePlayerFragment
-import code.name.monkey.retromusic.fragments.player.classic.ClassicPlayerFragment
-import code.name.monkey.retromusic.fragments.player.color.ColorFragment
-import code.name.monkey.retromusic.fragments.player.fit.FitFragment
-import code.name.monkey.retromusic.fragments.player.flat.FlatPlayerFragment
-import code.name.monkey.retromusic.fragments.player.full.FullPlayerFragment
-import code.name.monkey.retromusic.fragments.player.gradient.GradientPlayerFragment
-import code.name.monkey.retromusic.fragments.player.material.MaterialFragment
-import code.name.monkey.retromusic.fragments.player.md3.MD3PlayerFragment
-import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment
-import code.name.monkey.retromusic.fragments.player.peek.PeekPlayerFragment
-import code.name.monkey.retromusic.fragments.player.plain.PlainPlayerFragment
-import code.name.monkey.retromusic.fragments.player.simple.SimplePlayerFragment
-import code.name.monkey.retromusic.fragments.player.tiny.TinyPlayerFragment
-import code.name.monkey.retromusic.fragments.queue.PlayingQueueFragment
-import code.name.monkey.retromusic.helper.MusicPlayerRemote
-import code.name.monkey.retromusic.model.CategoryInfo
-import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.ViewUtil
-import code.name.monkey.retromusic.util.logD
-import com.google.android.material.bottomnavigation.BottomNavigationView
-import com.google.android.material.bottomsheet.BottomSheetBehavior
-import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback
-import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_COLLAPSED
-import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_DRAGGING
-import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED
-import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HIDDEN
-import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_SETTLING
-import com.google.android.material.bottomsheet.BottomSheetBehavior.from
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-
-abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(),
- SharedPreferences.OnSharedPreferenceChangeListener {
- companion object {
- val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName
- }
-
- var fromNotification = false
- private var windowInsets: WindowInsetsCompat? = null
- protected val libraryViewModel by viewModel()
- private lateinit var bottomSheetBehavior: BottomSheetBehavior
- private lateinit var playerFragment: AbsPlayerFragment
- private var miniPlayerFragment: MiniPlayerFragment? = null
- private var nowPlayingScreen: NowPlayingScreen? = null
- private var taskColor: Int = 0
- private var paletteColor: Int = Color.WHITE
- private var navigationBarColor = 0
-
- private val panelState: Int
- get() = bottomSheetBehavior.state
- private lateinit var binding: SlidingMusicPanelLayoutBinding
- private var isInOneTabMode = false
-
- private var navigationBarColorAnimator: ValueAnimator? = null
- private val argbEvaluator: ArgbEvaluator = ArgbEvaluator()
-
- private val onBackPressedCallback = object : OnBackPressedCallback(true) {
- override fun handleOnBackPressed() {
- println("Handle back press ${bottomSheetBehavior.state}")
- if (!handleBackPress()) {
- remove()
- onBackPressedDispatcher.onBackPressed()
- }
- }
- }
-
- private val bottomSheetCallbackList by lazy {
- object : BottomSheetCallback() {
-
- override fun onSlide(bottomSheet: View, slideOffset: Float) {
- setMiniPlayerAlphaProgress(slideOffset)
- navigationBarColorAnimator?.cancel()
- setNavigationBarColorPreOreo(
- argbEvaluator.evaluate(
- slideOffset,
- surfaceColor(),
- navigationBarColor
- ) as Int
- )
- }
-
- override fun onStateChanged(bottomSheet: View, newState: Int) {
- onBackPressedCallback.isEnabled = newState == STATE_EXPANDED
- when (newState) {
- STATE_EXPANDED -> {
- onPanelExpanded()
- if (PreferenceUtil.lyricsScreenOn && PreferenceUtil.showLyrics) {
- keepScreenOn(true)
- }
- }
-
- STATE_COLLAPSED -> {
- onPanelCollapsed()
- if ((PreferenceUtil.lyricsScreenOn && PreferenceUtil.showLyrics) || !PreferenceUtil.isScreenOnEnabled) {
- keepScreenOn(false)
- }
- }
-
- STATE_SETTLING, STATE_DRAGGING -> {
- if (fromNotification) {
- binding.navigationView.bringToFront()
- fromNotification = false
- }
- }
-
- STATE_HIDDEN -> {
- MusicPlayerRemote.clearQueue()
- }
-
- else -> {
- logD("Do a flip")
- }
- }
- }
- }
- }
-
- fun getBottomSheetBehavior() = bottomSheetBehavior
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- if (!hasPermissions()) {
- startActivity(Intent(this, PermissionActivity::class.java))
- finish()
- }
- binding = SlidingMusicPanelLayoutBinding.inflate(layoutInflater)
- setContentView(binding.root)
- binding.root.setOnApplyWindowInsetsListener { _, insets ->
- windowInsets = WindowInsetsCompat.toWindowInsetsCompat(insets)
- insets
- }
- chooseFragmentForTheme()
- setupSlidingUpPanel()
- setupBottomSheet()
- updateColor()
- if (!PreferenceUtil.materialYou) {
- binding.slidingPanel.backgroundTintList = ColorStateList.valueOf(darkAccentColor())
- navigationView.backgroundTintList = ColorStateList.valueOf(darkAccentColor())
- }
-
- navigationBarColor = surfaceColor()
-
- onBackPressedDispatcher.addCallback(onBackPressedCallback)
- }
-
- private fun setupBottomSheet() {
- bottomSheetBehavior = from(binding.slidingPanel)
- bottomSheetBehavior.addBottomSheetCallback(bottomSheetCallbackList)
- bottomSheetBehavior.isHideable = PreferenceUtil.swipeDownToDismiss
- bottomSheetBehavior.significantVelocityThreshold = 300
- setMiniPlayerAlphaProgress(0F)
- }
-
- override fun onResume() {
- super.onResume()
- PreferenceUtil.registerOnSharedPreferenceChangedListener(this)
- if (nowPlayingScreen != PreferenceUtil.nowPlayingScreen) {
- postRecreate()
- }
- if (bottomSheetBehavior.state == STATE_EXPANDED) {
- setMiniPlayerAlphaProgress(1f)
- }
- }
-
- override fun onDestroy() {
- super.onDestroy()
- bottomSheetBehavior.removeBottomSheetCallback(bottomSheetCallbackList)
- PreferenceUtil.unregisterOnSharedPreferenceChangedListener(this)
- }
-
- override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
- when (key) {
- SWIPE_DOWN_DISMISS -> {
- bottomSheetBehavior.isHideable = PreferenceUtil.swipeDownToDismiss
- }
-
- TOGGLE_ADD_CONTROLS -> {
- miniPlayerFragment?.setUpButtons()
- }
-
- NOW_PLAYING_SCREEN_ID -> {
- chooseFragmentForTheme()
- binding.slidingPanel.updateLayoutParams {
- height = if (nowPlayingScreen != Peek) {
- ViewGroup.LayoutParams.MATCH_PARENT
- } else {
- ViewGroup.LayoutParams.WRAP_CONTENT
- }
- onServiceConnected()
- }
- }
-
- ALBUM_COVER_TRANSFORM, CAROUSEL_EFFECT,
- ALBUM_COVER_STYLE, TOGGLE_VOLUME, EXTRA_SONG_INFO, CIRCLE_PLAY_BUTTON,
- -> {
- chooseFragmentForTheme()
- onServiceConnected()
- }
-
- SWIPE_ANYWHERE_NOW_PLAYING -> {
- playerFragment.addSwipeDetector()
- }
-
- ADAPTIVE_COLOR_APP -> {
- if (PreferenceUtil.nowPlayingScreen in listOf(Normal, Material, Flat)) {
- chooseFragmentForTheme()
- onServiceConnected()
- }
- }
-
- LIBRARY_CATEGORIES -> {
- updateTabs()
- }
-
- TAB_TEXT_MODE -> {
- navigationView.labelVisibilityMode = PreferenceUtil.tabTitleMode
- }
-
- TOGGLE_FULL_SCREEN -> {
- recreate()
- }
-
- SCREEN_ON_LYRICS -> {
- keepScreenOn(bottomSheetBehavior.state == STATE_EXPANDED && PreferenceUtil.lyricsScreenOn && PreferenceUtil.showLyrics || PreferenceUtil.isScreenOnEnabled)
- }
-
- KEEP_SCREEN_ON -> {
- maybeSetScreenOn()
- }
- }
- }
-
- fun collapsePanel() {
- bottomSheetBehavior.state = STATE_COLLAPSED
- }
-
- fun expandPanel() {
- bottomSheetBehavior.state = STATE_EXPANDED
- }
-
- private fun setMiniPlayerAlphaProgress(progress: Float) {
- if (progress < 0) return
- val alpha = 1 - progress
- miniPlayerFragment?.view?.alpha = 1 - (progress / 0.2F)
- miniPlayerFragment?.view?.isGone = alpha == 0f
- if (!isLandscape) {
- binding.navigationView.translationY = progress * 500
- binding.navigationView.alpha = alpha
- }
- binding.playerFragmentContainer.alpha = (progress - 0.2F) / 0.2F
- }
-
- private fun animateNavigationBarColor(color: Int) {
- if (VersionUtils.hasOreo()) return
- navigationBarColorAnimator?.cancel()
- navigationBarColorAnimator = ValueAnimator
- .ofArgb(window.navigationBarColor, color).apply {
- duration = ViewUtil.RETRO_MUSIC_ANIM_TIME.toLong()
- interpolator = PathInterpolator(0.4f, 0f, 1f, 1f)
- addUpdateListener { animation: ValueAnimator ->
- setNavigationBarColorPreOreo(
- animation.animatedValue as Int
- )
- }
- start()
- }
- }
-
- open fun onPanelCollapsed() {
- setMiniPlayerAlphaProgress(0F)
- // restore values
- animateNavigationBarColor(surfaceColor())
- setLightStatusBarAuto()
- setLightNavigationBarAuto()
- setTaskDescriptionColor(taskColor)
- //playerFragment?.onHide()
- }
-
- open fun onPanelExpanded() {
- setMiniPlayerAlphaProgress(1F)
- onPaletteColorChanged()
- //playerFragment?.onShow()
- }
-
- private fun setupSlidingUpPanel() {
- binding.slidingPanel.viewTreeObserver.addOnGlobalLayoutListener(object :
- ViewTreeObserver.OnGlobalLayoutListener {
- override fun onGlobalLayout() {
- binding.slidingPanel.viewTreeObserver.removeOnGlobalLayoutListener(this)
- if (nowPlayingScreen != Peek) {
- binding.slidingPanel.updateLayoutParams {
- height = ViewGroup.LayoutParams.MATCH_PARENT
- }
- }
- when (panelState) {
- STATE_EXPANDED -> onPanelExpanded()
- STATE_COLLAPSED -> onPanelCollapsed()
- else -> {
- // playerFragment!!.onHide()
- }
- }
- }
- })
- }
-
- val navigationView get() = binding.navigationView
-
- val slidingPanel get() = binding.slidingPanel
-
- val isBottomNavVisible get() = navigationView.isVisible && navigationView is BottomNavigationView
-
- override fun onServiceConnected() {
- super.onServiceConnected()
- hideBottomSheet(false)
- }
-
- override fun onQueueChanged() {
- super.onQueueChanged()
- // Mini player should be hidden in Playing Queue
- // it may pop up if hideBottomSheet is called
- if (currentFragment(R.id.fragment_container) !is PlayingQueueFragment) {
- hideBottomSheet(MusicPlayerRemote.playingQueue.isEmpty())
- }
- }
-
- private fun handleBackPress(): Boolean {
- if (panelState == STATE_EXPANDED) {
- collapsePanel()
- return true
- }
- return false
- }
-
- private fun onPaletteColorChanged() {
- if (panelState == STATE_EXPANDED) {
- navigationBarColor = surfaceColor()
- setTaskDescColor(paletteColor)
- val isColorLight = paletteColor.isColorLight
- if (PreferenceUtil.isAdaptiveColor && (nowPlayingScreen == Normal || nowPlayingScreen == Flat || nowPlayingScreen == Material)) {
- setLightNavigationBar(true)
- setLightStatusBar(isColorLight)
- } else if (nowPlayingScreen == Card || nowPlayingScreen == Blur || nowPlayingScreen == BlurCard) {
- animateNavigationBarColor(Color.BLACK)
- navigationBarColor = Color.BLACK
- setLightStatusBar(false)
- setLightNavigationBar(true)
- } else if (nowPlayingScreen == Color || nowPlayingScreen == Tiny || nowPlayingScreen == Gradient) {
- animateNavigationBarColor(paletteColor)
- navigationBarColor = paletteColor
- setLightNavigationBar(isColorLight)
- setLightStatusBar(isColorLight)
- } else if (nowPlayingScreen == Full) {
- animateNavigationBarColor(paletteColor)
- navigationBarColor = paletteColor
- setLightNavigationBar(isColorLight)
- setLightStatusBar(false)
- } else if (nowPlayingScreen == Classic) {
- setLightStatusBar(false)
- } else if (nowPlayingScreen == Fit) {
- setLightStatusBar(false)
- }
- }
- }
-
- private fun setTaskDescColor(color: Int) {
- taskColor = color
- if (panelState == STATE_COLLAPSED) {
- setTaskDescriptionColor(color)
- }
- }
-
- fun updateTabs() {
- binding.navigationView.menu.clear()
- val currentTabs: List = PreferenceUtil.libraryCategory
- for (tab in currentTabs) {
- if (tab.visible) {
- val menu = tab.category
- binding.navigationView.menu.add(0, menu.id, 0, menu.stringRes)
- .setIcon(menu.icon)
- }
- }
- if (binding.navigationView.menu.size() == 1) {
- isInOneTabMode = true
- binding.navigationView.isVisible = false
- } else {
- isInOneTabMode = false
- }
- }
-
- private fun updateColor() {
- libraryViewModel.paletteColor.observe(this) { color ->
- this.paletteColor = color
- onPaletteColorChanged()
- }
- }
-
- fun setBottomNavVisibility(
- visible: Boolean,
- animate: Boolean = false,
- hideBottomSheet: Boolean = MusicPlayerRemote.playingQueue.isEmpty(),
- ) {
- if (!ViewCompat.isLaidOut(navigationView)) {
- return
- }
- if (isInOneTabMode) {
- hideBottomSheet(
- hide = hideBottomSheet,
- animate = animate,
- isBottomNavVisible = false
- )
- return
- }
- if (visible xor navigationView.isVisible) {
- val mAnimate = animate && bottomSheetBehavior.state == STATE_COLLAPSED
- if (mAnimate) {
- if (visible) {
- binding.navigationView.bringToFront()
- binding.navigationView.show()
- } else {
- binding.navigationView.hide()
- }
- } else {
- binding.navigationView.isVisible = visible
- if (visible && bottomSheetBehavior.state != STATE_EXPANDED) {
- binding.navigationView.bringToFront()
- }
- }
- }
- hideBottomSheet(
- hide = hideBottomSheet,
- animate = animate,
- isBottomNavVisible = visible && navigationView is BottomNavigationView
- )
- }
-
- fun hideBottomSheet(
- hide: Boolean,
- animate: Boolean = false,
- isBottomNavVisible: Boolean = navigationView.isVisible && navigationView is BottomNavigationView,
- ) {
- val heightOfBar = windowInsets.getBottomInsets() + dip(R.dimen.mini_player_height)
- val heightOfBarWithTabs = heightOfBar + dip(R.dimen.bottom_nav_height)
- if (hide) {
- bottomSheetBehavior.peekHeight = -windowInsets.getBottomInsets()
- bottomSheetBehavior.state = STATE_COLLAPSED
- libraryViewModel.setFabMargin(
- this,
- if (isBottomNavVisible) dip(R.dimen.bottom_nav_height) else 0
- )
- } else {
- if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
- binding.slidingPanel.elevation = 0F
- binding.navigationView.elevation = 5F
- if (isBottomNavVisible) {
- logD("List")
- if (animate) {
- bottomSheetBehavior.peekHeightAnimate(heightOfBarWithTabs)
- } else {
- bottomSheetBehavior.peekHeight = heightOfBarWithTabs
- }
- libraryViewModel.setFabMargin(
- this,
- dip(R.dimen.bottom_nav_mini_player_height)
- )
- } else {
- logD("Details")
- if (animate) {
- bottomSheetBehavior.peekHeightAnimate(heightOfBar).doOnEnd {
- binding.slidingPanel.bringToFront()
- }
- } else {
- bottomSheetBehavior.peekHeight = heightOfBar
- binding.slidingPanel.bringToFront()
- }
- libraryViewModel.setFabMargin(this, dip(R.dimen.mini_player_height))
- }
- }
- }
- }
-
- fun setAllowDragging(allowDragging: Boolean) {
- bottomSheetBehavior.isDraggable = allowDragging
- hideBottomSheet(false)
- }
-
- private fun chooseFragmentForTheme() {
- nowPlayingScreen = PreferenceUtil.nowPlayingScreen
-
- val fragment: AbsPlayerFragment = when (nowPlayingScreen) {
- Blur -> BlurPlayerFragment()
- Adaptive -> AdaptiveFragment()
- Normal -> PlayerFragment()
- Card -> CardFragment()
- BlurCard -> CardBlurFragment()
- Fit -> FitFragment()
- Flat -> FlatPlayerFragment()
- Full -> FullPlayerFragment()
- Plain -> PlainPlayerFragment()
- Simple -> SimplePlayerFragment()
- Material -> MaterialFragment()
- Color -> ColorFragment()
- Gradient -> GradientPlayerFragment()
- Tiny -> TinyPlayerFragment()
- Peek -> PeekPlayerFragment()
- Circle -> CirclePlayerFragment()
- Classic -> ClassicPlayerFragment()
- MD3 -> MD3PlayerFragment()
- else -> PlayerFragment()
- } // must extend AbsPlayerFragment
- supportFragmentManager.commit {
- replace(R.id.playerFragmentContainer, fragment)
- }
- supportFragmentManager.executePendingTransactions()
- playerFragment = whichFragment(R.id.playerFragmentContainer)
- miniPlayerFragment = whichFragment(R.id.miniPlayerFragment)
- miniPlayerFragment?.view?.setOnClickListener { expandPanel() }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt
deleted file mode 100644
index 32b025f01..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.activities.base
-
-import android.content.Context
-import android.os.Bundle
-import android.os.Handler
-import android.os.Looper
-import android.view.KeyEvent
-import androidx.appcompat.app.AppCompatDelegate
-import androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode
-import androidx.core.os.LocaleListCompat
-import code.name.monkey.appthemehelper.common.ATHToolbarActivity
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.extensions.*
-import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.theme.getNightMode
-import code.name.monkey.retromusic.util.theme.getThemeResValue
-
-abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
-
- private val handler = Handler(Looper.getMainLooper())
-
- override fun onCreate(savedInstanceState: Bundle?) {
- updateLocale()
- updateTheme()
- hideStatusBar()
- super.onCreate(savedInstanceState)
- setEdgeToEdgeOrImmersive()
- maybeSetScreenOn()
- setLightNavigationBarAuto()
- setLightStatusBarAuto(surfaceColor())
- if (VersionUtils.hasQ()) {
- window.decorView.isForceDarkAllowed = false
- }
- }
-
- private fun updateTheme() {
- setTheme(getThemeResValue())
- if (PreferenceUtil.materialYou) {
- setDefaultNightMode(getNightMode())
- }
-
- if (PreferenceUtil.isCustomFont) {
- setTheme(R.style.FontThemeOverlay)
- }
- }
-
- private fun updateLocale() {
- val localeCode = PreferenceUtil.languageCode
- if (PreferenceUtil.isLocaleAutoStorageEnabled) {
- AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(localeCode))
- PreferenceUtil.isLocaleAutoStorageEnabled = true
- }
- }
-
- override fun onWindowFocusChanged(hasFocus: Boolean) {
- super.onWindowFocusChanged(hasFocus)
- if (hasFocus) {
- hideStatusBar()
- handler.removeCallbacks(this)
- handler.postDelayed(this, 300)
- } else {
- handler.removeCallbacks(this)
- }
- }
-
- override fun run() {
- setImmersiveFullscreen()
- }
-
- override fun onStop() {
- handler.removeCallbacks(this)
- super.onStop()
- }
-
- public override fun onDestroy() {
- super.onDestroy()
- exitFullscreen()
- }
-
- override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
- if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
- handler.removeCallbacks(this)
- handler.postDelayed(this, 500)
- }
- return super.onKeyDown(keyCode, event)
- }
-
- override fun attachBaseContext(newBase: Context?) {
- super.attachBaseContext(newBase)
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/BugReportActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/BugReportActivity.kt
deleted file mode 100644
index e99881953..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/BugReportActivity.kt
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.activities.bugreport
-
-import android.content.ClipData
-import android.content.ClipboardManager
-import android.content.Intent
-import android.os.Bundle
-import android.view.MenuItem
-import androidx.core.content.getSystemService
-import androidx.core.net.toUri
-import code.name.monkey.appthemehelper.util.TintHelper
-import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.base.AbsThemeActivity
-import code.name.monkey.retromusic.activities.bugreport.model.DeviceInfo
-import code.name.monkey.retromusic.databinding.ActivityBugReportBinding
-import code.name.monkey.retromusic.extensions.accentColor
-import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
-import code.name.monkey.retromusic.extensions.showToast
-
-open class BugReportActivity : AbsThemeActivity() {
-
- private lateinit var binding: ActivityBugReportBinding
- private var deviceInfo: DeviceInfo? = null
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- binding = ActivityBugReportBinding.inflate(layoutInflater)
- setContentView(binding.root)
- setTaskDescriptionColorAuto()
-
- initViews()
-
- if (title.isNullOrEmpty()) setTitle(R.string.report_an_issue)
-
- deviceInfo = DeviceInfo(this)
- binding.cardDeviceInfo.airTextDeviceInfo.text = deviceInfo.toString()
- }
-
- private fun initViews() {
- val accentColor = accentColor()
- setSupportActionBar(binding.toolbar)
- ToolbarContentTintHelper.colorBackButton(binding.toolbar)
- supportActionBar?.setDisplayHomeAsUpEnabled(true)
-
- binding.cardDeviceInfo.airTextDeviceInfo.setOnClickListener { copyDeviceInfoToClipBoard() }
-
- TintHelper.setTintAuto(binding.sendFab, accentColor, true)
- binding.sendFab.setOnClickListener { reportIssue() }
- }
-
- private fun reportIssue() {
- copyDeviceInfoToClipBoard()
- val i = Intent(Intent.ACTION_VIEW)
- i.data = ISSUE_TRACKER_LINK.toUri()
- i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
- startActivity(i)
- }
-
- private fun copyDeviceInfoToClipBoard() {
- val clipboard = getSystemService()
- val clip = ClipData.newPlainText(getString(R.string.device_info), deviceInfo?.toMarkdown())
- clipboard?.setPrimaryClip(clip)
- showToast(R.string.copied_device_info_to_clipboard)
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- if (item.itemId == android.R.id.home) {
- onBackPressedDispatcher.onBackPressed()
- }
- return super.onOptionsItemSelected(item)
- }
-
- companion object {
- private const val ISSUE_TRACKER_LINK =
- "https://github.com/MuntashirAkon/Metro/issues/new"
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/model/DeviceInfo.kt b/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/model/DeviceInfo.kt
deleted file mode 100644
index 19aff73a2..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/model/DeviceInfo.kt
+++ /dev/null
@@ -1,111 +0,0 @@
-package code.name.monkey.retromusic.activities.bugreport.model
-
-import android.annotation.SuppressLint
-import android.content.Context
-import android.content.pm.PackageManager
-import android.os.Build
-import androidx.annotation.IntRange
-import androidx.appcompat.app.AppCompatDelegate
-import androidx.core.content.pm.PackageInfoCompat
-import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.PreferenceUtil.isAdaptiveColor
-import code.name.monkey.retromusic.util.PreferenceUtil.nowPlayingScreen
-import java.util.*
-
-class DeviceInfo(context: Context) {
- @SuppressLint("NewApi")
- private val abis = Build.SUPPORTED_ABIS
-
- @SuppressLint("NewApi")
- private val abis32Bits = Build.SUPPORTED_32_BIT_ABIS
-
- @SuppressLint("NewApi")
- private val abis64Bits = Build.SUPPORTED_64_BIT_ABIS
- private val baseTheme: String
- private val brand = Build.BRAND
- private val buildID = Build.DISPLAY
- private val buildVersion = Build.VERSION.INCREMENTAL
- private val device = Build.DEVICE
- private val hardware = Build.HARDWARE
- private val isAdaptive: Boolean
- private val manufacturer = Build.MANUFACTURER
- private val model = Build.MODEL
- private val nowPlayingTheme: String
- private val product = Build.PRODUCT
- private val releaseVersion = Build.VERSION.RELEASE
-
- @IntRange(from = 0)
- private val sdkVersion = Build.VERSION.SDK_INT
- private var versionCode = 0L
- private var versionName: String? = null
- private val selectedLang: String
- fun toMarkdown(): String {
- return """
- Device info:
- ---
-
- App version $versionName
- App version code $versionCode
- Android build version $buildVersion
- Android release version $releaseVersion
- Android SDK version $sdkVersion
- Android build ID $buildID
- Device brand $brand
- Device manufacturer $manufacturer
- Device name $device
- Device model $model
- Device product name $product
- Device hardware name $hardware
- ABIs ${Arrays.toString(abis)}
- ABIs (32bit) ${Arrays.toString(abis32Bits)}
- ABIs (64bit) ${Arrays.toString(abis64Bits)}
- Language $selectedLang
-
-
- """.trimIndent()
- }
-
- override fun toString(): String {
- return """
- App version: $versionName
- App version code: $versionCode
- Android build version: $buildVersion
- Android release version: $releaseVersion
- Android SDK version: $sdkVersion
- Android build ID: $buildID
- Device brand: $brand
- Device manufacturer: $manufacturer
- Device name: $device
- Device model: $model
- Device product name: $product
- Device hardware name: $hardware
- ABIs: ${Arrays.toString(abis)}
- ABIs (32bit): ${Arrays.toString(abis32Bits)}
- ABIs (64bit): ${Arrays.toString(abis64Bits)}
- Base theme: $baseTheme
- Now playing theme: $nowPlayingTheme
- Adaptive: $isAdaptive
- System language: ${Locale.getDefault().toLanguageTag()}
- In-App Language: $selectedLang
- """.trimIndent()
- }
-
- init {
- val packageInfo = try {
- context.packageManager.getPackageInfo(context.packageName, 0)
- } catch (e: PackageManager.NameNotFoundException) {
- null
- }
- if (packageInfo != null) {
- versionCode = PackageInfoCompat.getLongVersionCode(packageInfo)
- versionName = packageInfo.versionName
- } else {
- versionCode = -1
- versionName = null
- }
- baseTheme = PreferenceUtil.baseTheme
- nowPlayingTheme = context.getString(nowPlayingScreen.titleRes)
- isAdaptive = isAdaptiveColor
- selectedLang = AppCompatDelegate.getApplicationLocales().toLanguageTags()
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/saf/SAFGuideActivity.java b/app/src/main/java/code/name/monkey/retromusic/activities/saf/SAFGuideActivity.java
deleted file mode 100644
index efd56210e..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/saf/SAFGuideActivity.java
+++ /dev/null
@@ -1,76 +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.activities.saf;
-
-import android.os.Build;
-import android.os.Bundle;
-
-import androidx.annotation.Nullable;
-
-import com.heinrichreimersoftware.materialintro.app.IntroActivity;
-import com.heinrichreimersoftware.materialintro.slide.SimpleSlide;
-
-import code.name.monkey.retromusic.R;
-
-/** Created by hemanths on 2019-07-31. */
-public class SAFGuideActivity extends IntroActivity {
-
- public static final int REQUEST_CODE_SAF_GUIDE = 98;
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setButtonCtaVisible(false);
- setButtonNextVisible(false);
- setButtonBackVisible(false);
-
- setButtonCtaTintMode(BUTTON_CTA_TINT_MODE_TEXT);
-
- String title =
- String.format(getString(R.string.saf_guide_slide1_title), getString(R.string.app_name));
-
- addSlide(
- new SimpleSlide.Builder()
- .title(title)
- .description(
- Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1
- ? R.string.saf_guide_slide1_description_before_o
- : R.string.saf_guide_slide1_description)
- .image(R.drawable.saf_guide_1)
- .background(code.name.monkey.appthemehelper.R.color.md_deep_purple_300)
- .backgroundDark(code.name.monkey.appthemehelper.R.color.md_deep_purple_400)
- .layout(R.layout.fragment_simple_slide_large_image)
- .build());
- addSlide(
- new SimpleSlide.Builder()
- .title(R.string.saf_guide_slide2_title)
- .description(R.string.saf_guide_slide2_description)
- .image(R.drawable.saf_guide_2)
- .background(code.name.monkey.appthemehelper.R.color.md_deep_purple_500)
- .backgroundDark(code.name.monkey.appthemehelper.R.color.md_deep_purple_600)
- .layout(R.layout.fragment_simple_slide_large_image)
- .build());
- addSlide(
- new SimpleSlide.Builder()
- .title(R.string.saf_guide_slide3_title)
- .description(R.string.saf_guide_slide3_description)
- .image(R.drawable.saf_guide_3)
- .background(code.name.monkey.appthemehelper.R.color.md_deep_purple_700)
- .backgroundDark(code.name.monkey.appthemehelper.R.color.md_deep_purple_800)
- .layout(R.layout.fragment_simple_slide_large_image)
- .build());
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/saf/SAFRequestActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/saf/SAFRequestActivity.kt
deleted file mode 100644
index 1b389b9d2..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/saf/SAFRequestActivity.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2021 Bartlomiej Uliasz.
- *
- * 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.activities.saf
-
-import android.app.Activity
-import android.content.Intent
-import android.os.Bundle
-import code.name.monkey.retromusic.activities.saf.SAFGuideActivity.REQUEST_CODE_SAF_GUIDE
-import code.name.monkey.retromusic.util.SAFUtil
-
-/** Created by buliasz on 2021-02-07. */
-class SAFRequestActivity : Activity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- val intent = Intent(this, code.name.monkey.retromusic.activities.saf.SAFGuideActivity::class.java)
- startActivityForResult(intent, REQUEST_CODE_SAF_GUIDE)
- }
-
- override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
- super.onActivityResult(requestCode, resultCode, intent)
- when (requestCode) {
- REQUEST_CODE_SAF_GUIDE -> {
- SAFUtil.openTreePicker(this)
- }
- SAFUtil.REQUEST_SAF_PICK_TREE -> {
- if (resultCode == RESULT_OK) {
- SAFUtil.saveTreeUri(this, intent)
- }
- finish()
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt
deleted file mode 100755
index 3a9ca4e4b..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.activities.tageditor
-
-import android.app.Activity
-import android.app.SearchManager
-import android.content.Intent
-import android.graphics.Bitmap
-import android.graphics.BitmapFactory
-import android.net.Uri
-import android.os.Bundle
-import android.provider.MediaStore
-import android.util.Log
-import android.view.LayoutInflater
-import android.view.MenuItem
-import android.view.animation.OvershootInterpolator
-import android.widget.ImageView
-import androidx.activity.result.ActivityResultLauncher
-import androidx.activity.result.IntentSenderRequest
-import androidx.activity.result.PickVisualMediaRequest
-import androidx.activity.result.contract.ActivityResultContracts
-import androidx.appcompat.app.AlertDialog
-import androidx.lifecycle.lifecycleScope
-import androidx.viewbinding.ViewBinding
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.base.AbsBaseActivity
-import code.name.monkey.retromusic.extensions.accentColor
-import code.name.monkey.retromusic.extensions.colorButtons
-import code.name.monkey.retromusic.extensions.hideSoftKeyboard
-import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
-import code.name.monkey.retromusic.model.ArtworkInfo
-import code.name.monkey.retromusic.model.AudioTagInfo
-import code.name.monkey.retromusic.repository.Repository
-import code.name.monkey.retromusic.util.logD
-import code.name.monkey.retromusic.util.logE
-import com.google.android.material.button.MaterialButton
-import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
-import org.jaudiotagger.audio.AudioFile
-import org.jaudiotagger.audio.AudioFileIO
-import org.jaudiotagger.tag.FieldKey
-import org.koin.android.ext.android.inject
-import java.io.File
-
-abstract class AbsTagEditorActivity : AbsBaseActivity() {
- abstract val editorImage: ImageView
- val repository by inject()
-
- lateinit var saveFab: MaterialButton
- protected var id: Long = 0
- private set
- private var paletteColorPrimary: Int = 0
- private var songPaths: List? = null
- private var savedSongPaths: List? = null
- private val currentSongPath: String? = null
- private var savedTags: Map? = null
- private var savedArtworkInfo: ArtworkInfo? = null
- private var _binding: VB? = null
- protected val binding: VB get() = _binding!!
- private var cacheFiles = listOf()
-
- abstract val bindingInflater: (LayoutInflater) -> VB
-
- private lateinit var launcher: ActivityResultLauncher
-
- protected abstract fun loadImageFromFile(selectedFile: Uri?)
-
- protected val show: AlertDialog
- get() =
- MaterialAlertDialogBuilder(this)
- .setTitle(R.string.update_image)
- .setItems(items.toTypedArray()) { _, position ->
- when (position) {
- 0 -> startImagePicker()
- 1 -> searchImageOnWeb()
- 2 -> deleteImage()
- }
- }
- .setNegativeButton(R.string.action_cancel, null)
- .show()
- .colorButtons()
-
- internal val albumArtist: String?
- get() {
- return try {
- getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ALBUM_ARTIST)
- } catch (e: Exception) {
- logE(e)
- null
- }
- }
-
- protected val songTitle: String?
- get() {
- return try {
- getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.TITLE)
- } catch (e: Exception) {
- logE(e)
- null
- }
- }
- protected val composer: String?
- get() {
- return try {
- getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.COMPOSER)
- } catch (e: Exception) {
- logE(e)
- null
- }
- }
-
- protected val albumTitle: String?
- get() {
- return try {
- getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ALBUM)
- } catch (e: Exception) {
- logE(e)
- null
- }
- }
-
- protected val artistName: String?
- get() {
- return try {
- getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ARTIST)
- } catch (e: Exception) {
- logE(e)
- null
- }
- }
-
- protected val albumArtistName: String?
- get() {
- return try {
- getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ALBUM_ARTIST)
- } catch (e: Exception) {
- logE(e)
- null
- }
- }
-
- protected val genreName: String?
- get() {
- return try {
- getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.GENRE)
- } catch (e: Exception) {
- logE(e)
- null
- }
- }
-
- protected val songYear: String?
- get() {
- return try {
- getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.YEAR)
- } catch (e: Exception) {
- logE(e)
- null
- }
- }
-
- protected val trackNumber: String?
- get() {
- return try {
- getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.TRACK)
- } catch (e: Exception) {
- logE(e)
- null
- }
- }
-
- protected val discNumber: String?
- get() {
- return try {
- getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.DISC_NO)
- } catch (e: Exception) {
- logE(e)
- null
- }
- }
-
- protected val lyrics: String?
- get() {
- return try {
- getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.LYRICS)
- } catch (e: Exception) {
- logE(e)
- null
- }
- }
-
- protected val albumArt: Bitmap?
- get() {
- try {
- val artworkTag = getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.firstArtwork
- if (artworkTag != null) {
- val artworkBinaryData = artworkTag.binaryData
- return BitmapFactory.decodeByteArray(
- artworkBinaryData,
- 0,
- artworkBinaryData.size
- )
- }
- return null
- } catch (e: Exception) {
- logE(e)
- return null
- }
- }
-
- private val pickArtworkImage =
- registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
- loadImageFromFile(uri)
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- _binding = bindingInflater.invoke(layoutInflater)
- setContentView(binding.root)
- setTaskDescriptionColorAuto()
-
- saveFab = findViewById(R.id.saveTags)
- getIntentExtras()
-
- songPaths = getSongPaths()
- logD(songPaths?.size)
- if (songPaths!!.isEmpty()) {
- finish()
- }
- setUpViews()
- launcher = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) {
- if (it.resultCode == Activity.RESULT_OK) {
- writeToFiles(getSongUris(), cacheFiles)
- }
- }
- }
-
- private fun setUpViews() {
- setUpFab()
- setUpImageView()
- }
-
- private lateinit var items: List
-
- private fun setUpImageView() {
- loadCurrentImage()
- items = listOf(
- getString(R.string.pick_from_local_storage),
- getString(R.string.web_search),
- getString(R.string.remove_cover)
- )
- editorImage.setOnClickListener { show }
- }
-
- private fun startImagePicker() {
- pickArtworkImage.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
- }
-
- protected abstract fun loadCurrentImage()
-
- protected abstract fun searchImageOnWeb()
-
- protected abstract fun deleteImage()
-
- private fun setUpFab() {
- saveFab.accentColor()
- saveFab.apply {
- scaleX = 0f
- scaleY = 0f
- isEnabled = false
- setOnClickListener { save() }
- }
- }
-
- protected abstract fun save()
-
- private fun getIntentExtras() {
- val intentExtras = intent.extras
- if (intentExtras != null) {
- id = intentExtras.getLong(EXTRA_ID)
- }
- }
-
- protected abstract fun getSongPaths(): List
-
- protected abstract fun getSongUris(): List
-
- protected fun searchWebFor(vararg keys: String) {
- val stringBuilder = StringBuilder()
- for (key in keys) {
- stringBuilder.append(key)
- stringBuilder.append(" ")
- }
- val intent = Intent(Intent.ACTION_WEB_SEARCH)
- intent.putExtra(SearchManager.QUERY, stringBuilder.toString())
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-
- startActivity(intent)
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- when (item.itemId) {
- android.R.id.home -> {
- onBackPressedDispatcher.onBackPressed()
- return true
- }
- }
- return super.onOptionsItemSelected(item)
- }
-
- protected fun dataChanged() {
- showFab()
- }
-
- private fun showFab() {
- saveFab.animate().setDuration(500).setInterpolator(OvershootInterpolator()).scaleX(1f)
- .scaleY(1f).start()
- saveFab.isEnabled = true
- }
-
- private fun hideFab() {
- saveFab.animate().setDuration(500).setInterpolator(OvershootInterpolator()).scaleX(0.0f)
- .scaleY(0.0f).start()
- saveFab.isEnabled = false
- }
-
- protected fun setImageBitmap(bitmap: Bitmap?, bgColor: Int) {
- if (bitmap == null) {
- editorImage.setImageResource(R.drawable.default_audio_art)
- } else {
- editorImage.setImageBitmap(bitmap)
- }
- setColors(bgColor)
- }
-
- protected open fun setColors(color: Int) {
- paletteColorPrimary = color
- }
-
- protected fun writeValuesToFiles(
- fieldKeyValueMap: Map,
- artworkInfo: ArtworkInfo?
- ) {
- hideSoftKeyboard()
-
- hideFab()
- logD(fieldKeyValueMap)
- GlobalScope.launch {
- if (VersionUtils.hasR()) {
- cacheFiles = TagWriter.writeTagsToFilesR(
- this@AbsTagEditorActivity, AudioTagInfo(
- songPaths,
- fieldKeyValueMap,
- artworkInfo
- )
- )
-
- if (cacheFiles.isNotEmpty()) {
- val pendingIntent =
- MediaStore.createWriteRequest(contentResolver, getSongUris())
- launcher.launch(IntentSenderRequest.Builder(pendingIntent).build())
- }
- } else {
- TagWriter.writeTagsToFiles(
- this@AbsTagEditorActivity, AudioTagInfo(
- songPaths,
- fieldKeyValueMap,
- artworkInfo
- )
- )
- }
- }
- }
-
- private fun writeTags(paths: List?) {
- GlobalScope.launch {
- if (VersionUtils.hasR()) {
- cacheFiles = TagWriter.writeTagsToFilesR(
- this@AbsTagEditorActivity, AudioTagInfo(
- paths,
- savedTags,
- savedArtworkInfo
- )
- )
- val pendingIntent = MediaStore.createWriteRequest(contentResolver, getSongUris())
-
- launcher.launch(IntentSenderRequest.Builder(pendingIntent).build())
- } else {
- TagWriter.writeTagsToFiles(
- this@AbsTagEditorActivity, AudioTagInfo(
- paths,
- savedTags,
- savedArtworkInfo
- )
- )
- }
- }
- }
-
- private lateinit var audioFile: AudioFile
-
- private fun getAudioFile(path: String): AudioFile {
- return try {
- if (!this::audioFile.isInitialized) {
- audioFile = AudioFileIO.read(File(path))
- }
- audioFile
- } catch (e: Exception) {
- Log.e(TAG, "Could not read audio file $path", e)
- AudioFile()
- }
- }
-
- private fun writeToFiles(songUris: List, cacheFiles: List) {
- if (cacheFiles.size == songUris.size) {
- for (i in cacheFiles.indices) {
- contentResolver.openOutputStream(songUris[i])?.use { output ->
- cacheFiles[i].inputStream().use { input ->
- input.copyTo(output)
- }
- }
- }
- }
- lifecycleScope.launch {
- TagWriter.scan(this@AbsTagEditorActivity, getSongPaths())
- }
- }
-
- override fun onDestroy() {
- super.onDestroy()
- // Delete Cache Files
- cacheFiles.forEach { file ->
- file.delete()
- }
- }
-
- companion object {
- const val EXTRA_ID = "extra_id"
- const val EXTRA_PALETTE = "extra_palette"
- private val TAG = AbsTagEditorActivity::class.java.simpleName
- private const val REQUEST_CODE_SELECT_IMAGE = 1000
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt
deleted file mode 100755
index 2c9013657..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.activities.tageditor
-
-import android.app.Activity
-import android.content.res.ColorStateList
-import android.graphics.Bitmap
-import android.graphics.BitmapFactory
-import android.graphics.Color
-import android.graphics.drawable.Drawable
-import android.net.Uri
-import android.os.Bundle
-import android.transition.Slide
-import android.view.LayoutInflater
-import android.widget.ImageView
-import android.widget.Toast
-import androidx.core.widget.doAfterTextChanged
-import code.name.monkey.appthemehelper.util.MaterialValueHelper
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.databinding.ActivityAlbumTagEditorBinding
-import code.name.monkey.retromusic.extensions.*
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
-import code.name.monkey.retromusic.model.ArtworkInfo
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.util.ImageUtil
-import code.name.monkey.retromusic.util.MusicUtil
-import code.name.monkey.retromusic.util.RetroColorUtil.generatePalette
-import code.name.monkey.retromusic.util.RetroColorUtil.getColor
-import code.name.monkey.retromusic.util.logD
-import com.bumptech.glide.Glide
-import com.bumptech.glide.load.engine.DiskCacheStrategy
-import com.bumptech.glide.request.target.ImageViewTarget
-import com.bumptech.glide.request.transition.Transition
-import com.google.android.material.shape.MaterialShapeDrawable
-import org.jaudiotagger.tag.FieldKey
-import java.util.*
-
-class AlbumTagEditorActivity : AbsTagEditorActivity() {
-
- override val bindingInflater: (LayoutInflater) -> ActivityAlbumTagEditorBinding =
- ActivityAlbumTagEditorBinding::inflate
-
- private fun windowEnterTransition() {
- val slide = Slide()
- slide.excludeTarget(R.id.appBarLayout, true)
- slide.excludeTarget(R.id.status_bar, true)
- slide.excludeTarget(android.R.id.statusBarBackground, true)
- slide.excludeTarget(android.R.id.navigationBarBackground, true)
-
- window.enterTransition = slide
- }
-
- private var albumArtBitmap: Bitmap? = null
- private var deleteAlbumArt: Boolean = false
-
- private fun setupToolbar() {
- setSupportActionBar(binding.toolbar)
- binding.appBarLayout?.statusBarForeground =
- MaterialShapeDrawable.createWithElevationOverlay(this)
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- window.sharedElementsUseOverlay = true
- binding.imageContainer.transitionName = getString(R.string.transition_album_art)
- windowEnterTransition()
- setUpViews()
- setupToolbar()
- }
-
- private fun setUpViews() {
- fillViewsWithFileTags()
-
- binding.yearContainer.setTint(false)
- binding.genreContainer.setTint(false)
- binding.albumTitleContainer.setTint(false)
- binding.albumArtistContainer.setTint(false)
-
- binding.albumText.appHandleColor().doAfterTextChanged { dataChanged() }
- binding.albumArtistText.appHandleColor().doAfterTextChanged { dataChanged() }
- binding.genreTitle.appHandleColor().doAfterTextChanged { dataChanged() }
- binding.yearTitle.appHandleColor().doAfterTextChanged { dataChanged() }
- }
-
- private fun fillViewsWithFileTags() {
- binding.albumText.setText(albumTitle)
- binding.albumArtistText.setText(albumArtistName)
- binding.genreTitle.setText(genreName)
- binding.yearTitle.setText(songYear)
- logD(albumTitle + albumArtistName)
- }
-
- override fun loadCurrentImage() {
- val bitmap = albumArt
- setImageBitmap(
- bitmap,
- getColor(
- generatePalette(bitmap),
- defaultFooterColor()
- )
- )
- deleteAlbumArt = false
- }
-
- private fun toastLoadingFailed() {
- showToast(R.string.could_not_download_album_cover)
- }
-
- override fun searchImageOnWeb() {
- searchWebFor(binding.albumText.text.toString(), binding.albumArtistText.text.toString())
- }
-
- override fun deleteImage() {
- setImageBitmap(
- BitmapFactory.decodeResource(resources, R.drawable.default_audio_art),
- defaultFooterColor()
- )
- deleteAlbumArt = true
- dataChanged()
- }
-
- override fun loadImageFromFile(selectedFile: Uri?) {
- Glide.with(this@AlbumTagEditorActivity)
- .asBitmapPalette()
- .load(selectedFile)
- .diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true)
- .into(object : ImageViewTarget(binding.editorImage) {
- override fun onResourceReady(
- resource: BitmapPaletteWrapper,
- transition: Transition?
- ) {
- getColor(resource.palette, Color.TRANSPARENT)
- albumArtBitmap = resource.bitmap?.let { ImageUtil.resizeBitmap(it, 2048) }
- setImageBitmap(
- albumArtBitmap,
- getColor(
- resource.palette,
- defaultFooterColor()
- )
- )
- deleteAlbumArt = false
- dataChanged()
- setResult(Activity.RESULT_OK)
- }
-
- override fun onLoadFailed(errorDrawable: Drawable?) {
- super.onLoadFailed(errorDrawable)
- showToast(R.string.error_load_failed, Toast.LENGTH_LONG)
- }
-
- override fun setResource(resource: BitmapPaletteWrapper?) {}
- })
- }
-
- override fun save() {
- val fieldKeyValueMap = EnumMap(FieldKey::class.java)
- fieldKeyValueMap[FieldKey.ALBUM] = binding.albumText.text.toString()
- // android seems not to recognize album_artist field so we additionally write the normal artist field
- fieldKeyValueMap[FieldKey.ARTIST] = binding.albumArtistText.text.toString()
- fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = binding.albumArtistText.text.toString()
- fieldKeyValueMap[FieldKey.GENRE] = binding.genreTitle.text.toString()
- fieldKeyValueMap[FieldKey.YEAR] = binding.yearTitle.text.toString()
-
- writeValuesToFiles(
- fieldKeyValueMap,
- when {
- deleteAlbumArt -> ArtworkInfo(id, null)
- albumArtBitmap == null -> null
- else -> ArtworkInfo(id, albumArtBitmap!!)
- }
- )
- }
-
- override fun getSongPaths(): List {
- return repository.albumById(id).songs
- .map(Song::data)
- }
-
- override fun getSongUris(): List = repository.albumById(id).songs.map {
- MusicUtil.getSongFileUri(it.id)
- }
-
- override fun setColors(color: Int) {
- super.setColors(color)
- saveFab.backgroundTintList = ColorStateList.valueOf(color)
- saveFab.backgroundTintList = ColorStateList.valueOf(color)
- ColorStateList.valueOf(
- MaterialValueHelper.getPrimaryTextColor(
- this,
- color.isColorLight
- )
- ).also {
- saveFab.iconTint = it
- saveFab.setTextColor(it)
- }
- }
-
-
- override val editorImage: ImageView
- get() = binding.editorImage
-
- companion object {
-
- val TAG: String = AlbumTagEditorActivity::class.java.simpleName
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/SongTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/SongTagEditorActivity.kt
deleted file mode 100755
index 93dd8a44f..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/SongTagEditorActivity.kt
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.activities.tageditor
-
-import android.annotation.SuppressLint
-import android.app.Activity
-import android.content.res.ColorStateList
-import android.graphics.Bitmap
-import android.graphics.BitmapFactory
-import android.graphics.Color
-import android.graphics.drawable.Drawable
-import android.net.Uri
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.widget.ImageView
-import android.widget.Toast
-import androidx.core.widget.doAfterTextChanged
-import code.name.monkey.appthemehelper.util.MaterialValueHelper
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.databinding.ActivitySongTagEditorBinding
-import code.name.monkey.retromusic.extensions.*
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
-import code.name.monkey.retromusic.model.ArtworkInfo
-import code.name.monkey.retromusic.repository.SongRepository
-import code.name.monkey.retromusic.util.ImageUtil
-import code.name.monkey.retromusic.util.MusicUtil
-import code.name.monkey.retromusic.util.RetroColorUtil
-import code.name.monkey.retromusic.util.logD
-import com.bumptech.glide.Glide
-import com.bumptech.glide.load.engine.DiskCacheStrategy
-import com.bumptech.glide.request.target.ImageViewTarget
-import com.bumptech.glide.request.transition.Transition
-import com.google.android.material.shape.MaterialShapeDrawable
-import org.jaudiotagger.tag.FieldKey
-import org.koin.android.ext.android.inject
-import java.util.*
-
-class SongTagEditorActivity : AbsTagEditorActivity() {
-
- override val bindingInflater: (LayoutInflater) -> ActivitySongTagEditorBinding =
- ActivitySongTagEditorBinding::inflate
-
-
- private val songRepository by inject()
-
- private var albumArtBitmap: Bitmap? = null
- private var deleteAlbumArt: Boolean = false
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setUpViews()
- setSupportActionBar(binding.toolbar)
- binding.appBarLayout?.statusBarForeground =
- MaterialShapeDrawable.createWithElevationOverlay(this)
- }
-
- @SuppressLint("ClickableViewAccessibility")
- private fun setUpViews() {
- fillViewsWithFileTags()
- binding.songTextContainer.setTint(false)
- binding.composerContainer.setTint(false)
- binding.albumTextContainer.setTint(false)
- binding.artistContainer.setTint(false)
- binding.albumArtistContainer.setTint(false)
- binding.yearContainer.setTint(false)
- binding.genreContainer.setTint(false)
- binding.trackNumberContainer.setTint(false)
- binding.discNumberContainer.setTint(false)
- binding.lyricsContainer.setTint(false)
-
- binding.songText.appHandleColor().doAfterTextChanged { dataChanged() }
- binding.albumText.appHandleColor().doAfterTextChanged { dataChanged() }
- binding.albumArtistText.appHandleColor().doAfterTextChanged { dataChanged() }
- binding.artistText.appHandleColor().doAfterTextChanged { dataChanged() }
- binding.genreText.appHandleColor().doAfterTextChanged { dataChanged() }
- binding.yearText.appHandleColor().doAfterTextChanged { dataChanged() }
- binding.trackNumberText.appHandleColor().doAfterTextChanged { dataChanged() }
- binding.discNumberText.appHandleColor().doAfterTextChanged { dataChanged() }
- binding.lyricsText.appHandleColor().doAfterTextChanged { dataChanged() }
- binding.songComposerText.appHandleColor().doAfterTextChanged { dataChanged() }
- }
-
- private fun fillViewsWithFileTags() {
- binding.songText.setText(songTitle)
- binding.albumArtistText.setText(albumArtist)
- binding.albumText.setText(albumTitle)
- binding.artistText.setText(artistName)
- binding.genreText.setText(genreName)
- binding.yearText.setText(songYear)
- binding.trackNumberText.setText(trackNumber)
- binding.discNumberText.setText(discNumber)
- binding.lyricsText.setText(lyrics)
- binding.songComposerText.setText(composer)
- logD(songTitle + songYear)
- }
-
- override fun loadCurrentImage() {
- val bitmap = albumArt
- setImageBitmap(
- bitmap,
- RetroColorUtil.getColor(
- RetroColorUtil.generatePalette(bitmap),
- defaultFooterColor()
- )
- )
- deleteAlbumArt = false
- }
-
- override fun searchImageOnWeb() {
- searchWebFor(binding.songText.text.toString(), binding.artistText.text.toString())
- }
-
- override fun deleteImage() {
- setImageBitmap(
- BitmapFactory.decodeResource(resources, R.drawable.default_audio_art),
- defaultFooterColor()
- )
- deleteAlbumArt = true
- dataChanged()
- }
-
- override fun setColors(color: Int) {
- super.setColors(color)
- saveFab.backgroundTintList = ColorStateList.valueOf(color)
- ColorStateList.valueOf(
- MaterialValueHelper.getPrimaryTextColor(
- this,
- color.isColorLight
- )
- ).also {
- saveFab.iconTint = it
- saveFab.setTextColor(it)
- }
- }
-
- override fun save() {
- val fieldKeyValueMap = EnumMap(FieldKey::class.java)
- fieldKeyValueMap[FieldKey.TITLE] = binding.songText.text.toString()
- fieldKeyValueMap[FieldKey.ALBUM] = binding.albumText.text.toString()
- fieldKeyValueMap[FieldKey.ARTIST] = binding.artistText.text.toString()
- fieldKeyValueMap[FieldKey.GENRE] = binding.genreText.text.toString()
- fieldKeyValueMap[FieldKey.YEAR] = binding.yearText.text.toString()
- fieldKeyValueMap[FieldKey.TRACK] = binding.trackNumberText.text.toString()
- fieldKeyValueMap[FieldKey.DISC_NO] = binding.discNumberText.text.toString()
- fieldKeyValueMap[FieldKey.LYRICS] = binding.lyricsText.text.toString()
- fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = binding.albumArtistText.text.toString()
- fieldKeyValueMap[FieldKey.COMPOSER] = binding.songComposerText.text.toString()
- writeValuesToFiles(
- fieldKeyValueMap, when {
- deleteAlbumArt -> ArtworkInfo(id, null)
- albumArtBitmap == null -> null
- else -> ArtworkInfo(id, albumArtBitmap!!)
- }
- )
- }
-
- override fun getSongPaths(): List = listOf(songRepository.song(id).data)
-
- override fun getSongUris(): List = listOf(MusicUtil.getSongFileUri(id))
-
- override fun loadImageFromFile(selectedFile: Uri?) {
- Glide.with(this@SongTagEditorActivity)
- .asBitmapPalette()
- .load(selectedFile)
- .diskCacheStrategy(DiskCacheStrategy.NONE)
- .skipMemoryCache(true)
- .into(object : ImageViewTarget(binding.editorImage) {
- override fun onResourceReady(
- resource: BitmapPaletteWrapper,
- transition: Transition?
- ) {
- RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT)
- albumArtBitmap = resource.bitmap?.let { ImageUtil.resizeBitmap(it, 2048) }
- setImageBitmap(
- albumArtBitmap,
- RetroColorUtil.getColor(
- resource.palette,
- defaultFooterColor()
- )
- )
- deleteAlbumArt = false
- dataChanged()
- setResult(Activity.RESULT_OK)
- }
-
- override fun onLoadFailed(errorDrawable: Drawable?) {
- super.onLoadFailed(errorDrawable)
- showToast(R.string.error_load_failed, Toast.LENGTH_LONG)
- }
-
- override fun setResource(resource: BitmapPaletteWrapper?) {}
- })
- }
-
- companion object {
- val TAG: String = SongTagEditorActivity::class.java.simpleName
- }
-
- override val editorImage: ImageView
- get() = binding.editorImage
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/TagWriter.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/TagWriter.kt
deleted file mode 100644
index b9d5f28dd..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/TagWriter.kt
+++ /dev/null
@@ -1,204 +0,0 @@
-package code.name.monkey.retromusic.activities.tageditor
-
-import android.app.Activity
-import android.content.Context
-import android.graphics.Bitmap
-import android.media.MediaScannerConnection
-import android.os.Build
-import android.util.Log
-import androidx.annotation.RequiresApi
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.extensions.showToast
-import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener
-import code.name.monkey.retromusic.model.AudioTagInfo
-import code.name.monkey.retromusic.util.MusicUtil.createAlbumArtFile
-import code.name.monkey.retromusic.util.MusicUtil.deleteAlbumArt
-import code.name.monkey.retromusic.util.MusicUtil.insertAlbumArt
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.withContext
-import org.jaudiotagger.audio.AudioFileIO
-import org.jaudiotagger.audio.exceptions.CannotReadException
-import org.jaudiotagger.audio.exceptions.CannotWriteException
-import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
-import org.jaudiotagger.audio.exceptions.ReadOnlyFileException
-import org.jaudiotagger.tag.FieldDataInvalidException
-import org.jaudiotagger.tag.TagException
-import org.jaudiotagger.tag.images.AndroidArtwork
-import org.jaudiotagger.tag.images.Artwork
-import java.io.File
-import java.io.IOException
-
-class TagWriter {
-
- companion object {
-
- suspend fun scan(context: Context, toBeScanned: List?) {
- if (toBeScanned.isNullOrEmpty()) {
- Log.i("scan", "scan: Empty")
- context.showToast("Scan file from folder")
- return
- }
- MediaScannerConnection.scanFile(
- context,
- toBeScanned.toTypedArray(),
- null,
- withContext(Dispatchers.Main) {
- if (context is Activity) UpdateToastMediaScannerCompletionListener(
- context, toBeScanned
- ) else null
- }
- )
- }
-
- suspend fun writeTagsToFiles(context: Context, info: AudioTagInfo) {
- withContext(Dispatchers.IO) {
- var artwork: Artwork? = null
- var albumArtFile: File? = null
- if (info.artworkInfo?.artwork != null) {
- try {
- albumArtFile = createAlbumArtFile(context).canonicalFile
- info.artworkInfo.artwork.compress(
- Bitmap.CompressFormat.JPEG,
- 100,
- albumArtFile.outputStream()
- )
- artwork = AndroidArtwork.createArtworkFromFile(albumArtFile)
- } catch (e: IOException) {
- e.printStackTrace()
- }
- }
- var wroteArtwork = false
- var deletedArtwork = false
- for (filePath in info.filePaths!!) {
- try {
- val audioFile = AudioFileIO.read(File(filePath))
- val tag = audioFile.tagOrCreateAndSetDefault
- if (info.fieldKeyValueMap != null) {
- for ((key, value) in info.fieldKeyValueMap) {
- try {
- tag.setField(key, value)
- } catch (e: FieldDataInvalidException) {
- withContext(Dispatchers.Main) {
- context.showToast(R.string.could_not_write_tags_to_file)
- }
- return@withContext listOf()
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
- }
- if (info.artworkInfo != null) {
- if (info.artworkInfo.artwork == null) {
- tag.deleteArtworkField()
- deletedArtwork = true
- } else if (artwork != null) {
- tag.deleteArtworkField()
- tag.setField(artwork)
- wroteArtwork = true
- }
- }
- audioFile.commit()
- } catch (e: CannotReadException) {
- e.printStackTrace()
- } catch (e: IOException) {
- e.printStackTrace()
- } catch (e: CannotWriteException) {
- e.printStackTrace()
- } catch (e: TagException) {
- e.printStackTrace()
- } catch (e: ReadOnlyFileException) {
- e.printStackTrace()
- } catch (e: InvalidAudioFrameException) {
- e.printStackTrace()
- }
- }
- if (wroteArtwork) {
- insertAlbumArt(context, info.artworkInfo!!.albumId, albumArtFile!!.path)
- } else if (deletedArtwork) {
- deleteAlbumArt(context, info.artworkInfo!!.albumId)
- }
- scan(context, info.filePaths)
- }
- }
-
- @RequiresApi(Build.VERSION_CODES.R)
- suspend fun writeTagsToFilesR(context: Context, info: AudioTagInfo): List =
- withContext(Dispatchers.IO) {
- val cacheFiles = mutableListOf()
- var artwork: Artwork? = null
- var albumArtFile: File? = null
- if (info.artworkInfo?.artwork != null) {
- try {
- albumArtFile = createAlbumArtFile(context).canonicalFile
- info.artworkInfo.artwork.compress(
- Bitmap.CompressFormat.JPEG,
- 100,
- albumArtFile.outputStream()
- )
- artwork = AndroidArtwork.createArtworkFromFile(albumArtFile)
- } catch (e: IOException) {
- e.printStackTrace()
- }
- }
- var wroteArtwork = false
- var deletedArtwork = false
- for (filePath in info.filePaths!!) {
- try {
- val originFile = File(filePath)
- val cacheFile = File(context.cacheDir, originFile.name)
- cacheFiles.add(cacheFile)
- originFile.inputStream().use { input ->
- cacheFile.outputStream().use { output ->
- input.copyTo(output)
- }
- }
- val audioFile = AudioFileIO.read(cacheFile)
- val tag = audioFile.tagOrCreateAndSetDefault
- if (info.fieldKeyValueMap != null) {
- for ((key, value) in info.fieldKeyValueMap) {
- try {
- tag.setField(key, value)
- } catch (e: FieldDataInvalidException) {
- withContext(Dispatchers.Main) {
- context.showToast(R.string.could_not_write_tags_to_file)
- }
- return@withContext listOf()
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
- }
- if (info.artworkInfo != null) {
- if (info.artworkInfo.artwork == null) {
- tag.deleteArtworkField()
- deletedArtwork = true
- } else if (artwork != null) {
- tag.deleteArtworkField()
- tag.setField(artwork)
- wroteArtwork = true
- }
- }
- audioFile.commit()
- } catch (e: CannotReadException) {
- e.printStackTrace()
- } catch (e: IOException) {
- e.printStackTrace()
- } catch (e: CannotWriteException) {
- e.printStackTrace()
- } catch (e: TagException) {
- e.printStackTrace()
- } catch (e: ReadOnlyFileException) {
- e.printStackTrace()
- } catch (e: InvalidAudioFrameException) {
- e.printStackTrace()
- }
- }
- if (wroteArtwork) {
- insertAlbumArt(context, info.artworkInfo!!.albumId, albumArtFile!!.path)
- } else if (deletedArtwork) {
- deleteAlbumArt(context, info.artworkInfo!!.albumId)
- }
- cacheFiles
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/CategoryInfoAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/CategoryInfoAdapter.kt
deleted file mode 100644
index dd5cda1d3..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/CategoryInfoAdapter.kt
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-package code.name.monkey.retromusic.adapter
-
-import android.annotation.SuppressLint
-import android.content.res.ColorStateList
-import android.view.LayoutInflater
-import android.view.MotionEvent
-import android.view.View
-import android.view.ViewGroup
-import androidx.recyclerview.widget.ItemTouchHelper
-import androidx.recyclerview.widget.RecyclerView
-import code.name.monkey.appthemehelper.ThemeStore.Companion.accentColor
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.databinding.PreferenceDialogLibraryCategoriesListitemBinding
-import code.name.monkey.retromusic.extensions.showToast
-import code.name.monkey.retromusic.model.CategoryInfo
-import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.SwipeAndDragHelper
-import code.name.monkey.retromusic.util.SwipeAndDragHelper.ActionCompletionContract
-
-class CategoryInfoAdapter : RecyclerView.Adapter(),
- ActionCompletionContract {
- var categoryInfos: MutableList =
- PreferenceUtil.libraryCategory.toMutableList()
- @SuppressLint("NotifyDataSetChanged")
- set(value) {
- field = value
- notifyDataSetChanged()
- }
- private val touchHelper: ItemTouchHelper
- fun attachToRecyclerView(recyclerView: RecyclerView?) {
- touchHelper.attachToRecyclerView(recyclerView)
- }
-
- override fun getItemCount(): Int {
- return categoryInfos.size
- }
-
- @SuppressLint("ClickableViewAccessibility")
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- val categoryInfo = categoryInfos[position]
- holder.binding.checkbox.isChecked = categoryInfo.visible
- holder.binding.title.text =
- holder.binding.title.resources.getString(categoryInfo.category.stringRes)
- holder.itemView.setOnClickListener {
- if (!(categoryInfo.visible && isLastCheckedCategory(categoryInfo))) {
- categoryInfo.visible = !categoryInfo.visible
- holder.binding.checkbox.isChecked = categoryInfo.visible
- } else {
- holder.itemView.context.showToast(R.string.you_have_to_select_at_least_one_category)
- }
- }
- holder.binding.dragView.setOnTouchListener { _: View?, event: MotionEvent ->
- if (event.actionMasked == MotionEvent.ACTION_DOWN) {
- touchHelper.startDrag(holder)
- }
- false
- }
- }
-
- override fun onCreateViewHolder(
- parent: ViewGroup, viewType: Int
- ): ViewHolder {
- return ViewHolder(
- PreferenceDialogLibraryCategoriesListitemBinding.inflate(
- LayoutInflater.from(
- parent.context
- ), parent, false
- )
- )
- }
-
- override fun onViewMoved(oldPosition: Int, newPosition: Int) {
- val categoryInfo = categoryInfos[oldPosition]
- categoryInfos.removeAt(oldPosition)
- categoryInfos.add(newPosition, categoryInfo)
- notifyItemMoved(oldPosition, newPosition)
- }
-
- private fun isLastCheckedCategory(categoryInfo: CategoryInfo): Boolean {
- if (categoryInfo.visible) {
- for (c in categoryInfos) {
- if (c !== categoryInfo && c.visible) {
- return false
- }
- }
- }
- return true
- }
-
- class ViewHolder(val binding: PreferenceDialogLibraryCategoriesListitemBinding) :
- RecyclerView.ViewHolder(binding.root) {
-
- init {
- binding.checkbox.buttonTintList =
- ColorStateList.valueOf(accentColor(binding.checkbox.context))
- }
- }
-
- init {
- val swipeAndDragHelper = SwipeAndDragHelper(this)
- touchHelper = ItemTouchHelper(swipeAndDragHelper)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt
deleted file mode 100644
index b139a0af8..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter
-
-import android.annotation.SuppressLint
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.view.ViewOutlineProvider
-import androidx.fragment.app.FragmentActivity
-import androidx.recyclerview.widget.RecyclerView
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.databinding.ItemGenreBinding
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
-import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
-import code.name.monkey.retromusic.interfaces.IGenreClickListener
-import code.name.monkey.retromusic.model.Genre
-import code.name.monkey.retromusic.util.MusicUtil
-import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
-import com.bumptech.glide.Glide
-import java.util.*
-
-/**
- * @author Hemanth S (h4h13).
- */
-
-class GenreAdapter(
- private val activity: FragmentActivity,
- var dataSet: List,
- private val listener: IGenreClickListener
-) : RecyclerView.Adapter() {
-
- init {
- this.setHasStableIds(true)
- }
-
- override fun getItemId(position: Int): Long {
- return dataSet[position].id
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
- return ViewHolder(ItemGenreBinding.inflate(LayoutInflater.from(activity), parent, false))
- }
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- val genre = dataSet[position]
- holder.binding.title.text = genre.name
- holder.binding.text.text = String.format(
- Locale.getDefault(),
- "%d %s",
- genre.songCount,
- if (genre.songCount > 1) activity.getString(R.string.songs) else activity.getString(R.string.song)
- )
- loadGenreImage(genre, holder)
- }
-
- private fun loadGenreImage(genre: Genre, holder: GenreAdapter.ViewHolder) {
- val genreSong = MusicUtil.songByGenre(genre.id)
- Glide.with(activity)
- .asBitmapPalette()
- .songCoverOptions(genreSong)
- .load(RetroGlideExtension.getSongModel(genreSong))
- .into(object : RetroMusicColoredTarget(holder.binding.image) {
- override fun onColorReady(colors: MediaNotificationProcessor) {
- setColors(holder, colors)
- }
- })
- // Just for a bit of shadow around image
- holder.binding.image.outlineProvider = ViewOutlineProvider.BOUNDS
- }
-
- private fun setColors(holder: ViewHolder, color: MediaNotificationProcessor) {
- holder.binding.imageContainerCard.setCardBackgroundColor(color.backgroundColor)
- holder.binding.title.setTextColor(color.primaryTextColor)
- holder.binding.text.setTextColor(color.secondaryTextColor)
- }
-
- override fun getItemCount(): Int {
- return dataSet.size
- }
-
- @SuppressLint("NotifyDataSetChanged")
- fun swapDataSet(list: List) {
- dataSet = list
- notifyDataSetChanged()
- }
-
- inner class ViewHolder(val binding: ItemGenreBinding) : RecyclerView.ViewHolder(binding.root),
- View.OnClickListener {
- override fun onClick(v: View?) {
- listener.onClickGenre(dataSet[layoutPosition], itemView)
- }
-
- init {
- itemView.setOnClickListener(this)
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt
deleted file mode 100644
index e3f809b5f..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter
-
-import android.annotation.SuppressLint
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.appcompat.app.AppCompatActivity
-import androidx.appcompat.widget.AppCompatTextView
-import androidx.core.os.bundleOf
-import androidx.fragment.app.findFragment
-import androidx.navigation.findNavController
-import androidx.navigation.fragment.FragmentNavigatorExtras
-import androidx.recyclerview.widget.GridLayoutManager
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import code.name.monkey.retromusic.*
-import code.name.monkey.retromusic.adapter.album.AlbumAdapter
-import code.name.monkey.retromusic.adapter.artist.ArtistAdapter
-import code.name.monkey.retromusic.adapter.song.SongAdapter
-import code.name.monkey.retromusic.fragments.home.HomeFragment
-import code.name.monkey.retromusic.interfaces.IAlbumClickListener
-import code.name.monkey.retromusic.interfaces.IArtistClickListener
-import code.name.monkey.retromusic.model.Album
-import code.name.monkey.retromusic.model.Artist
-import code.name.monkey.retromusic.model.Home
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.util.PreferenceUtil
-
-class HomeAdapter(private val activity: AppCompatActivity) :
- RecyclerView.Adapter(), IArtistClickListener, IAlbumClickListener {
-
- private var list = listOf()
-
- override fun getItemViewType(position: Int): Int {
- return list[position].homeSection
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
- val layout =
- LayoutInflater.from(activity).inflate(R.layout.section_recycler_view, parent, false)
- return when (viewType) {
- RECENT_ARTISTS, TOP_ARTISTS -> ArtistViewHolder(layout)
- FAVOURITES -> PlaylistViewHolder(layout)
- TOP_ALBUMS, RECENT_ALBUMS -> AlbumViewHolder(layout)
- else -> {
- ArtistViewHolder(layout)
- }
- }
- }
-
- override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
- val home = list[position]
- when (getItemViewType(position)) {
- RECENT_ALBUMS -> {
- val viewHolder = holder as AlbumViewHolder
- viewHolder.bindView(home)
- viewHolder.clickableArea.setOnClickListener {
- it.findFragment().setSharedAxisXTransitions()
- activity.findNavController(R.id.fragment_container).navigate(
- R.id.detailListFragment,
- bundleOf("type" to RECENT_ALBUMS)
- )
- }
- }
- TOP_ALBUMS -> {
- val viewHolder = holder as AlbumViewHolder
- viewHolder.bindView(home)
- viewHolder.clickableArea.setOnClickListener {
- it.findFragment().setSharedAxisXTransitions()
- activity.findNavController(R.id.fragment_container).navigate(
- R.id.detailListFragment,
- bundleOf("type" to TOP_ALBUMS)
- )
- }
- }
- RECENT_ARTISTS -> {
- val viewHolder = holder as ArtistViewHolder
- viewHolder.bindView(home)
- viewHolder.clickableArea.setOnClickListener {
- it.findFragment().setSharedAxisXTransitions()
- activity.findNavController(R.id.fragment_container).navigate(
- R.id.detailListFragment,
- bundleOf("type" to RECENT_ARTISTS)
- )
- }
- }
- TOP_ARTISTS -> {
- val viewHolder = holder as ArtistViewHolder
- viewHolder.bindView(home)
- viewHolder.clickableArea.setOnClickListener {
- it.findFragment().setSharedAxisXTransitions()
- activity.findNavController(R.id.fragment_container).navigate(
- R.id.detailListFragment,
- bundleOf("type" to TOP_ARTISTS)
- )
- }
- }
- FAVOURITES -> {
- val viewHolder = holder as PlaylistViewHolder
- viewHolder.bindView(home)
- viewHolder.clickableArea.setOnClickListener {
- it.findFragment().setSharedAxisXTransitions()
- activity.findNavController(R.id.fragment_container).navigate(
- R.id.detailListFragment,
- bundleOf("type" to FAVOURITES)
- )
- }
- }
- }
- }
-
- override fun getItemCount(): Int {
- return list.size
- }
-
- @SuppressLint("NotifyDataSetChanged")
- fun swapData(sections: List) {
- list = sections
- notifyDataSetChanged()
- }
-
- @Suppress("UNCHECKED_CAST")
- private inner class AlbumViewHolder(view: View) : AbsHomeViewItem(view) {
- fun bindView(home: Home) {
- title.setText(home.titleRes)
- recyclerView.apply {
- adapter = albumAdapter(home.arrayList as List)
- layoutManager = gridLayoutManager()
- }
- }
- }
-
- @Suppress("UNCHECKED_CAST")
- private inner class ArtistViewHolder(view: View) : AbsHomeViewItem(view) {
- fun bindView(home: Home) {
- title.setText(home.titleRes)
- recyclerView.apply {
- layoutManager = linearLayoutManager()
- adapter = artistsAdapter(home.arrayList as List)
- }
- }
- }
-
- @Suppress("UNCHECKED_CAST")
- private inner class PlaylistViewHolder(view: View) : AbsHomeViewItem(view) {
- fun bindView(home: Home) {
- title.setText(home.titleRes)
- recyclerView.apply {
- val songAdapter = SongAdapter(
- activity,
- home.arrayList as MutableList,
- R.layout.item_favourite_card
- )
- layoutManager = linearLayoutManager()
- adapter = songAdapter
- }
- }
- }
-
- open class AbsHomeViewItem(itemView: View) : RecyclerView.ViewHolder(itemView) {
- val recyclerView: RecyclerView = itemView.findViewById(R.id.recyclerView)
- val title: AppCompatTextView = itemView.findViewById(R.id.title)
- val clickableArea: ViewGroup = itemView.findViewById(R.id.clickable_area)
- }
-
- private fun artistsAdapter(artists: List) =
- ArtistAdapter(activity, artists, PreferenceUtil.homeArtistGridStyle, this)
-
- private fun albumAdapter(albums: List) =
- AlbumAdapter(activity, albums, PreferenceUtil.homeAlbumGridStyle, this)
-
- private fun gridLayoutManager() =
- GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
-
- private fun linearLayoutManager() =
- LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
-
- override fun onArtist(artistId: Long, view: View) {
- activity.findNavController(R.id.fragment_container).navigate(
- R.id.artistDetailsFragment,
- bundleOf(EXTRA_ARTIST_ID to artistId),
- null,
- FragmentNavigatorExtras(
- view to artistId.toString()
- )
- )
- }
-
- override fun onAlbumClick(albumId: Long, view: View) {
- activity.findNavController(R.id.fragment_container).navigate(
- R.id.albumDetailsFragment,
- bundleOf(EXTRA_ALBUM_ID to albumId),
- null,
- FragmentNavigatorExtras(
- view to albumId.toString()
- )
- )
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/SearchAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/SearchAdapter.kt
deleted file mode 100644
index 22a60bd95..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/SearchAdapter.kt
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter
-
-import android.annotation.SuppressLint
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.core.os.bundleOf
-import androidx.core.view.isGone
-import androidx.core.view.isInvisible
-import androidx.core.view.isVisible
-import androidx.fragment.app.FragmentActivity
-import androidx.navigation.findNavController
-import androidx.recyclerview.widget.RecyclerView
-import code.name.monkey.appthemehelper.ThemeStore
-import code.name.monkey.retromusic.*
-import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
-import code.name.monkey.retromusic.db.PlaylistWithSongs
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.albumCoverOptions
-import code.name.monkey.retromusic.glide.RetroGlideExtension.artistImageOptions
-import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
-import code.name.monkey.retromusic.helper.MusicPlayerRemote
-import code.name.monkey.retromusic.helper.menu.SongMenuHelper
-import code.name.monkey.retromusic.model.Album
-import code.name.monkey.retromusic.model.Artist
-import code.name.monkey.retromusic.model.Genre
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.util.MusicUtil
-import com.bumptech.glide.Glide
-import java.util.*
-
-class SearchAdapter(
- private val activity: FragmentActivity,
- private var dataSet: List
-) : RecyclerView.Adapter() {
-
- @SuppressLint("NotifyDataSetChanged")
- fun swapDataSet(dataSet: List) {
- this.dataSet = dataSet
- notifyDataSetChanged()
- }
-
- override fun getItemViewType(position: Int): Int {
- if (dataSet[position] is Album) return ALBUM
- if (dataSet[position] is Artist) return if ((dataSet[position] as Artist).isAlbumArtist) ALBUM_ARTIST else ARTIST
- if (dataSet[position] is Genre) return GENRE
- if (dataSet[position] is PlaylistWithSongs) return PLAYLIST
- return if (dataSet[position] is Song) SONG else HEADER
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
- return when (viewType) {
- HEADER -> ViewHolder(
- LayoutInflater.from(activity).inflate(
- R.layout.sub_header,
- parent,
- false
- ), viewType
- )
-
- ALBUM, ARTIST, ALBUM_ARTIST -> ViewHolder(
- LayoutInflater.from(activity).inflate(
- R.layout.item_list_big,
- parent,
- false
- ), viewType
- )
-
- else -> ViewHolder(
- LayoutInflater.from(activity).inflate(R.layout.item_list, parent, false),
- viewType
- )
- }
- }
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- when (getItemViewType(position)) {
- ALBUM -> {
- holder.imageTextContainer?.isVisible = true
- val album = dataSet[position] as Album
- holder.title?.text = album.title
- holder.text?.text = album.artistName
- Glide.with(activity).asDrawable().albumCoverOptions(album.safeGetFirstSong())
- .load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
- .into(holder.image!!)
- }
-
- ARTIST -> {
- holder.imageTextContainer?.isVisible = true
- val artist = dataSet[position] as Artist
- holder.title?.text = artist.name
- holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
- Glide.with(activity).asDrawable().artistImageOptions(artist).load(
- RetroGlideExtension.getArtistModel(artist)
- ).into(holder.image!!)
- }
-
- SONG -> {
- holder.imageTextContainer?.isVisible = true
- val song = dataSet[position] as Song
- holder.title?.text = song.title
- holder.text?.text = song.albumName
- Glide.with(activity).asDrawable().songCoverOptions(song)
- .load(RetroGlideExtension.getSongModel(song)).into(holder.image!!)
- }
-
- GENRE -> {
- val genre = dataSet[position] as Genre
- holder.title?.text = genre.name
- holder.text?.text = String.format(
- Locale.getDefault(),
- "%d %s",
- genre.songCount,
- if (genre.songCount > 1) activity.getString(R.string.songs) else activity.getString(
- R.string.song
- )
- )
- }
-
- PLAYLIST -> {
- val playlist = dataSet[position] as PlaylistWithSongs
- holder.title?.text = playlist.playlistEntity.playlistName
- //holder.text?.text = MusicUtil.playlistInfoString(activity, playlist.songs)
- }
-
- ALBUM_ARTIST -> {
- holder.imageTextContainer?.isVisible = true
- val artist = dataSet[position] as Artist
- holder.title?.text = artist.name
- holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
- Glide.with(activity).asDrawable().artistImageOptions(artist).load(
- RetroGlideExtension.getArtistModel(artist)
- ).into(holder.image!!)
- }
-
- else -> {
- holder.title?.text = dataSet[position].toString()
- holder.title?.setTextColor(ThemeStore.accentColor(activity))
- }
- }
- }
-
- override fun getItemCount(): Int {
- return dataSet.size
- }
-
- inner class ViewHolder(itemView: View, itemViewType: Int) : MediaEntryViewHolder(itemView) {
- init {
- itemView.setOnLongClickListener(null)
- imageTextContainer?.isInvisible = true
- if (itemViewType == SONG) {
- imageTextContainer?.isGone = true
- menu?.isVisible = true
- menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
- override val song: Song
- get() = dataSet[layoutPosition] as Song
- })
- } else {
- menu?.isVisible = false
- }
-
- when (itemViewType) {
- ALBUM -> setImageTransitionName(activity.getString(R.string.transition_album_art))
- ARTIST -> setImageTransitionName(activity.getString(R.string.transition_artist_image))
- else -> {
- val container = itemView.findViewById(R.id.imageContainer)
- container?.isVisible = false
- }
- }
- }
-
- override fun onClick(v: View?) {
- val item = dataSet[layoutPosition]
- when (itemViewType) {
- ALBUM -> {
- activity.findNavController(R.id.fragment_container).navigate(
- R.id.albumDetailsFragment,
- bundleOf(EXTRA_ALBUM_ID to (item as Album).id)
- )
- }
-
- ARTIST -> {
- activity.findNavController(R.id.fragment_container).navigate(
- R.id.artistDetailsFragment,
- bundleOf(EXTRA_ARTIST_ID to (item as Artist).id)
- )
- }
-
- ALBUM_ARTIST -> {
- activity.findNavController(R.id.fragment_container).navigate(
- R.id.albumArtistDetailsFragment,
- bundleOf(EXTRA_ARTIST_NAME to (item as Artist).name)
- )
- }
-
- GENRE -> {
- activity.findNavController(R.id.fragment_container).navigate(
- R.id.genreDetailsFragment,
- bundleOf(EXTRA_GENRE to (item as Genre))
- )
- }
-
- PLAYLIST -> {
- activity.findNavController(R.id.fragment_container).navigate(
- R.id.playlistDetailsFragment,
- bundleOf(EXTRA_PLAYLIST_ID to (item as PlaylistWithSongs).playlistEntity.playListId)
- )
- }
-
- SONG -> {
- MusicPlayerRemote.playNext(item as Song)
- MusicPlayerRemote.playNextSong()
- }
- }
- }
- }
-
- companion object {
- private const val HEADER = 0
- private const val ALBUM = 1
- private const val ARTIST = 2
- private const val SONG = 3
- private const val GENRE = 4
- private const val PLAYLIST = 5
- private const val ALBUM_ARTIST = 6
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/SongFileAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/SongFileAdapter.kt
deleted file mode 100644
index 4005c6e6c..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/SongFileAdapter.kt
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter
-
-import android.graphics.PorterDuff
-import android.view.LayoutInflater
-import android.view.MenuItem
-import android.view.View
-import android.view.ViewGroup
-import androidx.appcompat.app.AppCompatActivity
-import androidx.core.view.isVisible
-import code.name.monkey.appthemehelper.util.ATHUtil
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
-import code.name.monkey.retromusic.extensions.getTintedDrawable
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
-import code.name.monkey.retromusic.interfaces.ICallbacks
-import code.name.monkey.retromusic.util.MusicUtil
-import com.bumptech.glide.Glide
-import com.bumptech.glide.load.engine.DiskCacheStrategy
-import com.bumptech.glide.signature.MediaStoreSignature
-import me.zhanghai.android.fastscroll.PopupTextProvider
-import java.io.File
-import java.text.DecimalFormat
-import kotlin.math.log10
-import kotlin.math.pow
-
-class SongFileAdapter(
- override val activity: AppCompatActivity,
- private var dataSet: List,
- private val itemLayoutRes: Int,
- private val iCallbacks: ICallbacks?
-) : AbsMultiSelectAdapter(
- activity, R.menu.menu_media_selection
-), PopupTextProvider {
-
- init {
- this.setHasStableIds(true)
- }
-
- override fun getItemViewType(position: Int): Int {
- return if (dataSet[position].isDirectory) FOLDER else FILE
- }
-
- override fun getItemId(position: Int): Long {
- return dataSet[position].hashCode().toLong()
- }
-
- fun swapDataSet(songFiles: List) {
- this.dataSet = songFiles
- notifyDataSetChanged()
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
- return ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false))
- }
-
- override fun onBindViewHolder(holder: ViewHolder, index: Int) {
- val file = dataSet[index]
- holder.itemView.isActivated = isChecked(file)
- holder.title?.text = getFileTitle(file)
- if (holder.text != null) {
- if (holder.itemViewType == FILE) {
- holder.text?.text = getFileText(file)
- } else {
- holder.text?.isVisible = false
- }
- }
-
- if (holder.image != null) {
- loadFileImage(file, holder)
- }
- }
-
- private fun getFileTitle(file: File): String {
- return file.name
- }
-
- private fun getFileText(file: File): String? {
- return if (file.isDirectory) null else readableFileSize(file.length())
- }
-
- private fun loadFileImage(file: File, holder: ViewHolder) {
- val iconColor = ATHUtil.resolveColor(activity, androidx.appcompat.R.attr.colorControlNormal)
- if (file.isDirectory) {
- holder.image?.let {
- it.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN)
- it.setImageResource(R.drawable.ic_folder)
- }
- holder.imageTextContainer?.setCardBackgroundColor(
- ATHUtil.resolveColor(
- activity,
- com.google.android.material.R.attr.colorSurface
- )
- )
- } else {
- val error = activity.getTintedDrawable(R.drawable.ic_audio_file, iconColor)
- Glide.with(activity)
- .load(AudioFileCover(file.path))
- .diskCacheStrategy(DiskCacheStrategy.NONE)
- .error(error)
- .placeholder(error)
- .transition(RetroGlideExtension.getDefaultTransition())
- .signature(MediaStoreSignature("", file.lastModified(), 0))
- .into(holder.image!!)
- }
- }
-
- override fun getItemCount(): Int {
- return dataSet.size
- }
-
- override fun getIdentifier(position: Int): File {
- return dataSet[position]
- }
-
- override fun getName(model: File): String {
- return getFileTitle(model)
- }
-
- override fun onMultipleItemAction(menuItem: MenuItem, selection: List) {
- if (iCallbacks == null) return
- iCallbacks.onMultipleItemAction(menuItem, selection as ArrayList)
- }
-
- override fun getPopupText(position: Int): String {
- return if (position >= dataSet.lastIndex) "" else getSectionName(position)
- }
-
- private fun getSectionName(position: Int): String {
- return MusicUtil.getSectionName(dataSet[position].name)
- }
-
- inner class ViewHolder(itemView: View) : code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder(itemView) {
-
- init {
- if (menu != null && iCallbacks != null) {
- menu?.setOnClickListener { v ->
- val position = layoutPosition
- if (isPositionInRange(position)) {
- iCallbacks.onFileMenuClicked(dataSet[position], v)
- }
- }
- }
- if (imageTextContainer != null) {
- imageTextContainer?.cardElevation = 0f
- }
- }
-
- override fun onClick(v: View?) {
- val position = layoutPosition
- if (isPositionInRange(position)) {
- if (isInQuickSelectMode) {
- toggleChecked(position)
- } else {
- iCallbacks?.onFileSelected(dataSet[position])
- }
- }
- }
-
- override fun onLongClick(v: View?): Boolean {
- val position = layoutPosition
- return isPositionInRange(position) && toggleChecked(position)
- }
-
- private fun isPositionInRange(position: Int): Boolean {
- return position >= 0 && position < dataSet.size
- }
- }
-
- companion object {
-
- private const val FILE = 0
- private const val FOLDER = 1
-
- fun readableFileSize(size: Long): String {
- if (size <= 0) return "$size B"
- val units = arrayOf("B", "KB", "MB", "GB", "TB")
- val digitGroups = (log10(size.toDouble()) / log10(1024.0)).toInt()
- return DecimalFormat("#,##0.##").format(size / 1024.0.pow(digitGroups.toDouble())) + " " + units[digitGroups]
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/StorageAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/StorageAdapter.kt
deleted file mode 100644
index 98c2c632f..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/StorageAdapter.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-package code.name.monkey.retromusic.adapter
-
-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 java.io.File
-
-class StorageAdapter(
- val storageList: List,
- val storageClickListener: StorageClickListener
-) :
- RecyclerView.Adapter() {
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
- return ViewHolder(
- LayoutInflater.from(parent.context).inflate(
- R.layout.item_storage,
- parent,
- false
- )
- )
- }
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- holder.bindData(storageList[position])
- }
-
- override fun getItemCount(): Int {
- return storageList.size
- }
-
- inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- val title: TextView = itemView.findViewById(R.id.title)
-
- fun bindData(storage: Storage) {
- title.text = storage.title
- }
-
- init {
- itemView.setOnClickListener { storageClickListener.onStorageClicked(storageList[bindingAdapterPosition]) }
- }
- }
-}
-
-interface StorageClickListener {
- fun onStorageClicked(storage: Storage)
-}
-
-class Storage {
- lateinit var title: String
- lateinit var file: File
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt
deleted file mode 100644
index 160af7e47..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter.album
-
-import android.content.res.ColorStateList
-import android.view.LayoutInflater
-import android.view.MenuItem
-import android.view.View
-import android.view.ViewGroup
-import androidx.core.view.isVisible
-import androidx.fragment.app.FragmentActivity
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
-import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.albumCoverOptions
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
-import code.name.monkey.retromusic.helper.SortOrder
-import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
-import code.name.monkey.retromusic.interfaces.IAlbumClickListener
-import code.name.monkey.retromusic.model.Album
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.util.MusicUtil
-import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
-import com.bumptech.glide.Glide
-import me.zhanghai.android.fastscroll.PopupTextProvider
-
-open class AlbumAdapter(
- override val activity: FragmentActivity,
- var dataSet: List,
- var itemLayoutRes: Int,
- val listener: IAlbumClickListener?
-) : AbsMultiSelectAdapter(
- activity,
- R.menu.menu_media_selection
-), PopupTextProvider {
-
- init {
- this.setHasStableIds(true)
- }
-
- fun swapDataSet(dataSet: List) {
- this.dataSet = dataSet
- notifyDataSetChanged()
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
- val view = LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false)
- return createViewHolder(view, viewType)
- }
-
- protected open fun createViewHolder(view: View, viewType: Int): ViewHolder {
- return ViewHolder(view)
- }
-
- private fun getAlbumTitle(album: Album): String {
- return album.title
- }
-
- protected open fun getAlbumText(album: Album): String? {
- return album.albumArtist.let {
- if (it.isNullOrEmpty()) {
- album.artistName
- } else {
- it
- }
- }
- }
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- val album = dataSet[position]
- val isChecked = isChecked(album)
- holder.itemView.isActivated = isChecked
- holder.title?.text = getAlbumTitle(album)
- holder.text?.text = getAlbumText(album)
- // Check if imageContainer exists so we can have a smooth transition without
- // CardView clipping, if it doesn't exist in current layout set transition name to image instead.
- if (holder.imageContainer != null) {
- holder.imageContainer?.transitionName = album.id.toString()
- } else {
- holder.image?.transitionName = album.id.toString()
- }
- loadAlbumCover(album, holder)
- }
-
- protected open fun setColors(color: MediaNotificationProcessor, holder: ViewHolder) {
- if (holder.paletteColorContainer != null) {
- holder.title?.setTextColor(color.primaryTextColor)
- holder.text?.setTextColor(color.secondaryTextColor)
- holder.paletteColorContainer?.setBackgroundColor(color.backgroundColor)
- }
- holder.mask?.backgroundTintList = ColorStateList.valueOf(color.primaryTextColor)
- holder.imageContainerCard?.setCardBackgroundColor(color.backgroundColor)
- }
-
- protected open fun loadAlbumCover(album: Album, holder: ViewHolder) {
- if (holder.image == null) {
- return
- }
- val song = album.safeGetFirstSong()
- Glide.with(activity)
- .asBitmapPalette()
- .albumCoverOptions(song)
- //.checkIgnoreMediaStore()
- .load(RetroGlideExtension.getSongModel(song))
- .into(object : RetroMusicColoredTarget(holder.image!!) {
- override fun onColorReady(colors: MediaNotificationProcessor) {
- setColors(colors, holder)
- }
- })
- }
-
- override fun getItemCount(): Int {
- return dataSet.size
- }
-
- override fun getItemId(position: Int): Long {
- return dataSet[position].id
- }
-
- override fun getIdentifier(position: Int): Album? {
- return dataSet[position]
- }
-
- override fun getName(model: Album): String {
- return model.title
- }
-
- override fun onMultipleItemAction(
- menuItem: MenuItem,
- selection: List
- ) {
- SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
- }
-
- private fun getSongList(albums: List): List {
- val songs = ArrayList()
- for (album in albums) {
- songs.addAll(album.songs)
- }
- return songs
- }
-
- override fun getPopupText(position: Int): String {
- return getSectionName(position)
- }
-
- private fun getSectionName(position: Int): String {
- var sectionName: String? = null
- when (PreferenceUtil.albumSortOrder) {
- SortOrder.AlbumSortOrder.ALBUM_A_Z, SortOrder.AlbumSortOrder.ALBUM_Z_A -> sectionName =
- dataSet[position].title
-
- SortOrder.AlbumSortOrder.ALBUM_ARTIST -> sectionName = dataSet[position].albumArtist
- SortOrder.AlbumSortOrder.ALBUM_YEAR -> return MusicUtil.getYearString(
- dataSet[position].year
- )
- }
- return MusicUtil.getSectionName(sectionName)
- }
-
- inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
-
- init {
- menu?.isVisible = false
- }
-
- override fun onClick(v: View?) {
- super.onClick(v)
- if (isInQuickSelectMode) {
- toggleChecked(layoutPosition)
- } else {
- image?.let {
- listener?.onAlbumClick(dataSet[layoutPosition].id, imageContainer ?: it)
- }
- }
- }
-
- override fun onLongClick(v: View?): Boolean {
- return toggleChecked(layoutPosition)
- }
- }
-
- companion object {
- val TAG: String = AlbumAdapter::class.java.simpleName
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumCoverPagerAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumCoverPagerAdapter.kt
deleted file mode 100644
index 5a0a7d3cd..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumCoverPagerAdapter.kt
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter.album
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageView
-import androidx.core.os.BundleCompat
-import androidx.core.os.bundleOf
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentManager
-import androidx.lifecycle.lifecycleScope
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.MainActivity
-import code.name.monkey.retromusic.fragments.AlbumCoverStyle
-import code.name.monkey.retromusic.fragments.NowPlayingScreen.*
-import code.name.monkey.retromusic.fragments.base.goToLyrics
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
-import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
-import code.name.monkey.retromusic.misc.CustomFragmentStatePagerAdapter
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.util.MusicUtil
-import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
-import com.bumptech.glide.Glide
-import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED
-import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
-
-class AlbumCoverPagerAdapter(
- fragmentManager: FragmentManager,
- private val dataSet: List
-) : CustomFragmentStatePagerAdapter(fragmentManager) {
-
- private var currentColorReceiver: AlbumCoverFragment.ColorReceiver? = null
- private var currentColorReceiverPosition = -1
-
- override fun getItem(position: Int): Fragment {
- return AlbumCoverFragment.newInstance(dataSet[position])
- }
-
- override fun getCount(): Int {
- return dataSet.size
- }
-
- override fun instantiateItem(container: ViewGroup, position: Int): Any {
- val o = super.instantiateItem(container, position)
- if (currentColorReceiver != null && currentColorReceiverPosition == position) {
- receiveColor(currentColorReceiver!!, currentColorReceiverPosition)
- }
- return o
- }
-
- /**
- * Only the latest passed [AlbumCoverFragment.ColorReceiver] is guaranteed to receive a
- * response
- */
- fun receiveColor(colorReceiver: AlbumCoverFragment.ColorReceiver, position: Int) {
-
- if (getFragment(position) is AlbumCoverFragment) {
- val fragment = getFragment(position) as AlbumCoverFragment
- currentColorReceiver = null
- currentColorReceiverPosition = -1
- fragment.receiveColor(colorReceiver, position)
- } else {
- currentColorReceiver = colorReceiver
- currentColorReceiverPosition = position
- }
- }
-
- class AlbumCoverFragment : Fragment() {
-
- private var isColorReady: Boolean = false
- private lateinit var color: MediaNotificationProcessor
- private lateinit var song: Song
- private var colorReceiver: ColorReceiver? = null
- private var request: Int = 0
- private val mainActivity get() = activity as MainActivity
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- if (arguments != null) {
- song = BundleCompat.getParcelable(requireArguments(), SONG_ARG, Song::class.java)!!
- }
- }
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- val view = inflater.inflate(getLayoutWithPlayerTheme(), container, false)
- view.setOnClickListener {
- if (mainActivity.getBottomSheetBehavior().state == STATE_EXPANDED) {
- showLyricsDialog()
- }
- }
- return view
- }
-
- private fun showLyricsDialog() {
- lifecycleScope.launch(Dispatchers.IO) {
- val data: String? = MusicUtil.getLyrics(song)
- withContext(Dispatchers.Main) {
- MaterialAlertDialogBuilder(
- requireContext(),
- com.google.android.material.R.style.ThemeOverlay_MaterialComponents_Dialog_Alert
- ).apply {
- setTitle(song.title)
- setMessage(if (data.isNullOrEmpty()) "No lyrics found" else data)
- setNegativeButton(R.string.synced_lyrics) { _, _ ->
- goToLyrics(requireActivity())
- }
- show()
- }
- }
- }
- }
-
- private fun getLayoutWithPlayerTheme(): Int {
- return when (PreferenceUtil.nowPlayingScreen) {
- Card, Fit, Tiny, Classic, Gradient, Full -> R.layout.fragment_album_full_cover
- Peek -> R.layout.fragment_peek_album_cover
- else -> {
- if (PreferenceUtil.isCarouselEffect) {
- R.layout.fragment_album_carousel_cover
- } else {
- when (PreferenceUtil.albumCoverStyle) {
- AlbumCoverStyle.Normal -> R.layout.fragment_album_cover
- AlbumCoverStyle.Flat -> R.layout.fragment_album_flat_cover
- AlbumCoverStyle.Circle -> R.layout.fragment_album_circle_cover
- AlbumCoverStyle.Card -> R.layout.fragment_album_card_cover
- AlbumCoverStyle.Full -> R.layout.fragment_album_full_cover
- AlbumCoverStyle.FullCard -> R.layout.fragment_album_full_card_cover
- }
- }
- }
- }
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- loadAlbumCover(albumCover = view.findViewById(R.id.player_image))
- }
-
- override fun onDestroyView() {
- super.onDestroyView()
- colorReceiver = null
- }
-
- private fun loadAlbumCover(albumCover: ImageView) {
- Glide.with(this)
- .asBitmapPalette()
- .songCoverOptions(song)
- //.checkIgnoreMediaStore()
- .load(RetroGlideExtension.getSongModel(song))
- .dontAnimate()
- .into(object : RetroMusicColoredTarget(albumCover) {
- override fun onColorReady(colors: MediaNotificationProcessor) {
- setColor(colors)
- }
- })
- }
-
- private fun setColor(color: MediaNotificationProcessor) {
- this.color = color
- isColorReady = true
- if (colorReceiver != null) {
- colorReceiver!!.onColorReady(color, request)
- colorReceiver = null
- }
- }
-
- internal fun receiveColor(colorReceiver: ColorReceiver, request: Int) {
- if (isColorReady) {
- colorReceiver.onColorReady(color, request)
- } else {
- this.colorReceiver = colorReceiver
- this.request = request
- }
- }
-
- interface ColorReceiver {
- fun onColorReady(color: MediaNotificationProcessor, request: Int)
- }
-
- companion object {
-
- private const val SONG_ARG = "song"
-
- fun newInstance(song: Song): AlbumCoverFragment {
- val frag = AlbumCoverFragment()
- frag.arguments = bundleOf(SONG_ARG to song)
- return frag
- }
- }
- }
-
- companion object {
- val TAG: String = AlbumCoverPagerAdapter::class.java.simpleName
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/album/HorizontalAlbumAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/album/HorizontalAlbumAdapter.kt
deleted file mode 100644
index 7a9f7fa6e..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/album/HorizontalAlbumAdapter.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter.album
-
-import android.view.View
-import android.view.ViewGroup
-import androidx.fragment.app.FragmentActivity
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.albumCoverOptions
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
-import code.name.monkey.retromusic.helper.HorizontalAdapterHelper
-import code.name.monkey.retromusic.interfaces.IAlbumClickListener
-import code.name.monkey.retromusic.model.Album
-import code.name.monkey.retromusic.util.MusicUtil
-import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
-import com.bumptech.glide.Glide
-
-class HorizontalAlbumAdapter(
- activity: FragmentActivity,
- dataSet: List,
- albumClickListener: IAlbumClickListener
-) : AlbumAdapter(
- activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, albumClickListener
-) {
-
- override fun createViewHolder(view: View, viewType: Int): ViewHolder {
- val params = view.layoutParams as ViewGroup.MarginLayoutParams
- HorizontalAdapterHelper.applyMarginToLayoutParams(activity, params, viewType)
- return ViewHolder(view)
- }
-
- override fun setColors(color: MediaNotificationProcessor, holder: ViewHolder) {
- // holder.title?.setTextColor(ATHUtil.resolveColor(activity, android.R.attr.textColorPrimary))
- // holder.text?.setTextColor(ATHUtil.resolveColor(activity, android.R.attr.textColorSecondary))
- }
-
- override fun loadAlbumCover(album: Album, holder: ViewHolder) {
- if (holder.image == null) return
- Glide.with(activity)
- .asBitmapPalette()
- .albumCoverOptions(album.safeGetFirstSong())
- .load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
- .into(object : RetroMusicColoredTarget(holder.image!!) {
- override fun onColorReady(colors: MediaNotificationProcessor) {
- setColors(colors, holder)
- }
- })
- }
-
- override fun getAlbumText(album: Album): String {
- return MusicUtil.getYearString(album.year)
- }
-
- override fun getItemViewType(position: Int): Int {
- return HorizontalAdapterHelper.getItemViewType(position, itemCount)
- }
-
- override fun getItemCount(): Int {
- return dataSet.size
- }
-
- companion object {
- val TAG: String = AlbumAdapter::class.java.simpleName
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/artist/ArtistAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/artist/ArtistAdapter.kt
deleted file mode 100644
index e1ea2ca4c..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/artist/ArtistAdapter.kt
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter.artist
-
-import android.annotation.SuppressLint
-import android.content.res.ColorStateList
-import android.content.res.Resources
-import android.view.LayoutInflater
-import android.view.MenuItem
-import android.view.View
-import android.view.ViewGroup
-import androidx.core.view.isVisible
-import androidx.fragment.app.FragmentActivity
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
-import code.name.monkey.retromusic.extensions.hide
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.artistImageOptions
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
-import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
-import code.name.monkey.retromusic.interfaces.IAlbumArtistClickListener
-import code.name.monkey.retromusic.interfaces.IArtistClickListener
-import code.name.monkey.retromusic.model.Artist
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.util.MusicUtil
-import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
-import com.bumptech.glide.Glide
-import me.zhanghai.android.fastscroll.PopupTextProvider
-
-class ArtistAdapter(
- override val activity: FragmentActivity,
- var dataSet: List,
- var itemLayoutRes: Int,
- val IArtistClickListener: IArtistClickListener,
- val IAlbumArtistClickListener: IAlbumArtistClickListener? = null
-) : AbsMultiSelectAdapter(activity, R.menu.menu_media_selection),
- PopupTextProvider {
-
- var albumArtistsOnly = false
-
- init {
- this.setHasStableIds(true)
- }
-
- @SuppressLint("NotifyDataSetChanged")
- fun swapDataSet(dataSet: List) {
- this.dataSet = dataSet
- notifyDataSetChanged()
- albumArtistsOnly = PreferenceUtil.albumArtistsOnly
- }
-
- override fun getItemId(position: Int): Long {
- return dataSet[position].id
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
- val view =
- try {
- LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false)
- } catch (e: Resources.NotFoundException) {
- LayoutInflater.from(activity).inflate(R.layout.item_grid_circle, parent, false)
- }
- return createViewHolder(view)
- }
-
- private fun createViewHolder(view: View): ViewHolder {
- return ViewHolder(view)
- }
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- val artist = dataSet[position]
- val isChecked = isChecked(artist)
- holder.itemView.isActivated = isChecked
- holder.title?.text = artist.name
- holder.text?.hide()
- val transitionName =
- if (albumArtistsOnly) artist.name else artist.id.toString()
- if (holder.imageContainer != null) {
- holder.imageContainer?.transitionName = transitionName
- } else {
- holder.image?.transitionName = transitionName
- }
- loadArtistImage(artist, holder)
- }
-
- private fun setColors(processor: MediaNotificationProcessor, holder: ViewHolder) {
- holder.mask?.backgroundTintList = ColorStateList.valueOf(processor.primaryTextColor)
- if (holder.paletteColorContainer != null) {
- holder.paletteColorContainer?.setBackgroundColor(processor.backgroundColor)
- holder.title?.setTextColor(processor.primaryTextColor)
- }
- holder.imageContainerCard?.setCardBackgroundColor(processor.backgroundColor)
- }
-
- private fun loadArtistImage(artist: Artist, holder: ViewHolder) {
- if (holder.image == null) {
- return
- }
- Glide.with(activity)
- .asBitmapPalette()
- .artistImageOptions(artist)
- .load(RetroGlideExtension.getArtistModel(artist))
- .transition(RetroGlideExtension.getDefaultTransition())
- .into(object : RetroMusicColoredTarget(holder.image!!) {
- override fun onColorReady(colors: MediaNotificationProcessor) {
- setColors(colors, holder)
- }
- })
- }
-
- override fun getItemCount(): Int {
- return dataSet.size
- }
-
- override fun getIdentifier(position: Int): Artist {
- return dataSet[position]
- }
-
- override fun getName(model: Artist): String {
- return model.name
- }
-
- override fun onMultipleItemAction(
- menuItem: MenuItem,
- selection: List
- ) {
- SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
- }
-
- private fun getSongList(artists: List): List {
- val songs = ArrayList()
- for (artist in artists) {
- songs.addAll(artist.songs) // maybe async in future?
- }
- return songs
- }
-
- override fun getPopupText(position: Int): String {
- return getSectionName(position)
- }
-
- private fun getSectionName(position: Int): String {
- return MusicUtil.getSectionName(dataSet[position].name)
- }
-
- inner class ViewHolder(itemView: View) : code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder(itemView) {
-
- init {
- menu?.isVisible = false
- }
-
- override fun onClick(v: View?) {
- super.onClick(v)
- if (isInQuickSelectMode) {
- toggleChecked(layoutPosition)
- } else {
- val artist = dataSet[layoutPosition]
- image?.let {
- if (albumArtistsOnly && IAlbumArtistClickListener != null) {
- IAlbumArtistClickListener.onAlbumArtist(artist.name, imageContainer ?: it)
- } else {
- IArtistClickListener.onArtist(artist.id, imageContainer ?: it)
- }
- }
- }
- }
-
- override fun onLongClick(v: View?): Boolean {
- return toggleChecked(layoutPosition)
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/backup/BackupAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/backup/BackupAdapter.kt
deleted file mode 100644
index adfcecf1b..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/backup/BackupAdapter.kt
+++ /dev/null
@@ -1,65 +0,0 @@
-package code.name.monkey.retromusic.adapter.backup
-
-import android.annotation.SuppressLint
-import android.view.LayoutInflater
-import android.view.MenuItem
-import android.view.ViewGroup
-import androidx.appcompat.widget.PopupMenu
-import androidx.fragment.app.FragmentActivity
-import androidx.recyclerview.widget.RecyclerView
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.databinding.ItemListBackupBinding
-import java.io.File
-
-
-class BackupAdapter(
- val activity: FragmentActivity,
- var dataSet: MutableList,
- val backupClickedListener: BackupClickedListener
-) : RecyclerView.Adapter() {
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
- return ViewHolder(
- ItemListBackupBinding.inflate(LayoutInflater.from(activity), parent, false)
- )
- }
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- holder.binding.title.text = dataSet[position].nameWithoutExtension
- }
-
- override fun getItemCount(): Int = dataSet.size
-
- @SuppressLint("NotifyDataSetChanged")
- fun swapDataset(dataSet: List) {
- this.dataSet = ArrayList(dataSet)
- notifyDataSetChanged()
- }
-
- inner class ViewHolder(val binding: ItemListBackupBinding) :
- RecyclerView.ViewHolder(binding.root) {
-
- init {
- binding.menu.setOnClickListener { view ->
- val popupMenu = PopupMenu(activity, view)
- popupMenu.inflate(R.menu.menu_backup)
- popupMenu.setOnMenuItemClickListener { menuItem ->
- return@setOnMenuItemClickListener backupClickedListener.onBackupMenuClicked(
- dataSet[bindingAdapterPosition],
- menuItem
- )
- }
- popupMenu.show()
- }
- itemView.setOnClickListener {
- backupClickedListener.onBackupClicked(dataSet[bindingAdapterPosition])
- }
- }
- }
-
- interface BackupClickedListener {
- fun onBackupClicked(file: File)
-
- fun onBackupMenuClicked(file: File, menuItem: MenuItem): Boolean
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/base/AbsMultiSelectAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/base/AbsMultiSelectAdapter.kt
deleted file mode 100644
index bb7b8491c..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/base/AbsMultiSelectAdapter.kt
+++ /dev/null
@@ -1,131 +0,0 @@
-package code.name.monkey.retromusic.adapter.base
-
-import android.graphics.Color
-import android.view.ActionMode
-import android.view.Menu
-import android.view.MenuItem
-import androidx.activity.OnBackPressedCallback
-import androidx.annotation.MenuRes
-import androidx.fragment.app.FragmentActivity
-import androidx.recyclerview.widget.RecyclerView
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.databinding.NumberRollViewBinding
-import code.name.monkey.retromusic.views.NumberRollView
-
-abstract class AbsMultiSelectAdapter(
- open val activity: FragmentActivity, @MenuRes menuRes: Int,
-) : RecyclerView.Adapter(), ActionMode.Callback {
- var actionMode: ActionMode? = null
- private val checked: MutableList
- private var menuRes: Int
-
- override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
- val inflater = mode?.menuInflater
- inflater?.inflate(menuRes, menu)
- return true
- }
-
- override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
- return false
- }
-
- override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
- if (item?.itemId == R.id.action_multi_select_adapter_check_all) {
- checkAll()
- } else {
- onMultipleItemAction(item!!, ArrayList(checked))
- actionMode?.finish()
- clearChecked()
- }
- return true
- }
-
- override fun onDestroyActionMode(mode: ActionMode?) {
- clearChecked()
- activity.window.statusBarColor = when {
- VersionUtils.hasMarshmallow() -> Color.TRANSPARENT
- else -> Color.BLACK
- }
- actionMode = null
- onBackPressedCallback.remove()
- }
-
- private fun checkAll() {
- if (actionMode != null) {
- checked.clear()
- for (i in 0 until itemCount) {
- val identifier = getIdentifier(i)
- if (identifier != null) {
- checked.add(identifier)
- }
- }
- notifyDataSetChanged()
- updateCab()
- }
- }
-
- protected abstract fun getIdentifier(position: Int): I?
-
- protected abstract fun getName(model: I): String?
-
- protected fun isChecked(identifier: I): Boolean {
- return checked.contains(identifier)
- }
-
- protected val isInQuickSelectMode: Boolean
- get() = actionMode != null
-
- protected abstract fun onMultipleItemAction(menuItem: MenuItem, selection: List)
- protected fun setMultiSelectMenuRes(@MenuRes menuRes: Int) {
- this.menuRes = menuRes
- }
-
- protected fun toggleChecked(position: Int): Boolean {
- val identifier = getIdentifier(position) ?: return false
- if (!checked.remove(identifier)) {
- checked.add(identifier)
- }
- notifyItemChanged(position)
- updateCab()
- return true
- }
-
- private fun clearChecked() {
- checked.clear()
- notifyDataSetChanged()
- }
-
- private fun updateCab() {
- if (actionMode == null) {
- actionMode = activity.startActionMode(this)?.apply {
- customView = NumberRollViewBinding.inflate(activity.layoutInflater).root
- }
- activity.onBackPressedDispatcher.addCallback(onBackPressedCallback)
- }
- val size = checked.size
- when {
- size <= 0 -> {
- actionMode?.finish()
- }
- else -> {
- actionMode?.customView?.findViewById(R.id.selection_mode_number)
- ?.setNumber(size, true)
- }
- }
- }
-
- init {
- checked = ArrayList()
- this.menuRes = menuRes
- }
-
- private val onBackPressedCallback = object : OnBackPressedCallback(true) {
- override fun handleOnBackPressed() {
- if (actionMode != null) {
- actionMode?.finish()
- remove()
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/base/MediaEntryViewHolder.java b/app/src/main/java/code/name/monkey/retromusic/adapter/base/MediaEntryViewHolder.java
deleted file mode 100644
index d68186c0f..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/base/MediaEntryViewHolder.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package code.name.monkey.retromusic.adapter.base;
-
-import android.graphics.Color;
-import android.view.View;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.widget.AppCompatImageView;
-
-import com.google.android.material.card.MaterialCardView;
-import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractDraggableSwipeableItemViewHolder;
-
-import code.name.monkey.retromusic.R;
-
-public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHolder
- implements View.OnLongClickListener, View.OnClickListener {
-
- @Nullable
- public View dragView;
-
- @Nullable
- public View dummyContainer;
-
- @Nullable
- public ImageView image;
-
- @Nullable
- public MaterialCardView imageContainerCard;
-
- @Nullable
- public FrameLayout imageContainer;
-
- @Nullable
- public TextView imageText;
-
- @Nullable
- public MaterialCardView imageTextContainer;
-
- @Nullable
- public View mask;
-
- @Nullable
- public AppCompatImageView menu;
-
- @Nullable
- public View paletteColorContainer;
-
- @Nullable
- public TextView text;
-
- @Nullable
- public TextView text2;
-
- @Nullable
- public TextView time;
-
- @Nullable
- public TextView title;
-
- public MediaEntryViewHolder(@NonNull View itemView) {
- super(itemView);
- title = itemView.findViewById(R.id.title);
- text = itemView.findViewById(R.id.text);
- text2 = itemView.findViewById(R.id.text2);
-
- image = itemView.findViewById(R.id.image);
- time = itemView.findViewById(R.id.time);
-
- imageText = itemView.findViewById(R.id.imageText);
- imageTextContainer = itemView.findViewById(R.id.imageTextContainer);
- imageContainerCard = itemView.findViewById(R.id.imageContainerCard);
- imageContainer = itemView.findViewById(R.id.imageContainer);
-
- menu = itemView.findViewById(R.id.menu);
- dragView = itemView.findViewById(R.id.drag_view);
- paletteColorContainer = itemView.findViewById(R.id.paletteColorContainer);
- mask = itemView.findViewById(R.id.mask);
- dummyContainer = itemView.findViewById(R.id.dummy_view);
-
- if (imageContainerCard != null) {
- imageContainerCard.setCardBackgroundColor(Color.TRANSPARENT);
- }
- itemView.setOnClickListener(this);
- itemView.setOnLongClickListener(this);
- }
-
- @Nullable
- @Override
- public View getSwipeableContainerView() {
- return null;
- }
-
- @Override
- public void onClick(View v) {
- }
-
- @Override
- public boolean onLongClick(View v) {
- return false;
- }
-
- public void setImageTransitionName(@NonNull String transitionName) {
- itemView.setTransitionName(transitionName);
- /* if (imageContainerCard != null) {
- imageContainerCard.setTransitionName(transitionName);
- }
- if (image != null) {
- image.setTransitionName(transitionName);
- }*/
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/LegacyPlaylistAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/LegacyPlaylistAdapter.kt
deleted file mode 100644
index 19d681ecf..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/LegacyPlaylistAdapter.kt
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter.playlist
-
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.fragment.app.FragmentActivity
-import androidx.recyclerview.widget.RecyclerView
-import code.name.monkey.retromusic.model.Playlist
-import code.name.monkey.retromusic.util.MusicUtil
-
-class LegacyPlaylistAdapter(
- private val activity: FragmentActivity,
- private var list: List,
- private val layoutRes: Int,
- private val playlistClickListener: PlaylistClickListener
-) :
- RecyclerView.Adapter() {
-
- fun swapData(list: List) {
- this.list = list
- notifyDataSetChanged()
- }
-
- class ViewHolder(itemView: View) : code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder(itemView)
-
- override fun onCreateViewHolder(
- parent: ViewGroup,
- viewType: Int
- ): ViewHolder {
- return ViewHolder(
- LayoutInflater.from(parent.context).inflate(layoutRes, parent, false)
- )
- }
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- val playlist: Playlist = list[position]
- holder.title?.text = playlist.name
- holder.text?.text = MusicUtil.getPlaylistInfoString(activity, playlist.getSongs())
- holder.itemView.setOnClickListener {
- playlistClickListener.onPlaylistClick(playlist)
- }
- }
-
- override fun getItemCount(): Int {
- return list.size
- }
-
- interface PlaylistClickListener {
- fun onPlaylistClick(playlist: Playlist)
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt
deleted file mode 100755
index 6e5b0c001..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter.playlist
-
-import android.graphics.Color
-import android.graphics.drawable.Drawable
-import android.view.LayoutInflater
-import android.view.MenuItem
-import android.view.View
-import android.view.ViewGroup
-import androidx.appcompat.widget.PopupMenu
-import androidx.core.view.isGone
-import androidx.core.view.setPadding
-import androidx.fragment.app.FragmentActivity
-import code.name.monkey.appthemehelper.util.ATHUtil
-import code.name.monkey.appthemehelper.util.TintHelper
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
-import code.name.monkey.retromusic.db.PlaylistEntity
-import code.name.monkey.retromusic.db.PlaylistWithSongs
-import code.name.monkey.retromusic.db.toSongs
-import code.name.monkey.retromusic.extensions.dipToPix
-import code.name.monkey.retromusic.glide.RetroGlideExtension.playlistOptions
-import code.name.monkey.retromusic.glide.playlistPreview.PlaylistPreview
-import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder
-import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
-import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
-import code.name.monkey.retromusic.interfaces.IPlaylistClickListener
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.util.MusicUtil
-import code.name.monkey.retromusic.util.PreferenceUtil
-import com.bumptech.glide.Glide
-import me.zhanghai.android.fastscroll.PopupTextProvider
-
-class PlaylistAdapter(
- override val activity: FragmentActivity,
- var dataSet: List,
- private var itemLayoutRes: Int,
- private val listener: IPlaylistClickListener
-) : AbsMultiSelectAdapter(
- activity,
- R.menu.menu_playlists_selection
-), PopupTextProvider {
-
- init {
- setHasStableIds(true)
- }
-
- fun swapDataSet(dataSet: List) {
- this.dataSet = dataSet
- notifyDataSetChanged()
- }
-
- override fun getItemId(position: Int): Long {
- return dataSet[position].playlistEntity.playListId
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
- val view = LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false)
- return createViewHolder(view)
- }
-
- private fun createViewHolder(view: View): ViewHolder {
- return ViewHolder(view)
- }
-
- private fun getPlaylistTitle(playlist: PlaylistEntity): String {
- return playlist.playlistName.ifEmpty { "-" }
- }
-
- private fun getPlaylistText(playlist: PlaylistWithSongs): String {
- return MusicUtil.getPlaylistInfoString(activity, playlist.songs.toSongs())
- }
-
- override fun getPopupText(position: Int): String {
- val sectionName: String = when (PreferenceUtil.playlistSortOrder) {
- PlaylistSortOrder.PLAYLIST_A_Z, PlaylistSortOrder.PLAYLIST_Z_A -> dataSet[position].playlistEntity.playlistName
- PlaylistSortOrder.PLAYLIST_SONG_COUNT, PlaylistSortOrder.PLAYLIST_SONG_COUNT_DESC -> dataSet[position].songs.size.toString()
- else -> {
- return ""
- }
- }
- return MusicUtil.getSectionName(sectionName)
- }
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- val playlist = dataSet[position]
- holder.itemView.isActivated = isChecked(playlist)
- holder.title?.text = getPlaylistTitle(playlist.playlistEntity)
- holder.text?.text = getPlaylistText(playlist)
- holder.menu?.isGone = isChecked(playlist)
- if (itemLayoutRes == R.layout.item_list) {
- holder.image?.setPadding(activity.dipToPix(8F).toInt())
- holder.image?.setImageDrawable(getIconRes())
- } else {
- Glide.with(activity)
- .load(PlaylistPreview(playlist))
- .playlistOptions()
- .into(holder.image!!)
- }
- }
-
- private fun getIconRes(): Drawable = TintHelper.createTintedDrawable(
- activity,
- R.drawable.ic_playlist_play,
- ATHUtil.resolveColor(activity, android.R.attr.colorControlNormal)
- )
-
- override fun getItemCount(): Int {
- return dataSet.size
- }
-
- override fun getIdentifier(position: Int): PlaylistWithSongs {
- return dataSet[position]
- }
-
- override fun getName(model: PlaylistWithSongs): String {
- return model.playlistEntity.playlistName
- }
-
- override fun onMultipleItemAction(menuItem: MenuItem, selection: List) {
- when (menuItem.itemId) {
- else -> SongsMenuHelper.handleMenuClick(
- activity,
- getSongList(selection),
- menuItem.itemId
- )
- }
- }
-
- private fun getSongList(playlists: List): List {
- val songs = mutableListOf()
- playlists.forEach {
- songs.addAll(it.songs.toSongs())
- }
- return songs
- }
-
- inner class ViewHolder(itemView: View) : code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder(itemView) {
- init {
- menu?.setOnClickListener { view ->
- val popupMenu = PopupMenu(activity, view)
- popupMenu.inflate(R.menu.menu_item_playlist)
- popupMenu.setOnMenuItemClickListener { item ->
- PlaylistMenuHelper.handleMenuClick(activity, dataSet[layoutPosition], item)
- }
- popupMenu.show()
- }
-
- imageTextContainer?.apply {
- cardElevation = 0f
- setCardBackgroundColor(Color.TRANSPARENT)
- }
- }
-
- override fun onClick(v: View?) {
- if (isInQuickSelectMode) {
- toggleChecked(layoutPosition)
- } else {
- itemView.transitionName = "playlist"
- listener.onPlaylistClick(dataSet[layoutPosition], itemView)
- }
- }
-
- override fun onLongClick(v: View?): Boolean {
- toggleChecked(layoutPosition)
- return true
- }
- }
-
- companion object {
- val TAG: String = PlaylistAdapter::class.java.simpleName
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/AbsOffsetSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/AbsOffsetSongAdapter.kt
deleted file mode 100644
index 2d5fd724f..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/AbsOffsetSongAdapter.kt
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter.song
-
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.annotation.LayoutRes
-import androidx.fragment.app.FragmentActivity
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.helper.MusicPlayerRemote
-import code.name.monkey.retromusic.model.Song
-
-abstract class AbsOffsetSongAdapter(
- activity: FragmentActivity,
- dataSet: MutableList,
- @LayoutRes itemLayoutRes: Int
-) : SongAdapter(activity, dataSet, itemLayoutRes) {
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongAdapter.ViewHolder {
- if (viewType == OFFSET_ITEM) {
- val view = LayoutInflater.from(activity)
- .inflate(R.layout.item_list_quick_actions, parent, false)
- return createViewHolder(view)
- }
- return super.onCreateViewHolder(parent, viewType)
- }
-
- override fun createViewHolder(view: View): SongAdapter.ViewHolder {
- return ViewHolder(view)
- }
-
- override fun getItemId(position: Int): Long {
- var positionFinal = position
- positionFinal--
- return if (positionFinal < 0) -2 else super.getItemId(positionFinal)
- }
-
- override fun getIdentifier(position: Int): Song? {
- var positionFinal = position
- positionFinal--
- return if (positionFinal < 0) null else super.getIdentifier(positionFinal)
- }
-
- override fun getItemCount(): Int {
- val superItemCount = super.getItemCount()
- return if (superItemCount == 0) 0 else superItemCount + 1
- }
-
- override fun getItemViewType(position: Int): Int {
- return if (position == 0) OFFSET_ITEM else SONG
- }
-
- open inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) {
-
- override // could also return null, just to be safe return empty song
- val song: Song
- get() = if (itemViewType == OFFSET_ITEM) Song.emptySong else dataSet[layoutPosition - 1]
-
- override fun onClick(v: View?) {
- if (isInQuickSelectMode && itemViewType != OFFSET_ITEM) {
- toggleChecked(layoutPosition)
- } else {
- MusicPlayerRemote.openQueue(dataSet, layoutPosition - 1, true)
- }
- }
-
- override fun onLongClick(v: View?): Boolean {
- if (itemViewType == OFFSET_ITEM) return false
- toggleChecked(layoutPosition)
- return true
- }
- }
-
- companion object {
- const val OFFSET_ITEM = 0
- const val SONG = 1
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt
deleted file mode 100644
index bf85fe28b..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter.song
-
-import android.view.MenuItem
-import android.view.View
-import androidx.core.view.isVisible
-import androidx.fragment.app.FragmentActivity
-import androidx.lifecycle.lifecycleScope
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.db.PlaylistEntity
-import code.name.monkey.retromusic.db.toSongEntity
-import code.name.monkey.retromusic.db.toSongsEntity
-import code.name.monkey.retromusic.dialogs.RemoveSongFromPlaylistDialog
-import code.name.monkey.retromusic.fragments.LibraryViewModel
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.util.ViewUtil
-import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter
-import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class OrderablePlaylistSongAdapter(
- private val playlistId: Long,
- activity: FragmentActivity,
- dataSet: MutableList,
- itemLayoutRes: Int,
-) : SongAdapter(activity, dataSet, itemLayoutRes),
- DraggableItemAdapter {
-
- val libraryViewModel: LibraryViewModel by activity.viewModel()
-
- init {
- this.setHasStableIds(true)
- this.setMultiSelectMenuRes(R.menu.menu_playlists_songs_selection)
- }
-
- override fun getItemId(position: Int): Long {
- // requires static value, it means need to keep the same value
- // even if the item position has been changed.
- return dataSet[position].id
- }
-
- override fun createViewHolder(view: View): SongAdapter.ViewHolder {
- return ViewHolder(view)
- }
-
- override fun onMultipleItemAction(menuItem: MenuItem, selection: List) {
- when (menuItem.itemId) {
- R.id.action_remove_from_playlist -> RemoveSongFromPlaylistDialog.create(
- selection.toSongsEntity(
- playlistId
- )
- )
- .show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST")
-
- else -> super.onMultipleItemAction(menuItem, selection)
- }
- }
-
- inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) {
-
- override var songMenuRes: Int
- get() = R.menu.menu_item_playlist_song
- set(value) {
- super.songMenuRes = value
- }
-
- override fun onSongMenuItemClick(item: MenuItem): Boolean {
- when (item.itemId) {
- R.id.action_remove_from_playlist -> {
- RemoveSongFromPlaylistDialog.create(song.toSongEntity(playlistId))
- .show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST")
- return true
- }
- }
- return super.onSongMenuItemClick(item)
- }
-
- init {
- dragView?.isVisible = true
- }
- }
-
- override fun onCheckCanStartDrag(holder: ViewHolder, position: Int, x: Int, y: Int): Boolean {
- if (isInQuickSelectMode) {
- return false
- }
- return ViewUtil.hitTest(holder.imageText!!, x, y) || ViewUtil.hitTest(
- holder.dragView!!,
- x,
- y
- )
- }
-
- override fun onMoveItem(fromPosition: Int, toPosition: Int) {
- dataSet.add(toPosition, dataSet.removeAt(fromPosition))
- }
-
- override fun onGetItemDraggableRange(holder: ViewHolder, position: Int): ItemDraggableRange? {
- return null
- }
-
- override fun onCheckCanDrop(draggingPosition: Int, dropPosition: Int): Boolean {
- return true
- }
-
- override fun onItemDragStarted(position: Int) {
- notifyDataSetChanged()
- }
-
- override fun onItemDragFinished(fromPosition: Int, toPosition: Int, result: Boolean) {
- notifyDataSetChanged()
- }
-
- fun saveSongs(playlistEntity: PlaylistEntity) {
- activity.lifecycleScope.launch(Dispatchers.IO) {
- libraryViewModel.insertSongs(dataSet.toSongsEntity(playlistEntity))
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlayingQueueAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlayingQueueAdapter.kt
deleted file mode 100644
index 2d387be44..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlayingQueueAdapter.kt
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter.song
-
-import android.view.MenuItem
-import android.view.View
-import androidx.core.view.isVisible
-import androidx.fragment.app.FragmentActivity
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
-import code.name.monkey.retromusic.helper.MusicPlayerRemote
-import code.name.monkey.retromusic.helper.MusicPlayerRemote.isPlaying
-import code.name.monkey.retromusic.helper.MusicPlayerRemote.playNextSong
-import code.name.monkey.retromusic.helper.MusicPlayerRemote.removeFromQueue
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.util.MusicUtil
-import code.name.monkey.retromusic.util.ViewUtil
-import com.bumptech.glide.Glide
-import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter
-import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange
-import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags
-import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemAdapter
-import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemConstants
-import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultAction
-import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionDefault
-import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionRemoveItem
-import me.zhanghai.android.fastscroll.PopupTextProvider
-
-class PlayingQueueAdapter(
- activity: FragmentActivity,
- dataSet: MutableList,
- private var current: Int,
- itemLayoutRes: Int,
-) : SongAdapter(activity, dataSet, itemLayoutRes),
- DraggableItemAdapter,
- SwipeableItemAdapter,
- PopupTextProvider {
-
- private var songToRemove: Song? = null
-
- override fun createViewHolder(view: View): SongAdapter.ViewHolder {
- return ViewHolder(view)
- }
-
- override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
- super.onBindViewHolder(holder, position)
- val song = dataSet[position]
- holder.time?.text = MusicUtil.getReadableDurationString(song.duration)
- if (holder.itemViewType == HISTORY || holder.itemViewType == CURRENT) {
- setAlpha(holder, 0.5f)
- }
- }
-
- override fun getItemViewType(position: Int): Int {
- if (position < current) {
- return HISTORY
- } else if (position > current) {
- return UP_NEXT
- }
- return CURRENT
- }
-
- override fun loadAlbumCover(song: Song, holder: SongAdapter.ViewHolder) {
- if (holder.image == null) {
- return
- }
- Glide.with(activity)
- .load(RetroGlideExtension.getSongModel(song))
- .songCoverOptions(song)
- .into(holder.image!!)
- }
-
- fun swapDataSet(dataSet: List, position: Int) {
- this.dataSet = dataSet.toMutableList()
- current = position
- notifyDataSetChanged()
- }
-
- fun setCurrent(current: Int) {
- this.current = current
- notifyDataSetChanged()
- }
-
- private fun setAlpha(holder: SongAdapter.ViewHolder, alpha: Float) {
- holder.image?.alpha = alpha
- holder.title?.alpha = alpha
- holder.text?.alpha = alpha
- holder.paletteColorContainer?.alpha = alpha
- holder.dragView?.alpha = alpha
- holder.menu?.alpha = alpha
- }
-
- override fun getPopupText(position: Int): String {
- return MusicUtil.getSectionName(dataSet[position].title)
- }
-
- override fun onCheckCanStartDrag(holder: ViewHolder, position: Int, x: Int, y: Int): Boolean {
- return ViewUtil.hitTest(holder.imageText!!, x, y) || ViewUtil.hitTest(
- holder.dragView!!,
- x,
- y
- )
- }
-
- override fun onGetItemDraggableRange(holder: ViewHolder, position: Int): ItemDraggableRange? {
- return null
- }
-
- override fun onMoveItem(fromPosition: Int, toPosition: Int) {
- MusicPlayerRemote.moveSong(fromPosition, toPosition)
- }
-
- override fun onCheckCanDrop(draggingPosition: Int, dropPosition: Int): Boolean {
- return true
- }
-
- override fun onItemDragStarted(position: Int) {
- notifyDataSetChanged()
- }
-
- override fun onItemDragFinished(fromPosition: Int, toPosition: Int, result: Boolean) {
- notifyDataSetChanged()
- }
-
- fun setSongToRemove(song: Song) {
- songToRemove = song
- }
-
- inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) {
- @DraggableItemStateFlags
- private var mDragStateFlags: Int = 0
-
- override var songMenuRes: Int
- get() = R.menu.menu_item_playing_queue_song
- set(value) {
- super.songMenuRes = value
- }
-
- init {
- dragView?.isVisible = true
- }
-
- override fun onClick(v: View?) {
- if (isInQuickSelectMode) {
- toggleChecked(layoutPosition)
- } else {
- MusicPlayerRemote.playSongAt(layoutPosition)
- }
- }
-
- override fun onSongMenuItemClick(item: MenuItem): Boolean {
- when (item.itemId) {
- R.id.action_remove_from_playing_queue -> {
- removeFromQueue(layoutPosition)
- return true
- }
- }
- return super.onSongMenuItemClick(item)
- }
-
- @DraggableItemStateFlags
- override fun getDragStateFlags(): Int {
- return mDragStateFlags
- }
-
- override fun setDragStateFlags(@DraggableItemStateFlags flags: Int) {
- mDragStateFlags = flags
- }
-
- override fun getSwipeableContainerView(): View {
- return dummyContainer!!
- }
- }
-
- companion object {
-
- private const val HISTORY = 0
- private const val CURRENT = 1
- private const val UP_NEXT = 2
- }
-
- override fun onSwipeItem(holder: ViewHolder, position: Int, result: Int): SwipeResultAction {
- return if (result == SwipeableItemConstants.RESULT_CANCELED) {
- SwipeResultActionDefault()
- } else {
- SwipedResultActionRemoveItem(this, position)
- }
- }
-
- override fun onGetSwipeReactionType(holder: ViewHolder, position: Int, x: Int, y: Int): Int {
- return if (onCheckCanStartDrag(holder, position, x, y)) {
- SwipeableItemConstants.REACTION_CAN_NOT_SWIPE_BOTH_H
- } else {
- SwipeableItemConstants.REACTION_CAN_SWIPE_BOTH_H
- }
- }
-
- override fun onSwipeItemStarted(holder: ViewHolder, p1: Int) {
- }
-
- override fun onSetSwipeBackground(holder: ViewHolder, position: Int, result: Int) {
- }
-
- internal class SwipedResultActionRemoveItem(
- private val adapter: PlayingQueueAdapter,
- private val position: Int,
- ) : SwipeResultActionRemoveItem() {
-
- private var songToRemove: Song? = null
- override fun onPerformAction() {
- // currentlyShownSnackbar = null
- }
-
- override fun onSlideAnimationEnd() {
- // initializeSnackBar(adapter, position, activity, isPlaying)
- songToRemove = adapter.dataSet[position]
- // If song removed was the playing song, then play the next song
- if (isPlaying(songToRemove!!)) {
- playNextSong()
- }
- // Swipe animation is much smoother when we do the heavy lifting after it's completed
- adapter.setSongToRemove(songToRemove!!)
- removeFromQueue(songToRemove!!)
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/ShuffleButtonSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/ShuffleButtonSongAdapter.kt
deleted file mode 100644
index 82ba1a7f7..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/ShuffleButtonSongAdapter.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter.song
-
-import android.view.View
-import androidx.core.view.isVisible
-import androidx.fragment.app.FragmentActivity
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.extensions.accentColor
-import code.name.monkey.retromusic.extensions.accentOutlineColor
-import code.name.monkey.retromusic.helper.MusicPlayerRemote
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.RetroUtil
-import com.google.android.material.button.MaterialButton
-
-class ShuffleButtonSongAdapter(
- activity: FragmentActivity,
- dataSet: MutableList,
- itemLayoutRes: Int
-) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes) {
-
-
- override fun createViewHolder(view: View): SongAdapter.ViewHolder {
- return ViewHolder(view)
- }
-
- override fun getItemViewType(position: Int): Int {
- return if (position == 0) OFFSET_ITEM else SONG
- }
-
- override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
- if (holder.itemViewType == OFFSET_ITEM) {
- val viewHolder = holder as ViewHolder
- viewHolder.playAction?.let {
- it.setOnClickListener {
- MusicPlayerRemote.openQueue(dataSet, 0, true)
- }
- it.accentOutlineColor()
- }
- viewHolder.shuffleAction?.let {
- it.setOnClickListener {
- MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
- }
- it.accentColor()
- }
- } else {
- super.onBindViewHolder(holder, position - 1)
- val landscape = RetroUtil.isLandscape
- if ((PreferenceUtil.songGridSize > 2 && !landscape) || (PreferenceUtil.songGridSizeLand > 5 && landscape)) {
- holder.menu?.isVisible = false
- }
- }
- }
-
- inner class ViewHolder(itemView: View) : AbsOffsetSongAdapter.ViewHolder(itemView) {
- val playAction: MaterialButton? = itemView.findViewById(R.id.playAction)
- val shuffleAction: MaterialButton? = itemView.findViewById(R.id.shuffleAction)
-
- override fun onClick(v: View?) {
- if (itemViewType == OFFSET_ITEM) {
- MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
- return
- }
- super.onClick(v)
- }
- }
-
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/SimpleSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/SimpleSongAdapter.kt
deleted file mode 100755
index f1f50e627..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/SimpleSongAdapter.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter.song
-
-import android.view.LayoutInflater
-import android.view.ViewGroup
-import androidx.fragment.app.FragmentActivity
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.util.MusicUtil
-
-class SimpleSongAdapter(
- context: FragmentActivity,
- songs: ArrayList,
- layoutRes: Int
-) : SongAdapter(context, songs, layoutRes) {
-
- override fun swapDataSet(dataSet: List) {
- this.dataSet = dataSet.toMutableList()
- notifyDataSetChanged()
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
- return ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false))
- }
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- super.onBindViewHolder(holder, position)
- val fixedTrackNumber = MusicUtil.getFixedTrackNumber(dataSet[position].trackNumber)
- val trackAndTime = (if (fixedTrackNumber > 0) "$fixedTrackNumber | " else "") +
- MusicUtil.getReadableDurationString(dataSet[position].duration)
-
- holder.time?.text = trackAndTime
- holder.text2?.text = dataSet[position].artistName
- }
-
- override fun getItemCount(): Int {
- return dataSet.size
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/SongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/SongAdapter.kt
deleted file mode 100644
index 7b7b7bf99..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/SongAdapter.kt
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- */
-package code.name.monkey.retromusic.adapter.song
-
-import android.content.res.ColorStateList
-import android.content.res.Resources
-import android.view.LayoutInflater
-import android.view.MenuItem
-import android.view.View
-import android.view.ViewGroup
-import androidx.core.os.bundleOf
-import androidx.core.view.isGone
-import androidx.core.view.isVisible
-import androidx.fragment.app.FragmentActivity
-import androidx.navigation.findNavController
-import code.name.monkey.retromusic.EXTRA_ALBUM_ID
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
-import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
-import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
-import code.name.monkey.retromusic.helper.MusicPlayerRemote
-import code.name.monkey.retromusic.helper.SortOrder
-import code.name.monkey.retromusic.helper.menu.SongMenuHelper
-import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.util.MusicUtil
-import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.RetroUtil
-import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
-import com.bumptech.glide.Glide
-import me.zhanghai.android.fastscroll.PopupTextProvider
-
-/**
- * Created by hemanths on 13/08/17.
- */
-
-open class SongAdapter(
- override val activity: FragmentActivity,
- var dataSet: MutableList,
- protected var itemLayoutRes: Int,
- showSectionName: Boolean = true
-) : AbsMultiSelectAdapter(
- activity,
- R.menu.menu_media_selection
-), PopupTextProvider {
-
- private var showSectionName = true
-
- init {
- this.showSectionName = showSectionName
- this.setHasStableIds(true)
- }
-
- open fun swapDataSet(dataSet: List) {
- this.dataSet = ArrayList(dataSet)
- notifyDataSetChanged()
- }
-
- override fun getItemId(position: Int): Long {
- return dataSet[position].id
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
- val view =
- try {
- LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false)
- } catch (e: Resources.NotFoundException) {
- LayoutInflater.from(activity).inflate(R.layout.item_list, parent, false)
- }
- return createViewHolder(view)
- }
-
- protected open fun createViewHolder(view: View): ViewHolder {
- return ViewHolder(view)
- }
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- val song = dataSet[position]
- val isChecked = isChecked(song)
- holder.itemView.isActivated = isChecked
- holder.menu?.isGone = isChecked
- holder.title?.text = getSongTitle(song)
- holder.text?.text = getSongText(song)
- holder.text2?.text = getSongText(song)
- loadAlbumCover(song, holder)
- val landscape = RetroUtil.isLandscape
- if ((PreferenceUtil.songGridSize > 2 && !landscape) || (PreferenceUtil.songGridSizeLand > 5 && landscape)) {
- holder.menu?.isVisible = false
- }
- }
-
- private fun setColors(color: MediaNotificationProcessor, holder: ViewHolder) {
- if (holder.paletteColorContainer != null) {
- holder.title?.setTextColor(color.primaryTextColor)
- holder.text?.setTextColor(color.secondaryTextColor)
- holder.paletteColorContainer?.setBackgroundColor(color.backgroundColor)
- holder.menu?.imageTintList = ColorStateList.valueOf(color.primaryTextColor)
- }
- holder.mask?.backgroundTintList = ColorStateList.valueOf(color.primaryTextColor)
- }
-
- protected open fun loadAlbumCover(song: Song, holder: ViewHolder) {
- if (holder.image == null) {
- return
- }
- Glide.with(activity)
- .asBitmapPalette()
- .songCoverOptions(song)
- .load(RetroGlideExtension.getSongModel(song))
- .into(object : RetroMusicColoredTarget(holder.image!!) {
- override fun onColorReady(colors: MediaNotificationProcessor) {
- setColors(colors, holder)
- }
- })
- }
-
- private fun getSongTitle(song: Song): String {
- return song.title
- }
-
- private fun getSongText(song: Song): String {
- return song.artistName
- }
-
- private fun getSongText2(song: Song): String {
- return song.albumName
- }
-
- override fun getItemCount(): Int {
- return dataSet.size
- }
-
- override fun getIdentifier(position: Int): Song? {
- return dataSet[position]
- }
-
- override fun getName(model: Song): String {
- return model.title
- }
-
- override fun onMultipleItemAction(menuItem: MenuItem, selection: List) {
- SongsMenuHelper.handleMenuClick(activity, selection, menuItem.itemId)
- }
-
- override fun getPopupText(position: Int): String {
- val sectionName: String? = when (PreferenceUtil.songSortOrder) {
- SortOrder.SongSortOrder.SONG_DEFAULT -> return MusicUtil.getSectionName(
- dataSet[position].title,
- true
- )
-
- SortOrder.SongSortOrder.SONG_A_Z, SortOrder.SongSortOrder.SONG_Z_A -> dataSet[position].title
- SortOrder.SongSortOrder.SONG_ALBUM -> dataSet[position].albumName
- SortOrder.SongSortOrder.SONG_ARTIST -> dataSet[position].artistName
- SortOrder.SongSortOrder.SONG_YEAR -> return MusicUtil.getYearString(dataSet[position].year)
- SortOrder.SongSortOrder.COMPOSER -> dataSet[position].composer
- SortOrder.SongSortOrder.SONG_ALBUM_ARTIST -> dataSet[position].albumArtist
- else -> {
- return ""
- }
- }
- return MusicUtil.getSectionName(sectionName)
- }
-
- open inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
- protected open var songMenuRes = SongMenuHelper.MENU_RES
- protected open val song: Song
- get() = dataSet[layoutPosition]
-
- init {
- menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
- override val song: Song
- get() = this@ViewHolder.song
-
- override val menuRes: Int
- get() = songMenuRes
-
- override fun onMenuItemClick(item: MenuItem): Boolean {
- return onSongMenuItemClick(item) || super.onMenuItemClick(item)
- }
- })
- }
-
- protected open fun onSongMenuItemClick(item: MenuItem): Boolean {
- if (image != null && image!!.isVisible) {
- when (item.itemId) {
- R.id.action_go_to_album -> {
- activity.findNavController(R.id.fragment_container)
- .navigate(
- R.id.albumDetailsFragment,
- bundleOf(EXTRA_ALBUM_ID to song.albumId)
- )
- return true
- }
- }
- }
- return false
- }
-
- override fun onClick(v: View?) {
- if (isInQuickSelectMode) {
- toggleChecked(layoutPosition)
- } else {
- MusicPlayerRemote.openQueue(dataSet, layoutPosition, true)
- }
- }
-
- override fun onLongClick(v: View?): Boolean {
- println("Long click")
- return toggleChecked(layoutPosition)
- }
- }
-
- companion object {
- val TAG: String = SongAdapter::class.java.simpleName
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutIconGenerator.java b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutIconGenerator.java
new file mode 100644
index 000000000..7c9eef617
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutIconGenerator.java
@@ -0,0 +1,71 @@
+package code.name.monkey.retromusic.appshortcuts;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.graphics.drawable.LayerDrawable;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+import android.util.TypedValue;
+
+import code.name.monkey.appthemehelper.ThemeStore;
+
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.util.PreferenceUtil;
+import code.name.monkey.retromusic.util.RetroUtil;
+
+/**
+ * @author Adrian Campos
+ */
+@RequiresApi(Build.VERSION_CODES.N_MR1)
+public final class AppShortcutIconGenerator {
+ public static Icon generateThemedIcon(Context context, int iconId) {
+ if (PreferenceUtil.getInstance(context).coloredAppShortcuts()){
+ return generateUserThemedIcon(context, iconId);
+ } else {
+ return generateDefaultThemedIcon(context, iconId);
+ }
+ }
+
+ private static Icon generateDefaultThemedIcon(Context context, int iconId) {
+ // Return an Icon of iconId with default colors
+ return generateThemedIcon(context, iconId,
+ context.getColor(R.color.app_shortcut_default_foreground),
+ context.getColor(R.color.app_shortcut_default_background)
+ );
+ }
+
+ private static Icon generateUserThemedIcon(Context context, int iconId) {
+ // Get background color from context's theme
+ final TypedValue typedColorBackground = new TypedValue();
+ context.getTheme().resolveAttribute(android.R.attr.colorBackground, typedColorBackground, true);
+
+ // Return an Icon of iconId with those colors
+ return generateThemedIcon(context, iconId,
+ ThemeStore.accentColor(context),
+ typedColorBackground.data
+ );
+ }
+
+ private static Icon generateThemedIcon(Context context, int iconId, int foregroundColor, int backgroundColor) {
+ // Get and tint foreground and background drawables
+ Drawable vectorDrawable = RetroUtil.getTintedVectorDrawable(context, iconId, foregroundColor);
+ Drawable backgroundDrawable = RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_app_shortcut_background, backgroundColor);
+
+ // Squash the two drawables together
+ LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{backgroundDrawable, vectorDrawable});
+
+ // Return as an Icon
+ return Icon.createWithBitmap(drawableToBitmap(layerDrawable));
+ }
+
+ private static Bitmap drawableToBitmap(Drawable drawable) {
+ Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ drawable.draw(canvas);
+ return bitmap;
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutIconGenerator.kt b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutIconGenerator.kt
deleted file mode 100644
index ad8f964e7..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutIconGenerator.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appshortcuts
-
-import android.content.Context
-import android.graphics.drawable.Icon
-import android.graphics.drawable.LayerDrawable
-import android.os.Build
-import android.util.TypedValue
-import androidx.annotation.RequiresApi
-import androidx.core.graphics.drawable.toBitmap
-import code.name.monkey.appthemehelper.ThemeStore
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.extensions.getTintedDrawable
-import code.name.monkey.retromusic.util.PreferenceUtil
-
-@RequiresApi(Build.VERSION_CODES.N_MR1)
-object AppShortcutIconGenerator {
- fun generateThemedIcon(context: Context, iconId: Int): Icon {
- return if (PreferenceUtil.isColoredAppShortcuts) {
- generateUserThemedIcon(context, iconId)
- } else {
- generateDefaultThemedIcon(context, iconId)
- }
- }
-
- private fun generateDefaultThemedIcon(context: Context, iconId: Int): Icon {
- // Return an Icon of iconId with default colors
- return generateThemedIcon(
- context,
- iconId,
- context.getColor(R.color.app_shortcut_default_foreground),
- context.getColor(R.color.app_shortcut_default_background)
- )
- }
-
- private fun generateUserThemedIcon(context: Context, iconId: Int): Icon {
- // Get background color from context's theme
- val typedColorBackground = TypedValue()
- context.theme.resolveAttribute(android.R.attr.colorBackground, typedColorBackground, true)
-
- // Return an Icon of iconId with those colors
- return generateThemedIcon(
- context, iconId, ThemeStore.accentColor(context), typedColorBackground.data
- )
- }
-
- private fun generateThemedIcon(
- context: Context,
- iconId: Int,
- foregroundColor: Int,
- backgroundColor: Int,
- ): Icon {
- // Get and tint foreground and background drawables
- val vectorDrawable = context.getTintedDrawable(iconId, foregroundColor)
- val backgroundDrawable =
- context.getTintedDrawable(R.drawable.ic_app_shortcut_background, backgroundColor)
-
- // Squash the two drawables together
- val layerDrawable = LayerDrawable(arrayOf(backgroundDrawable, vectorDrawable))
-
- // Return as an Icon
- return Icon.createWithBitmap(layerDrawable.toBitmap())
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutLauncherActivity.java b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutLauncherActivity.java
new file mode 100644
index 000000000..85e9c4021
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutLauncherActivity.java
@@ -0,0 +1,77 @@
+package code.name.monkey.retromusic.appshortcuts;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+import code.name.monkey.retromusic.model.Playlist;
+import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist;
+import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist;
+import code.name.monkey.retromusic.model.smartplaylist.ShuffleAllPlaylist;
+
+import code.name.monkey.retromusic.appshortcuts.shortcuttype.LastAddedShortcutType;
+import code.name.monkey.retromusic.appshortcuts.shortcuttype.ShuffleAllShortcutType;
+import code.name.monkey.retromusic.appshortcuts.shortcuttype.TopTracksShortcutType;
+import code.name.monkey.retromusic.service.MusicService;
+
+import static code.name.monkey.retromusic.Constants.*;
+
+/**
+ * @author Adrian Campos
+ */
+
+public class AppShortcutLauncherActivity extends Activity {
+ public static final String KEY_SHORTCUT_TYPE = "code.name.monkey.retromusic.appshortcuts.ShortcutType";
+
+ public static final int SHORTCUT_TYPE_SHUFFLE_ALL = 0;
+ public static final int SHORTCUT_TYPE_TOP_TRACKS = 1;
+ public static final int SHORTCUT_TYPE_LAST_ADDED = 2;
+ public static final int SHORTCUT_TYPE_NONE = 3;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ int shortcutType = SHORTCUT_TYPE_NONE;
+
+ // Set shortcutType from the intent extras
+ Bundle extras = getIntent().getExtras();
+ if (extras != null) {
+ //noinspection WrongConstant
+ shortcutType = extras.getInt(KEY_SHORTCUT_TYPE, SHORTCUT_TYPE_NONE);
+ }
+
+ switch (shortcutType) {
+ case SHORTCUT_TYPE_SHUFFLE_ALL:
+ startServiceWithPlaylist(MusicService.SHUFFLE_MODE_SHUFFLE,
+ new ShuffleAllPlaylist(getApplicationContext()));
+ DynamicShortcutManager.reportShortcutUsed(this, ShuffleAllShortcutType.getId());
+ break;
+ case SHORTCUT_TYPE_TOP_TRACKS:
+ startServiceWithPlaylist(MusicService.SHUFFLE_MODE_NONE,
+ new MyTopTracksPlaylist(getApplicationContext()));
+ DynamicShortcutManager.reportShortcutUsed(this, TopTracksShortcutType.getId());
+ break;
+ case SHORTCUT_TYPE_LAST_ADDED:
+ startServiceWithPlaylist(MusicService.SHUFFLE_MODE_NONE,
+ new LastAddedPlaylist(getApplicationContext()));
+ DynamicShortcutManager.reportShortcutUsed(this, LastAddedShortcutType.getId());
+ break;
+ }
+
+ finish();
+ }
+
+ private void startServiceWithPlaylist(int shuffleMode, Playlist playlist) {
+ Intent intent = new Intent(this, MusicService.class);
+ intent.setAction(ACTION_PLAY_PLAYLIST);
+
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(INTENT_EXTRA_PLAYLIST, playlist);
+ bundle.putInt(INTENT_EXTRA_SHUFFLE_MODE, shuffleMode);
+
+ intent.putExtras(bundle);
+
+ startService(intent);
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutLauncherActivity.kt b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutLauncherActivity.kt
deleted file mode 100644
index 9f10d795b..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutLauncherActivity.kt
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appshortcuts
-
-import android.app.Activity
-import android.content.Intent
-import android.os.Bundle
-import androidx.core.os.bundleOf
-import code.name.monkey.retromusic.appshortcuts.shortcuttype.LastAddedShortcutType
-import code.name.monkey.retromusic.appshortcuts.shortcuttype.ShuffleAllShortcutType
-import code.name.monkey.retromusic.appshortcuts.shortcuttype.TopTracksShortcutType
-import code.name.monkey.retromusic.extensions.extraNotNull
-import code.name.monkey.retromusic.model.Playlist
-import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist
-import code.name.monkey.retromusic.model.smartplaylist.ShuffleAllPlaylist
-import code.name.monkey.retromusic.model.smartplaylist.TopTracksPlaylist
-import code.name.monkey.retromusic.service.MusicService
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_PLAY_PLAYLIST
-import code.name.monkey.retromusic.service.MusicService.Companion.INTENT_EXTRA_PLAYLIST
-import code.name.monkey.retromusic.service.MusicService.Companion.INTENT_EXTRA_SHUFFLE_MODE
-import code.name.monkey.retromusic.service.MusicService.Companion.SHUFFLE_MODE_NONE
-import code.name.monkey.retromusic.service.MusicService.Companion.SHUFFLE_MODE_SHUFFLE
-
-class AppShortcutLauncherActivity : Activity() {
-
- public override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- when (extraNotNull(KEY_SHORTCUT_TYPE, SHORTCUT_TYPE_NONE).value) {
- SHORTCUT_TYPE_SHUFFLE_ALL -> {
- startServiceWithPlaylist(
- SHUFFLE_MODE_SHUFFLE, ShuffleAllPlaylist()
- )
- DynamicShortcutManager.reportShortcutUsed(this, ShuffleAllShortcutType.id)
- }
- SHORTCUT_TYPE_TOP_TRACKS -> {
- startServiceWithPlaylist(
- SHUFFLE_MODE_NONE, TopTracksPlaylist()
- )
- DynamicShortcutManager.reportShortcutUsed(this, TopTracksShortcutType.id)
- }
- SHORTCUT_TYPE_LAST_ADDED -> {
- startServiceWithPlaylist(
- SHUFFLE_MODE_NONE, LastAddedPlaylist()
- )
- DynamicShortcutManager.reportShortcutUsed(this, LastAddedShortcutType.id)
- }
- }
- finish()
- }
-
- private fun startServiceWithPlaylist(shuffleMode: Int, playlist: Playlist) {
- val intent = Intent(this, MusicService::class.java)
- intent.action = ACTION_PLAY_PLAYLIST
-
- val bundle = bundleOf(
- INTENT_EXTRA_PLAYLIST to playlist,
- INTENT_EXTRA_SHUFFLE_MODE to shuffleMode
- )
-
- intent.putExtras(bundle)
-
- startService(intent)
- }
-
- companion object {
- const val KEY_SHORTCUT_TYPE = "io.github.muntashirakon.Music.appshortcuts.ShortcutType"
- const val SHORTCUT_TYPE_SHUFFLE_ALL = 0L
- const val SHORTCUT_TYPE_TOP_TRACKS = 1L
- const val SHORTCUT_TYPE_LAST_ADDED = 2L
- const val SHORTCUT_TYPE_NONE = 4L
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/DynamicShortcutManager.java b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/DynamicShortcutManager.java
new file mode 100644
index 000000000..5fb280549
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/DynamicShortcutManager.java
@@ -0,0 +1,63 @@
+package code.name.monkey.retromusic.appshortcuts;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutManager;
+import android.graphics.drawable.Icon;
+import android.os.Build;
+
+import code.name.monkey.retromusic.appshortcuts.shortcuttype.LastAddedShortcutType;
+import code.name.monkey.retromusic.appshortcuts.shortcuttype.ShuffleAllShortcutType;
+import code.name.monkey.retromusic.appshortcuts.shortcuttype.TopTracksShortcutType;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Adrian Campos
+ */
+
+@TargetApi(Build.VERSION_CODES.N_MR1)
+public class DynamicShortcutManager {
+
+ private Context context;
+ private ShortcutManager shortcutManager;
+
+ public DynamicShortcutManager(Context context) {
+ this.context = context;
+ shortcutManager = this.context.getSystemService(ShortcutManager.class);
+ }
+
+ public static ShortcutInfo createShortcut(Context context, String id, String shortLabel, String longLabel, Icon icon, Intent intent) {
+ return new ShortcutInfo.Builder(context, id)
+ .setShortLabel(shortLabel)
+ .setLongLabel(longLabel)
+ .setIcon(icon)
+ .setIntent(intent)
+ .build();
+ }
+
+ public void initDynamicShortcuts() {
+ if (shortcutManager.getDynamicShortcuts().size() == 0) {
+ shortcutManager.setDynamicShortcuts(getDefaultShortcuts());
+ }
+ }
+
+ public void updateDynamicShortcuts() {
+ shortcutManager.updateShortcuts(getDefaultShortcuts());
+ }
+
+ public List getDefaultShortcuts() {
+ return (Arrays.asList(
+ new ShuffleAllShortcutType(context).getShortcutInfo(),
+ new TopTracksShortcutType(context).getShortcutInfo(),
+ new LastAddedShortcutType(context).getShortcutInfo()
+ ));
+ }
+
+ public static void reportShortcutUsed(Context context, String shortcutId){
+ context.getSystemService(ShortcutManager.class).reportShortcutUsed(shortcutId);
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/DynamicShortcutManager.kt b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/DynamicShortcutManager.kt
deleted file mode 100644
index a943ed0c8..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/DynamicShortcutManager.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appshortcuts
-
-import android.annotation.TargetApi
-import android.content.Context
-import android.content.Intent
-import android.content.pm.ShortcutInfo
-import android.content.pm.ShortcutManager
-import android.graphics.drawable.Icon
-import android.os.Build
-import androidx.core.content.getSystemService
-import code.name.monkey.retromusic.appshortcuts.shortcuttype.LastAddedShortcutType
-import code.name.monkey.retromusic.appshortcuts.shortcuttype.ShuffleAllShortcutType
-import code.name.monkey.retromusic.appshortcuts.shortcuttype.TopTracksShortcutType
-
-@TargetApi(Build.VERSION_CODES.N_MR1)
-class DynamicShortcutManager(private val context: Context) {
- private val shortcutManager: ShortcutManager? =
- this.context.getSystemService()
-
- private val defaultShortcuts: List
- get() = listOf(
- ShuffleAllShortcutType(context).shortcutInfo,
- TopTracksShortcutType(context).shortcutInfo,
- LastAddedShortcutType(context).shortcutInfo
- )
-
- fun initDynamicShortcuts() {
- // if (shortcutManager.dynamicShortcuts.size == 0) {
- shortcutManager?.dynamicShortcuts = defaultShortcuts
- // }
- }
-
- fun updateDynamicShortcuts() {
- shortcutManager?.updateShortcuts(defaultShortcuts)
- }
-
- companion object {
-
- fun createShortcut(
- context: Context,
- id: String,
- shortLabel: String,
- longLabel: String,
- icon: Icon,
- intent: Intent
- ): ShortcutInfo {
- return ShortcutInfo.Builder(context, id)
- .setShortLabel(shortLabel)
- .setLongLabel(longLabel)
- .setIcon(icon)
- .setIntent(intent)
- .build()
- }
-
- fun reportShortcutUsed(context: Context, shortcutId: String) {
- context.getSystemService()?.reportShortcutUsed(shortcutId)
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/BaseShortcutType.java b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/BaseShortcutType.java
new file mode 100644
index 000000000..28f16a7e4
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/BaseShortcutType.java
@@ -0,0 +1,50 @@
+package code.name.monkey.retromusic.appshortcuts.shortcuttype;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ShortcutInfo;
+import android.os.Build;
+import android.os.Bundle;
+
+import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity;
+
+
+/**
+ * @author Adrian Campos
+ */
+@TargetApi(Build.VERSION_CODES.N_MR1)
+public abstract class BaseShortcutType {
+
+ static final String ID_PREFIX = "code.name.monkey.retromusic.appshortcuts.id.";
+
+ Context context;
+
+ public BaseShortcutType(Context context) {
+ this.context = context;
+ }
+
+ static public String getId() {
+ return ID_PREFIX + "invalid";
+ }
+
+ abstract ShortcutInfo getShortcutInfo();
+
+ /**
+ * Creates an Intent that will launch MainActivtiy and immediately play {@param songs} in either shuffle or normal mode
+ *
+ * @param shortcutType Describes the type of shortcut to create (ShuffleAll, TopTracks, custom playlist, etc.)
+ * @return
+ */
+ Intent getPlaySongsIntent(int shortcutType) {
+ Intent intent = new Intent(context, AppShortcutLauncherActivity.class);
+ intent.setAction(Intent.ACTION_VIEW);
+
+ Bundle b = new Bundle();
+ b.putInt(AppShortcutLauncherActivity.KEY_SHORTCUT_TYPE, shortcutType);
+
+ intent.putExtras(b);
+
+ return intent;
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/BaseShortcutType.kt b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/BaseShortcutType.kt
deleted file mode 100644
index 4b0c7f3a0..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/BaseShortcutType.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appshortcuts.shortcuttype
-
-import android.annotation.TargetApi
-import android.content.Context
-import android.content.Intent
-import android.content.pm.ShortcutInfo
-import android.os.Build
-import androidx.core.os.bundleOf
-import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
-
-@TargetApi(Build.VERSION_CODES.N_MR1)
-abstract class BaseShortcutType(internal var context: Context) {
-
- internal abstract val shortcutInfo: ShortcutInfo
-
- /**
- * Creates an Intent that will launch MainActivtiy and immediately play {@param songs} in either shuffle or normal mode
- *
- * @param shortcutType Describes the type of shortcut to create (ShuffleAll, TopTracks, custom playlist, etc.)
- * @return
- */
- internal fun getPlaySongsIntent(shortcutType: Long): Intent {
- val intent = Intent(context, AppShortcutLauncherActivity::class.java)
- intent.action = Intent.ACTION_VIEW
- val b = bundleOf(AppShortcutLauncherActivity.KEY_SHORTCUT_TYPE to shortcutType)
- intent.putExtras(b)
- return intent
- }
-
- companion object {
- internal const val ID_PREFIX = "io.github.muntashirakon.Music.appshortcuts.id."
- val id: String
- get() = ID_PREFIX + "invalid"
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/LastAddedShortcutType.java b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/LastAddedShortcutType.java
new file mode 100644
index 000000000..72db3eeb8
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/LastAddedShortcutType.java
@@ -0,0 +1,34 @@
+package code.name.monkey.retromusic.appshortcuts.shortcuttype;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.pm.ShortcutInfo;
+import android.os.Build;
+
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator;
+import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity;
+
+
+/**
+ * @author Adrian Campos
+ */
+@TargetApi(Build.VERSION_CODES.N_MR1)
+public final class LastAddedShortcutType extends BaseShortcutType {
+ public LastAddedShortcutType(Context context) {
+ super(context);
+ }
+
+ public static String getId() {
+ return ID_PREFIX + "last_added";
+ }
+
+ public ShortcutInfo getShortcutInfo() {
+ return new ShortcutInfo.Builder(context, getId())
+ .setShortLabel(context.getString(R.string.app_shortcut_last_added_short))
+ .setLongLabel(context.getString(R.string.app_shortcut_last_added_long))
+ .setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_last_added))
+ .setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_LAST_ADDED))
+ .build();
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/LastAddedShortcutType.kt b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/LastAddedShortcutType.kt
deleted file mode 100644
index d0976042c..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/LastAddedShortcutType.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appshortcuts.shortcuttype
-
-import android.annotation.TargetApi
-import android.content.Context
-import android.content.pm.ShortcutInfo
-import android.os.Build
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator
-import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
-
-@TargetApi(Build.VERSION_CODES.N_MR1)
-class LastAddedShortcutType(context: Context) : BaseShortcutType(context) {
-
- override val shortcutInfo: ShortcutInfo
- get() = ShortcutInfo.Builder(
- context,
- id
- ).setShortLabel(context.getString(R.string.app_shortcut_last_added_short)).setLongLabel(
- context.getString(R.string.app_shortcut_last_added_long)
- ).setIcon(
- AppShortcutIconGenerator.generateThemedIcon(
- context,
- R.drawable.ic_app_shortcut_last_added
- )
- ).setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_LAST_ADDED))
- .build()
-
- companion object {
-
- val id: String
- get() = ID_PREFIX + "last_added"
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/ShuffleAllShortcutType.java b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/ShuffleAllShortcutType.java
new file mode 100644
index 000000000..be3ba0088
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/ShuffleAllShortcutType.java
@@ -0,0 +1,35 @@
+package code.name.monkey.retromusic.appshortcuts.shortcuttype;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.pm.ShortcutInfo;
+import android.os.Build;
+
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator;
+import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity;
+
+
+
+/**
+ * @author Adrian Campos
+ */
+@TargetApi(Build.VERSION_CODES.N_MR1)
+public final class ShuffleAllShortcutType extends BaseShortcutType {
+ public ShuffleAllShortcutType(Context context) {
+ super(context);
+ }
+
+ public static String getId() {
+ return ID_PREFIX + "shuffle_all";
+ }
+
+ public ShortcutInfo getShortcutInfo() {
+ return new ShortcutInfo.Builder(context, getId())
+ .setShortLabel(context.getString(R.string.app_shortcut_shuffle_all_short))
+ .setLongLabel(context.getString(R.string.app_shortcut_shuffle_all_long))
+ .setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_shuffle_all))
+ .setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_SHUFFLE_ALL))
+ .build();
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/ShuffleAllShortcutType.kt b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/ShuffleAllShortcutType.kt
deleted file mode 100644
index 21855cacd..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/ShuffleAllShortcutType.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appshortcuts.shortcuttype
-
-import android.annotation.TargetApi
-import android.content.Context
-import android.content.pm.ShortcutInfo
-import android.os.Build
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator
-import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
-
-@TargetApi(Build.VERSION_CODES.N_MR1)
-class ShuffleAllShortcutType(context: Context) : BaseShortcutType(context) {
-
- override val shortcutInfo: ShortcutInfo
- get() = ShortcutInfo.Builder(context, id)
- .setShortLabel(context.getString(R.string.app_shortcut_shuffle_all_short))
- .setLongLabel(context.getString(R.string.app_shortcut_shuffle_all_long))
- .setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_shuffle_all))
- .setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_SHUFFLE_ALL))
- .build()
-
- companion object {
-
- val id: String
- get() = ID_PREFIX + "shuffle_all"
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/TopTracksShortcutType.java b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/TopTracksShortcutType.java
new file mode 100644
index 000000000..3e78db33c
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/TopTracksShortcutType.java
@@ -0,0 +1,35 @@
+package code.name.monkey.retromusic.appshortcuts.shortcuttype;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.pm.ShortcutInfo;
+import android.os.Build;
+
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator;
+import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity;
+
+
+
+/**
+ * @author Adrian Campos
+ */
+@TargetApi(Build.VERSION_CODES.N_MR1)
+public final class TopTracksShortcutType extends BaseShortcutType {
+ public TopTracksShortcutType(Context context) {
+ super(context);
+ }
+
+ public static String getId() {
+ return ID_PREFIX + "top_tracks";
+ }
+
+ public ShortcutInfo getShortcutInfo() {
+ return new ShortcutInfo.Builder(context, getId())
+ .setShortLabel(context.getString(R.string.app_shortcut_top_tracks_short))
+ .setLongLabel(context.getString(R.string.app_shortcut_top_tracks_long))
+ .setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_top_tracks))
+ .setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_TOP_TRACKS))
+ .build();
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/TopTracksShortcutType.kt b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/TopTracksShortcutType.kt
deleted file mode 100644
index fc0fa9f47..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/shortcuttype/TopTracksShortcutType.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appshortcuts.shortcuttype
-
-import android.annotation.TargetApi
-import android.content.Context
-import android.content.pm.ShortcutInfo
-import android.os.Build
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator
-import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
-
-@TargetApi(Build.VERSION_CODES.N_MR1)
-class TopTracksShortcutType(context: Context) : BaseShortcutType(context) {
-
- override val shortcutInfo: ShortcutInfo
- get() = ShortcutInfo.Builder(
- context, id
- ).setShortLabel(context.getString(R.string.app_shortcut_top_tracks_short)).setLongLabel(
- context.getString(R.string.app_shortcut_top_tracks_long)
- ).setIcon(
- AppShortcutIconGenerator.generateThemedIcon(
- context, R.drawable.ic_app_shortcut_top_tracks
- )
- ).setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_TOP_TRACKS))
- .build()
-
- companion object {
-
- val id: String
- get() = ID_PREFIX + "top_tracks"
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetBig.java b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetBig.java
new file mode 100644
index 000000000..4b90e941f
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetBig.java
@@ -0,0 +1,171 @@
+package code.name.monkey.retromusic.appwidgets;
+
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Point;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.RemoteViews;
+import code.name.monkey.appthemehelper.util.MaterialValueHelper;
+import code.name.monkey.retromusic.Constants;
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget;
+import code.name.monkey.retromusic.glide.SongGlideRequest;
+import code.name.monkey.retromusic.model.Song;
+import code.name.monkey.retromusic.service.MusicService;
+import code.name.monkey.retromusic.ui.activities.MainActivity;
+import code.name.monkey.retromusic.util.RetroUtil;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.request.animation.GlideAnimation;
+import com.bumptech.glide.request.target.SimpleTarget;
+import com.bumptech.glide.request.target.Target;
+
+public class AppWidgetBig extends BaseAppWidget {
+
+ public static final String NAME = "app_widget_big";
+
+ private static AppWidgetBig mInstance;
+ private Target target; // for cancellation
+
+ public static synchronized AppWidgetBig getInstance() {
+ if (mInstance == null) {
+ mInstance = new AppWidgetBig();
+ }
+ return mInstance;
+ }
+
+ /**
+ * Initialize given widgets to default state, where we launch Music on default click and hide
+ * actions if service not running.
+ */
+ protected void defaultAppWidget(final Context context, final int[] appWidgetIds) {
+ final RemoteViews appWidgetView = new RemoteViews(context.getPackageName(),
+ R.layout.app_widget_big);
+
+ appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE);
+ appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art);
+ appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(
+ RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp,
+ MaterialValueHelper.getPrimaryTextColor(context, false)), 1f));
+ appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(
+ RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp,
+ MaterialValueHelper.getPrimaryTextColor(context, false)), 1f));
+ appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(
+ RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_24dp,
+ MaterialValueHelper.getPrimaryTextColor(context, false)), 1f));
+
+ linkButtons(context, appWidgetView);
+ pushUpdate(context, appWidgetIds, appWidgetView);
+ }
+
+ /**
+ * Update all active widget instances by pushing changes
+ */
+ public void performUpdate(final MusicService service, final int[] appWidgetIds) {
+ final RemoteViews appWidgetView = new RemoteViews(service.getPackageName(),
+ R.layout.app_widget_big);
+
+ final boolean isPlaying = service.isPlaying();
+ final Song song = service.getCurrentSong();
+
+ // Set the titles and artwork
+ if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
+ appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE);
+ } else {
+ appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE);
+ appWidgetView.setTextViewText(R.id.title, song.title);
+ appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song));
+ }
+
+ // Set correct drawable for pause state
+ int playPauseRes =
+ isPlaying ? R.drawable.ic_pause_white_24dp : R.drawable.ic_play_arrow_white_24dp;
+ appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(
+ RetroUtil.getTintedVectorDrawable(service, playPauseRes,
+ MaterialValueHelper.getPrimaryTextColor(service, false)), 1f));
+
+ // Set prev/next button drawables
+ appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(
+ RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp,
+ MaterialValueHelper.getPrimaryTextColor(service, false)), 1f));
+ appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(
+ RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp,
+ MaterialValueHelper.getPrimaryTextColor(service, false)), 1f));
+
+ // Link actions buttons to intents
+ linkButtons(service, appWidgetView);
+
+ // Load the album cover async and push the update on completion
+ Point p = RetroUtil.getScreenSize(service);
+ final int widgetImageSize = Math.min(p.x, p.y);
+ final Context appContext = service.getApplicationContext();
+ service.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (target != null) {
+ Glide.clear(target);
+ }
+ target = SongGlideRequest.Builder.from(Glide.with(appContext), song)
+ .checkIgnoreMediaStore(appContext)
+ .asBitmap().build()
+ .into(new SimpleTarget(widgetImageSize, widgetImageSize) {
+ @Override
+ public void onResourceReady(Bitmap resource,
+ GlideAnimation super Bitmap> glideAnimation) {
+ update(resource);
+ }
+
+ @Override
+ public void onLoadFailed(Exception e, Drawable errorDrawable) {
+ super.onLoadFailed(e, errorDrawable);
+ update(null);
+ }
+
+ private void update(@Nullable Bitmap bitmap) {
+ if (bitmap == null) {
+ appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art);
+ } else {
+ appWidgetView.setImageViewBitmap(R.id.image, bitmap);
+ }
+ pushUpdate(appContext, appWidgetIds, appWidgetView);
+ }
+ });
+ }
+ });
+ }
+
+ /**
+ * Link up various button actions using {@link PendingIntent}.
+ */
+ private void linkButtons(final Context context, final RemoteViews views) {
+ Intent action;
+ PendingIntent pendingIntent;
+
+ final ComponentName serviceName = new ComponentName(context, MusicService.class);
+
+ // Home
+ action = new Intent(context, MainActivity.class);
+ action.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ pendingIntent = PendingIntent.getActivity(context, 0, action, 0);
+ views.setOnClickPendingIntent(R.id.clickable_area, pendingIntent);
+
+ // Previous track
+ pendingIntent = buildPendingIntent(context, Constants.ACTION_REWIND, serviceName);
+ views.setOnClickPendingIntent(R.id.button_prev, pendingIntent);
+
+ // Play and pause
+ pendingIntent = buildPendingIntent(context, Constants.ACTION_TOGGLE_PAUSE, serviceName);
+ views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent);
+
+ // Next track
+ pendingIntent = buildPendingIntent(context, Constants.ACTION_SKIP, serviceName);
+ views.setOnClickPendingIntent(R.id.button_next, pendingIntent);
+
+
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetBig.kt b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetBig.kt
deleted file mode 100644
index 7d9497209..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetBig.kt
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appwidgets
-
-import android.app.PendingIntent
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.graphics.Bitmap
-import android.graphics.drawable.Drawable
-import android.view.View
-import android.widget.RemoteViews
-import androidx.core.graphics.drawable.toBitmap
-import code.name.monkey.appthemehelper.util.MaterialValueHelper
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.MainActivity
-import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
-import code.name.monkey.retromusic.extensions.getTintedDrawable
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.service.MusicService
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_SKIP
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_TOGGLE_PAUSE
-import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.RetroUtil
-import com.bumptech.glide.Glide
-import com.bumptech.glide.request.target.CustomTarget
-import com.bumptech.glide.request.target.Target
-import com.bumptech.glide.request.transition.Transition
-
-class AppWidgetBig : BaseAppWidget() {
- private var target: Target? = null // for cancellation
-
- /**
- * Initialize given widgets to default state, where we launch Music on default click and hide
- * actions if service not running.
- */
- override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
- val appWidgetView = RemoteViews(
- context.packageName, R.layout.app_widget_big
- )
-
- appWidgetView.setViewVisibility(
- R.id.media_titles,
- View.INVISIBLE
- )
- appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
- appWidgetView.setImageViewBitmap(
- R.id.button_next, context.getTintedDrawable(
- R.drawable.ic_skip_next,
- MaterialValueHelper.getPrimaryTextColor(context, false)
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_prev,
- context.getTintedDrawable(
- R.drawable.ic_skip_previous,
- MaterialValueHelper.getPrimaryTextColor(context, false)
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- context.getTintedDrawable(
- R.drawable.ic_play_arrow_white_32dp,
- MaterialValueHelper.getPrimaryTextColor(context, false)
- ).toBitmap()
- )
-
- linkButtons(context, appWidgetView)
- pushUpdate(context, appWidgetIds, appWidgetView)
- }
-
- /**
- * Update all active widget instances by pushing changes
- */
- override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
- val appWidgetView = RemoteViews(
- service.packageName, R.layout.app_widget_big
- )
-
- val isPlaying = service.isPlaying
- val song = service.currentSong
-
- // Set the titles and artwork
- if (song.title.isEmpty() && song.artistName.isEmpty()) {
- appWidgetView.setViewVisibility(
- R.id.media_titles,
- View.INVISIBLE
- )
- } else {
- appWidgetView.setViewVisibility(
- R.id.media_titles,
- View.VISIBLE
- )
- appWidgetView.setTextViewText(R.id.title, song.title)
- appWidgetView.setTextViewText(
- R.id.text,
- getSongArtistAndAlbum(song)
- )
- }
-
- val primaryColor = MaterialValueHelper.getPrimaryTextColor(service, false)
- // Set correct drawable for pause state
- val playPauseRes =
- if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play_arrow_white_32dp
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- service.getTintedDrawable(
- playPauseRes,
- primaryColor
- ).toBitmap()
- )
-
- // Set prev/next button drawables
- appWidgetView.setImageViewBitmap(
- R.id.button_next,
- service.getTintedDrawable(
- R.drawable.ic_skip_next,
- primaryColor
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_prev,
- service.getTintedDrawable(
- R.drawable.ic_skip_previous,
- primaryColor
- ).toBitmap()
- )
-
- // Link actions buttons to intents
- linkButtons(service, appWidgetView)
-
- // Load the album cover async and push the update on completion
- val p = RetroUtil.getScreenSize(service)
- val widgetImageSize = p.x.coerceAtMost(p.y)
- val appContext = service.applicationContext
- service.runOnUiThread {
- if (target != null) {
- Glide.with(service).clear(target)
- }
- target = Glide.with(appContext)
- .asBitmap()
- //.checkIgnoreMediaStore()
- .load(RetroGlideExtension.getSongModel(song))
- .into(object : CustomTarget(widgetImageSize, widgetImageSize) {
- override fun onResourceReady(
- resource: Bitmap,
- transition: Transition?,
- ) {
- update(resource)
- }
-
- override fun onLoadFailed(errorDrawable: Drawable?) {
- super.onLoadFailed(errorDrawable)
- update(null)
- }
-
- override fun onLoadCleared(placeholder: Drawable?) {}
-
- private fun update(bitmap: Bitmap?) {
- if (bitmap == null) {
- appWidgetView.setImageViewResource(
- R.id.image,
- R.drawable.default_audio_art
- )
- } else {
- appWidgetView.setImageViewBitmap(R.id.image, bitmap)
- }
- pushUpdate(appContext, appWidgetIds, appWidgetView)
- }
- })
- }
- }
-
- /**
- * Link up various button actions using [PendingIntent].
- */
- private fun linkButtons(context: Context, views: RemoteViews) {
- val action = Intent(context, MainActivity::class.java)
- .putExtra(
- MainActivity.EXPAND_PANEL,
- PreferenceUtil.isExpandPanel
- )
-
- val serviceName = ComponentName(context, MusicService::class.java)
-
- // Home
- action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
- var pendingIntent =
- PendingIntent.getActivity(
- context, 0, action, if (VersionUtils.hasMarshmallow())
- PendingIntent.FLAG_IMMUTABLE
- else 0
- )
- views.setOnClickPendingIntent(R.id.clickable_area, pendingIntent)
-
- // Previous track
- pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
- views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
-
- // Play and pause
- pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
- views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
-
- // Next track
- pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
- views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
- }
-
- companion object {
-
- const val NAME: String = "app_widget_big"
- private var mInstance: AppWidgetBig? = null
-
- val instance: AppWidgetBig
- @Synchronized get() {
- if (mInstance == null) {
- mInstance = AppWidgetBig()
- }
- return mInstance!!
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetCard.java b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetCard.java
new file mode 100644
index 000000000..d7c080672
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetCard.java
@@ -0,0 +1,194 @@
+package code.name.monkey.retromusic.appwidgets;
+
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.Nullable;
+import android.support.v7.graphics.Palette;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.RemoteViews;
+import code.name.monkey.appthemehelper.util.MaterialValueHelper;
+import code.name.monkey.retromusic.Constants;
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget;
+import code.name.monkey.retromusic.glide.SongGlideRequest;
+import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
+import code.name.monkey.retromusic.model.Song;
+import code.name.monkey.retromusic.service.MusicService;
+import code.name.monkey.retromusic.ui.activities.MainActivity;
+import code.name.monkey.retromusic.util.RetroUtil;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.request.animation.GlideAnimation;
+import com.bumptech.glide.request.target.SimpleTarget;
+import com.bumptech.glide.request.target.Target;
+
+public class AppWidgetCard extends BaseAppWidget {
+
+ public static final String NAME = "app_widget_card";
+
+ private static AppWidgetCard mInstance;
+ private static int imageSize = 0;
+ private static float cardRadius = 0f;
+ private Target target; // for cancellation
+
+ public static synchronized AppWidgetCard getInstance() {
+ if (mInstance == null) {
+ mInstance = new AppWidgetCard();
+ }
+ return mInstance;
+ }
+
+ /**
+ * Initialize given widgets to default state, where we launch Music on default click and hide
+ * actions if service not running.
+ */
+ protected void defaultAppWidget(final Context context, final int[] appWidgetIds) {
+ final RemoteViews appWidgetView = new RemoteViews(context.getPackageName(),
+ R.layout.app_widget_card);
+
+ appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE);
+ appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art);
+ appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(
+ RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp,
+ MaterialValueHelper.getSecondaryTextColor(context, true)), 1f));
+ appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(
+ RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp,
+ MaterialValueHelper.getSecondaryTextColor(context, true)), 1f));
+ appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(
+ RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_24dp,
+ MaterialValueHelper.getSecondaryTextColor(context, true)), 1f));
+
+ linkButtons(context, appWidgetView);
+ pushUpdate(context, appWidgetIds, appWidgetView);
+ }
+
+ /**
+ * Update all active widget instances by pushing changes
+ */
+ public void performUpdate(final MusicService service, final int[] appWidgetIds) {
+ final RemoteViews appWidgetView = new RemoteViews(service.getPackageName(),
+ R.layout.app_widget_card);
+
+ final boolean isPlaying = service.isPlaying();
+ final Song song = service.getCurrentSong();
+
+ // Set the titles and artwork
+ if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
+ appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE);
+ } else {
+ appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE);
+ appWidgetView.setTextViewText(R.id.title, song.title);
+ appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song));
+ }
+
+ // Set correct drawable for pause state
+ int playPauseRes =
+ isPlaying ? R.drawable.ic_pause_white_24dp : R.drawable.ic_play_arrow_white_24dp;
+ appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(
+ RetroUtil.getTintedVectorDrawable(service, playPauseRes,
+ MaterialValueHelper.getSecondaryTextColor(service, true)), 1f));
+
+ // Set prev/next button drawables
+ appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(
+ RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp,
+ MaterialValueHelper.getSecondaryTextColor(service, true)), 1f));
+ appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(
+ RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp,
+ MaterialValueHelper.getSecondaryTextColor(service, true)), 1f));
+
+ // Link actions buttons to intents
+ linkButtons(service, appWidgetView);
+
+ if (imageSize == 0) {
+ imageSize = service.getResources().getDimensionPixelSize(R.dimen.app_widget_card_image_size);
+ }
+ if (cardRadius == 0f) {
+ cardRadius = service.getResources().getDimension(R.dimen.app_widget_card_radius);
+ }
+
+ // Load the album cover async and push the update on completion
+ service.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (target != null) {
+ Glide.clear(target);
+ }
+ target = SongGlideRequest.Builder.from(Glide.with(service), song)
+ .checkIgnoreMediaStore(service)
+ .generatePalette(service).build()
+ .centerCrop()
+ .into(new SimpleTarget(imageSize, imageSize) {
+ @Override
+ public void onResourceReady(BitmapPaletteWrapper resource,
+ GlideAnimation super BitmapPaletteWrapper> glideAnimation) {
+ Palette palette = resource.getPalette();
+ update(resource.getBitmap(), palette.getVibrantColor(palette
+ .getMutedColor(MaterialValueHelper.getSecondaryTextColor(service, true))));
+ }
+
+ @Override
+ public void onLoadFailed(Exception e, Drawable errorDrawable) {
+ super.onLoadFailed(e, errorDrawable);
+ update(null, MaterialValueHelper.getSecondaryTextColor(service, true));
+ }
+
+ private void update(@Nullable Bitmap bitmap, int color) {
+ // Set correct drawable for pause state
+ int playPauseRes = isPlaying ? R.drawable.ic_pause_white_24dp
+ : R.drawable.ic_play_arrow_white_24dp;
+ appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause,
+ createBitmap(RetroUtil.getTintedVectorDrawable(service, playPauseRes, color), 1f));
+
+ // Set prev/next button drawables
+ appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(
+ RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp,
+ color), 1f));
+ appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(
+ RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp,
+ color), 1f));
+
+ final Drawable image = getAlbumArtDrawable(service.getResources(), bitmap);
+ final Bitmap roundedBitmap = createRoundedBitmap(image, imageSize, imageSize,
+ cardRadius, 0, cardRadius, 0);
+ appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap);
+
+ pushUpdate(service, appWidgetIds, appWidgetView);
+ }
+ });
+ }
+ });
+ }
+
+ /**
+ * Link up various button actions using {@link PendingIntent}.
+ */
+ private void linkButtons(final Context context, final RemoteViews views) {
+ Intent action;
+ PendingIntent pendingIntent;
+
+ final ComponentName serviceName = new ComponentName(context, MusicService.class);
+
+ // Home
+ action = new Intent(context, MainActivity.class);
+ action.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ pendingIntent = PendingIntent.getActivity(context, 0, action, 0);
+ views.setOnClickPendingIntent(R.id.image, pendingIntent);
+ views.setOnClickPendingIntent(R.id.media_titles, pendingIntent);
+
+ // Previous track
+ pendingIntent = buildPendingIntent(context, Constants.ACTION_REWIND, serviceName);
+ views.setOnClickPendingIntent(R.id.button_prev, pendingIntent);
+
+ // Play and pause
+ pendingIntent = buildPendingIntent(context, Constants.ACTION_TOGGLE_PAUSE, serviceName);
+ views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent);
+
+ // Next track
+ pendingIntent = buildPendingIntent(context, Constants.ACTION_SKIP, serviceName);
+ views.setOnClickPendingIntent(R.id.button_next, pendingIntent);
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetCard.kt b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetCard.kt
deleted file mode 100644
index 471d908d6..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetCard.kt
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appwidgets
-
-import android.app.PendingIntent
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.graphics.Bitmap
-import android.graphics.drawable.Drawable
-import android.view.View
-import android.widget.RemoteViews
-import androidx.core.graphics.drawable.toBitmap
-import code.name.monkey.appthemehelper.util.MaterialValueHelper
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.MainActivity
-import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
-import code.name.monkey.retromusic.extensions.getTintedDrawable
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
-import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
-import code.name.monkey.retromusic.service.MusicService
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_SKIP
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_TOGGLE_PAUSE
-import code.name.monkey.retromusic.util.PreferenceUtil
-import com.bumptech.glide.Glide
-import com.bumptech.glide.request.target.CustomTarget
-import com.bumptech.glide.request.target.Target
-import com.bumptech.glide.request.transition.Transition
-
-class AppWidgetCard : BaseAppWidget() {
- private var target: Target? = null // for cancellation
-
- /**
- * Initialize given widgets to default state, where we launch Music on default click and hide
- * actions if service not running.
- */
- override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
- val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_card)
-
- appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
- appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
- val secondaryColor = MaterialValueHelper.getSecondaryTextColor(context, true)
- appWidgetView.setImageViewBitmap(
- R.id.button_next,
- context.getTintedDrawable(
- R.drawable.ic_skip_next,
- secondaryColor
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_prev,
- context.getTintedDrawable(
- R.drawable.ic_skip_previous,
- secondaryColor
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- context.getTintedDrawable(
- R.drawable.ic_play_arrow_white_32dp,
- secondaryColor
- ).toBitmap()
- )
-
- linkButtons(context, appWidgetView)
- pushUpdate(context, appWidgetIds, appWidgetView)
- }
-
- /**
- * Update all active widget instances by pushing changes
- */
- override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
- val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_card)
-
- val isPlaying = service.isPlaying
- val song = service.currentSong
-
- // Set the titles and artwork
- if (song.title.isEmpty() && song.artistName.isEmpty()) {
- appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
- } else {
- appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
- appWidgetView.setTextViewText(R.id.title, song.title)
- appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song))
- }
-
- // Set correct drawable for pause state
- val playPauseRes =
- if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play_arrow_white_32dp
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- service.getTintedDrawable(
- playPauseRes,
- MaterialValueHelper.getSecondaryTextColor(service, true)
- ).toBitmap()
- )
-
- // Set prev/next button drawables
- appWidgetView.setImageViewBitmap(
- R.id.button_next,
- service.getTintedDrawable(
- R.drawable.ic_skip_next,
- MaterialValueHelper.getSecondaryTextColor(service, true)
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_prev,
- service.getTintedDrawable(
- R.drawable.ic_skip_previous,
- MaterialValueHelper.getSecondaryTextColor(service, true)
- ).toBitmap()
- )
-
- // Link actions buttons to intents
- linkButtons(service, appWidgetView)
-
- if (imageSize == 0) {
- imageSize =
- service.resources.getDimensionPixelSize(R.dimen.app_widget_card_image_size)
- }
- if (cardRadius == 0f) {
- cardRadius =
- service.resources.getDimension(R.dimen.app_widget_card_radius)
- }
-
- // Load the album cover async and push the update on completion
- service.runOnUiThread {
- if (target != null) {
- Glide.with(service).clear(target)
- }
- target = Glide.with(service)
- .asBitmapPalette()
- .songCoverOptions(song)
- .load(RetroGlideExtension.getSongModel(song))
- .centerCrop()
- .into(object : CustomTarget(imageSize, imageSize) {
- override fun onResourceReady(
- resource: BitmapPaletteWrapper,
- transition: Transition?,
- ) {
- val palette = resource.palette
- update(
- resource.bitmap, palette.getVibrantColor(
- palette.getMutedColor(
- MaterialValueHelper.getSecondaryTextColor(
- service, true
- )
- )
- )
- )
- }
-
- override fun onLoadFailed(errorDrawable: Drawable?) {
- super.onLoadFailed(errorDrawable)
- update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
- }
-
- override fun onLoadCleared(placeholder: Drawable?) {}
-
- private fun update(bitmap: Bitmap?, color: Int) {
- // Set correct drawable for pause state
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- service.getTintedDrawable(playPauseRes, color).toBitmap()
- )
-
- // Set prev/next button drawables
- appWidgetView.setImageViewBitmap(
- R.id.button_next,
- service.getTintedDrawable(R.drawable.ic_skip_next, color).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_prev,
- service.getTintedDrawable(R.drawable.ic_skip_previous, color).toBitmap()
- )
-
- val image = getAlbumArtDrawable(service, bitmap)
- val roundedBitmap = createRoundedBitmap(
- image, imageSize, imageSize, cardRadius, 0F, cardRadius, 0F
- )
- appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
-
- pushUpdate(service, appWidgetIds, appWidgetView)
- }
- })
- }
- }
-
- /**
- * Link up various button actions using [PendingIntent].
- */
- private fun linkButtons(context: Context, views: RemoteViews) {
- val action = Intent(context, MainActivity::class.java)
- .putExtra(
- MainActivity.EXPAND_PANEL,
- PreferenceUtil.isExpandPanel
- )
-
- val serviceName = ComponentName(context, MusicService::class.java)
-
- // Home
- action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
- var pendingIntent =
- PendingIntent.getActivity(
- context, 0, action, if (VersionUtils.hasMarshmallow())
- PendingIntent.FLAG_IMMUTABLE
- else 0
- )
- views.setOnClickPendingIntent(R.id.image, pendingIntent)
- views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
-
- // Previous track
- pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
- views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
-
- // Play and pause
- pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
- views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
-
- // Next track
- pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
- views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
- }
-
- companion object {
-
- const val NAME = "app_widget_card"
-
- private var mInstance: AppWidgetCard? = null
- private var imageSize = 0
- private var cardRadius = 0f
-
- val instance: AppWidgetCard
- @Synchronized get() {
- if (mInstance == null) {
- mInstance = AppWidgetCard()
- }
- return mInstance!!
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetCircle.kt b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetCircle.kt
deleted file mode 100644
index cb3ae0e44..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetCircle.kt
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appwidgets
-
-import android.app.PendingIntent
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.graphics.Bitmap
-import android.graphics.drawable.Drawable
-import android.widget.RemoteViews
-import androidx.core.graphics.drawable.toBitmap
-import code.name.monkey.appthemehelper.util.MaterialValueHelper
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.MainActivity
-import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
-import code.name.monkey.retromusic.extensions.getTintedDrawable
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
-import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
-import code.name.monkey.retromusic.service.MusicService
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_TOGGLE_PAUSE
-import code.name.monkey.retromusic.service.MusicService.Companion.TOGGLE_FAVORITE
-import code.name.monkey.retromusic.util.MusicUtil
-import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.RetroUtil
-import com.bumptech.glide.Glide
-import com.bumptech.glide.request.RequestOptions
-import com.bumptech.glide.request.target.CustomTarget
-import com.bumptech.glide.request.target.Target
-import com.bumptech.glide.request.transition.Transition
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.runBlocking
-
-class AppWidgetCircle : BaseAppWidget() {
- private var target: Target? = null // for cancellation
-
- /**
- * Initialize given widgets to default state, where we launch Music on default click and hide
- * actions if service not running.
- */
- override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
- val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_circle)
-
- appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
- val secondaryColor = MaterialValueHelper.getSecondaryTextColor(context, true)
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- context.getTintedDrawable(
- R.drawable.ic_play_arrow,
- secondaryColor
- ).toBitmap()
- )
-
- linkButtons(context, appWidgetView)
- pushUpdate(context, appWidgetIds, appWidgetView)
- }
-
- /**
- * Update all active widget instances by pushing changes
- */
- override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
- val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_circle)
-
- val isPlaying = service.isPlaying
- val song = service.currentSong
-
- // Set correct drawable for pause state
- val playPauseRes =
- if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play_arrow
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- service.getTintedDrawable(
- playPauseRes,
- MaterialValueHelper.getSecondaryTextColor(service, true)
- ).toBitmap()
- )
- val isFavorite = runBlocking(Dispatchers.IO) {
- return@runBlocking MusicUtil.isFavorite(song)
- }
- val favoriteRes =
- if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_favorite,
- service.getTintedDrawable(
- favoriteRes,
- MaterialValueHelper.getSecondaryTextColor(service, true)
- ).toBitmap()
- )
-
- // Link actions buttons to intents
- linkButtons(service, appWidgetView)
-
- if (imageSize == 0) {
- val p = RetroUtil.getScreenSize(service)
- imageSize = p.x.coerceAtMost(p.y)
- }
-
- // Load the album cover async and push the update on completion
- service.runOnUiThread {
- if (target != null) {
- Glide.with(service).clear(target)
- }
- target = Glide.with(service)
- .asBitmapPalette()
- .songCoverOptions(song)
- .load(RetroGlideExtension.getSongModel(song))
- .apply(RequestOptions.circleCropTransform())
- .into(object : CustomTarget(imageSize, imageSize) {
- override fun onResourceReady(
- resource: BitmapPaletteWrapper,
- transition: Transition?,
- ) {
- val palette = resource.palette
- update(
- resource.bitmap, palette.getVibrantColor(
- palette.getMutedColor(
- MaterialValueHelper.getSecondaryTextColor(
- service, true
- )
- )
- )
- )
- }
-
- override fun onLoadFailed(errorDrawable: Drawable?) {
- super.onLoadFailed(errorDrawable)
- update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
- }
-
- private fun update(bitmap: Bitmap?, color: Int) {
- // Set correct drawable for pause state
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- service.getTintedDrawable(
- playPauseRes, color
- ).toBitmap()
- )
-
- // Set favorite button drawables
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_favorite,
- service.getTintedDrawable(
- favoriteRes, color
- ).toBitmap()
- )
- if (bitmap != null) {
- appWidgetView.setImageViewBitmap(R.id.image, bitmap)
- }
-
- pushUpdate(service, appWidgetIds, appWidgetView)
- }
-
- override fun onLoadCleared(placeholder: Drawable?) {}
- })
- }
- }
-
- /**
- * Link up various button actions using [PendingIntent].
- */
- private fun linkButtons(context: Context, views: RemoteViews) {
- val action = Intent(context, MainActivity::class.java)
- .putExtra(
- MainActivity.EXPAND_PANEL,
- PreferenceUtil.isExpandPanel
- )
-
- val serviceName = ComponentName(context, MusicService::class.java)
-
- // Home
- action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
- var pendingIntent =
- PendingIntent.getActivity(
- context, 0, action, if (VersionUtils.hasMarshmallow())
- PendingIntent.FLAG_IMMUTABLE
- else 0
- )
- views.setOnClickPendingIntent(R.id.image, pendingIntent)
- // Favorite track
- pendingIntent = buildPendingIntent(context, TOGGLE_FAVORITE, serviceName)
- views.setOnClickPendingIntent(R.id.button_toggle_favorite, pendingIntent)
-
- // Play and pause
- pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
- views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
- }
-
- companion object {
-
- const val NAME = "app_widget_circle"
-
- private var mInstance: AppWidgetCircle? = null
- private var imageSize = 0
-
- val instance: AppWidgetCircle
- @Synchronized get() {
- if (mInstance == null) {
- mInstance = AppWidgetCircle()
- }
- return mInstance!!
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetClassic.java b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetClassic.java
new file mode 100644
index 000000000..120b9952c
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetClassic.java
@@ -0,0 +1,181 @@
+package code.name.monkey.retromusic.appwidgets;
+
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.Nullable;
+import android.support.v7.graphics.Palette;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.RemoteViews;
+import code.name.monkey.appthemehelper.util.MaterialValueHelper;
+import code.name.monkey.retromusic.Constants;
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget;
+import code.name.monkey.retromusic.glide.SongGlideRequest;
+import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
+import code.name.monkey.retromusic.model.Song;
+import code.name.monkey.retromusic.service.MusicService;
+import code.name.monkey.retromusic.ui.activities.MainActivity;
+import code.name.monkey.retromusic.util.RetroUtil;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.request.animation.GlideAnimation;
+import com.bumptech.glide.request.target.SimpleTarget;
+import com.bumptech.glide.request.target.Target;
+
+public class AppWidgetClassic extends BaseAppWidget {
+
+ public static final String NAME = "app_widget_classic";
+
+ private static AppWidgetClassic mInstance;
+ private static int imageSize = 0;
+ private static float cardRadius = 0f;
+ private Target target; // for cancellation
+
+ public static synchronized AppWidgetClassic getInstance() {
+ if (mInstance == null) {
+ mInstance = new AppWidgetClassic();
+ }
+ return mInstance;
+ }
+
+ /**
+ * Initialize given widgets to default state, where we launch Music on default click and hide
+ * actions if service not running.
+ */
+ protected void defaultAppWidget(final Context context, final int[] appWidgetIds) {
+ final RemoteViews appWidgetView = new RemoteViews(context.getPackageName(),
+ R.layout.app_widget_classic);
+
+ appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE);
+ appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art);
+ appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(
+ RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp,
+ MaterialValueHelper.getSecondaryTextColor(context, true)), 1f));
+ appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(
+ RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp,
+ MaterialValueHelper.getSecondaryTextColor(context, true)), 1f));
+ appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(
+ RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_24dp,
+ MaterialValueHelper.getSecondaryTextColor(context, true)), 1f));
+
+ linkButtons(context, appWidgetView);
+ pushUpdate(context, appWidgetIds, appWidgetView);
+ }
+
+ /**
+ * Update all active widget instances by pushing changes
+ */
+ public void performUpdate(final MusicService service, final int[] appWidgetIds) {
+ final RemoteViews appWidgetView = new RemoteViews(service.getPackageName(),
+ R.layout.app_widget_classic);
+
+ final boolean isPlaying = service.isPlaying();
+ final Song song = service.getCurrentSong();
+
+ // Set the titles and artwork
+ if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
+ appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE);
+ } else {
+ appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE);
+ appWidgetView.setTextViewText(R.id.title, song.title);
+ appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song));
+ }
+
+ // Link actions buttons to intents
+ linkButtons(service, appWidgetView);
+
+ if (imageSize == 0) {
+ imageSize = service.getResources()
+ .getDimensionPixelSize(R.dimen.app_widget_classic_image_size);
+ }
+ if (cardRadius == 0f) {
+ cardRadius = service.getResources().getDimension(R.dimen.app_widget_card_radius);
+ }
+
+ // Load the album cover async and push the update on completion
+ final Context appContext = service.getApplicationContext();
+ service.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (target != null) {
+ Glide.clear(target);
+ }
+ target = SongGlideRequest.Builder.from(Glide.with(appContext), song)
+ .checkIgnoreMediaStore(appContext)
+ .generatePalette(service).build()
+ .centerCrop()
+ .into(new SimpleTarget(imageSize, imageSize) {
+ @Override
+ public void onResourceReady(BitmapPaletteWrapper resource,
+ GlideAnimation super BitmapPaletteWrapper> glideAnimation) {
+ Palette palette = resource.getPalette();
+ update(resource.getBitmap(), palette.getVibrantColor(palette
+ .getMutedColor(MaterialValueHelper.getSecondaryTextColor(appContext, true))));
+ }
+
+ @Override
+ public void onLoadFailed(Exception e, Drawable errorDrawable) {
+ super.onLoadFailed(e, errorDrawable);
+ update(null, MaterialValueHelper.getSecondaryTextColor(appContext, true));
+ }
+
+ private void update(@Nullable Bitmap bitmap, int color) {
+ // Set correct drawable for pause state
+ int playPauseRes = isPlaying ? R.drawable.ic_pause_white_24dp
+ : R.drawable.ic_play_arrow_white_24dp;
+ appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause,
+ createBitmap(RetroUtil.getTintedVectorDrawable(service, playPauseRes, color), 1f));
+
+ // Set prev/next button drawables
+ appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(
+ RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp,
+ color), 1f));
+ appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(
+ RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp,
+ color), 1f));
+
+ final Drawable image = getAlbumArtDrawable(service.getResources(), bitmap);
+ final Bitmap roundedBitmap = createRoundedBitmap(image, imageSize, imageSize,
+ cardRadius, 0, cardRadius, 0);
+ appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap);
+
+ pushUpdate(appContext, appWidgetIds, appWidgetView);
+ }
+ });
+ }
+ });
+ }
+
+ /**
+ * Link up various button actions using {@link PendingIntent}.
+ */
+ private void linkButtons(final Context context, final RemoteViews views) {
+ Intent action;
+ PendingIntent pendingIntent;
+
+ final ComponentName serviceName = new ComponentName(context, MusicService.class);
+
+ // Home
+ action = new Intent(context, MainActivity.class);
+ action.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ pendingIntent = PendingIntent.getActivity(context, 0, action, 0);
+ views.setOnClickPendingIntent(R.id.image, pendingIntent);
+ views.setOnClickPendingIntent(R.id.media_titles, pendingIntent);
+
+ // Previous track
+ pendingIntent = buildPendingIntent(context, Constants.ACTION_REWIND, serviceName);
+ views.setOnClickPendingIntent(R.id.button_prev, pendingIntent);
+
+ // Play and pause
+ pendingIntent = buildPendingIntent(context, Constants.ACTION_TOGGLE_PAUSE, serviceName);
+ views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent);
+
+ // Next track
+ pendingIntent = buildPendingIntent(context, Constants.ACTION_SKIP, serviceName);
+ views.setOnClickPendingIntent(R.id.button_next, pendingIntent);
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetClassic.kt b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetClassic.kt
deleted file mode 100644
index ad04f8aae..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetClassic.kt
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appwidgets
-
-import android.app.PendingIntent
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.graphics.Bitmap
-import android.graphics.Color
-import android.graphics.drawable.Drawable
-import android.view.View
-import android.widget.RemoteViews
-import androidx.core.graphics.drawable.toBitmap
-import code.name.monkey.appthemehelper.util.MaterialValueHelper
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.MainActivity
-import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
-import code.name.monkey.retromusic.extensions.getTintedDrawable
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
-import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
-import code.name.monkey.retromusic.service.MusicService
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_SKIP
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_TOGGLE_PAUSE
-import code.name.monkey.retromusic.util.PreferenceUtil
-import com.bumptech.glide.Glide
-import com.bumptech.glide.request.target.CustomTarget
-import com.bumptech.glide.request.target.Target
-import com.bumptech.glide.request.transition.Transition
-
-class AppWidgetClassic : BaseAppWidget() {
- private var target: Target? = null // for cancellation
-
- /**
- * Initialize given widgets to default state, where we launch Music on default click and hide
- * actions if service not running.
- */
- override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
- val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_classic)
-
- appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
- appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
- appWidgetView.setImageViewBitmap(
- R.id.button_next,
-
- context.getTintedDrawable(
- R.drawable.ic_skip_next,
- MaterialValueHelper.getSecondaryTextColor(context, true)
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_prev,
-
- context.getTintedDrawable(
- R.drawable.ic_skip_previous,
- MaterialValueHelper.getSecondaryTextColor(context, true)
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
-
- context.getTintedDrawable(
- R.drawable.ic_play_arrow_white_32dp,
- MaterialValueHelper.getSecondaryTextColor(context, true)
- ).toBitmap()
- )
-
- linkButtons(context, appWidgetView)
- pushUpdate(context, appWidgetIds, appWidgetView)
- }
-
- /**
- * Update all active widget instances by pushing changes
- */
- override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
- val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_classic)
-
- val isPlaying = service.isPlaying
- val song = service.currentSong
-
- // Set the titles and artwork
- if (song.title.isEmpty() && song.artistName.isEmpty()) {
- appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
- } else {
- appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
- appWidgetView.setTextViewText(R.id.title, song.title)
- appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song))
- }
-
- // Link actions buttons to intents
- linkButtons(service, appWidgetView)
-
- if (imageSize == 0) {
- imageSize =
- service.resources.getDimensionPixelSize(R.dimen.app_widget_classic_image_size)
- }
- if (cardRadius == 0f) {
- cardRadius = service.resources.getDimension(R.dimen.app_widget_card_radius)
- }
-
- // Load the album cover async and push the update on completion
- val appContext = service.applicationContext
- service.runOnUiThread {
- if (target != null) {
- Glide.with(service).clear(target)
- }
- target = Glide.with(service)
- .asBitmapPalette()
- .songCoverOptions(song)
- .load(RetroGlideExtension.getSongModel(song))
- //.checkIgnoreMediaStore()
- .centerCrop()
- .into(object : CustomTarget(imageSize, imageSize) {
- override fun onResourceReady(
- resource: BitmapPaletteWrapper,
- transition: Transition?,
- ) {
- val palette = resource.palette
- update(
- resource.bitmap,
- palette.getVibrantColor(
- palette.getMutedColor(
- MaterialValueHelper.getSecondaryTextColor(
- service,
- true
- )
- )
- )
- )
- }
-
- override fun onLoadFailed(errorDrawable: Drawable?) {
- super.onLoadFailed(errorDrawable)
- update(null, Color.WHITE)
- }
-
- override fun onLoadCleared(placeholder: Drawable?) {}
-
- private fun update(bitmap: Bitmap?, color: Int) {
- // Set correct drawable for pause state
- val playPauseRes =
- if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play_arrow
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- service.getTintedDrawable(
- playPauseRes,
- color
- ).toBitmap()
- )
-
- // Set prev/next button drawables
- appWidgetView.setImageViewBitmap(
- R.id.button_next,
- service.getTintedDrawable(
- R.drawable.ic_skip_next,
- color
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_prev,
- service.getTintedDrawable(
- R.drawable.ic_skip_previous,
- color
- ).toBitmap()
- )
-
- val image = getAlbumArtDrawable(service, bitmap)
- val roundedBitmap =
- createRoundedBitmap(
- image,
- imageSize,
- imageSize,
- cardRadius,
- 0F,
- cardRadius,
- 0F
- )
- appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
-
- pushUpdate(appContext, appWidgetIds, appWidgetView)
- }
- })
- }
- }
-
- /**
- * Link up various button actions using [PendingIntent].
- */
- private fun linkButtons(context: Context, views: RemoteViews) {
- val action = Intent(context, MainActivity::class.java)
- .putExtra(
- MainActivity.EXPAND_PANEL,
- PreferenceUtil.isExpandPanel
- )
-
- val serviceName = ComponentName(context, MusicService::class.java)
-
- // Home
- action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
- var pendingIntent = PendingIntent.getActivity(
- context, 0, action, if (VersionUtils.hasMarshmallow())
- PendingIntent.FLAG_IMMUTABLE
- else 0
- )
- views.setOnClickPendingIntent(R.id.image, pendingIntent)
- views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
-
- // Previous track
- pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
- views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
-
- // Play and pause
- pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
- views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
-
- // Next track
- pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
- views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
- }
-
- companion object {
-
- const val NAME = "app_widget_classic"
-
- private var mInstance: AppWidgetClassic? = null
- private var imageSize = 0
- private var cardRadius = 0f
-
- val instance: AppWidgetClassic
- @Synchronized get() {
- if (mInstance == null) {
- mInstance = AppWidgetClassic()
- }
- return mInstance!!
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetMD3.kt b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetMD3.kt
deleted file mode 100644
index 618914ff3..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetMD3.kt
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appwidgets
-
-import android.app.PendingIntent
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.graphics.Bitmap
-import android.graphics.drawable.Drawable
-import android.view.View
-import android.widget.RemoteViews
-import androidx.core.graphics.drawable.toBitmap
-import code.name.monkey.appthemehelper.util.MaterialValueHelper
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.MainActivity
-import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
-import code.name.monkey.retromusic.extensions.getTintedDrawable
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
-import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
-import code.name.monkey.retromusic.service.MusicService
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_SKIP
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_TOGGLE_PAUSE
-import code.name.monkey.retromusic.util.DensityUtil
-import code.name.monkey.retromusic.util.PreferenceUtil
-import com.bumptech.glide.Glide
-import com.bumptech.glide.request.target.CustomTarget
-import com.bumptech.glide.request.target.Target
-import com.bumptech.glide.request.transition.Transition
-
-class AppWidgetMD3 : BaseAppWidget() {
- private var target: Target? = null // for cancellation
-
- /**
- * Initialize given widgets to default state, where we launch Music on default click and hide
- * actions if service not running.
- */
- override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
- val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_md3)
-
- appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
- appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
- val secondaryColor = MaterialValueHelper.getSecondaryTextColor(context, true)
- appWidgetView.setImageViewBitmap(
- R.id.button_next,
- context.getTintedDrawable(
- R.drawable.ic_skip_next,
- secondaryColor
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_prev,
- context.getTintedDrawable(
- R.drawable.ic_skip_previous,
- secondaryColor
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- context.getTintedDrawable(
- R.drawable.ic_play_arrow_white_32dp,
- secondaryColor
- ).toBitmap()
- )
-
- linkButtons(context, appWidgetView)
- pushUpdate(context, appWidgetIds, appWidgetView)
- }
-
- /**
- * Update all active widget instances by pushing changes
- */
- override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
- val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_md3)
-
- val isPlaying = service.isPlaying
- val song = service.currentSong
-
- // Set the titles and artwork
- if (song.title.isEmpty() && song.artistName.isEmpty()) {
- appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
- } else {
- appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
- appWidgetView.setTextViewText(R.id.title, song.title)
- appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song))
- }
-
- // Set correct drawable for pause state
- val playPauseRes =
- if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play_arrow_white_32dp
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- service.getTintedDrawable(
- playPauseRes,
- MaterialValueHelper.getSecondaryTextColor(service, true)
- ).toBitmap()
- )
-
- // Set prev/next button drawables
- appWidgetView.setImageViewBitmap(
- R.id.button_next,
- service.getTintedDrawable(
- R.drawable.ic_skip_next,
- MaterialValueHelper.getSecondaryTextColor(service, true)
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_prev,
- service.getTintedDrawable(
- R.drawable.ic_skip_previous,
- MaterialValueHelper.getSecondaryTextColor(service, true)
- ).toBitmap()
- )
-
- // Link actions buttons to intents
- linkButtons(service, appWidgetView)
-
- if (imageSize == 0) {
- imageSize =
- service.resources.getDimensionPixelSize(R.dimen.app_widget_card_image_size)
- }
- if (cardRadius == 0f) {
- cardRadius =
- DensityUtil.dip2px(service, 8F).toFloat()
- }
-
- // Load the album cover async and push the update on completion
- service.runOnUiThread {
- if (target != null) {
- Glide.with(service).clear(target)
- }
- target = Glide.with(service)
- .asBitmapPalette()
- .songCoverOptions(song)
- .load(RetroGlideExtension.getSongModel(song))
- .centerCrop()
- .into(object : CustomTarget(imageSize, imageSize) {
- override fun onResourceReady(
- resource: BitmapPaletteWrapper,
- transition: Transition?,
- ) {
- val palette = resource.palette
- update(
- resource.bitmap, palette.getVibrantColor(
- palette.getMutedColor(
- MaterialValueHelper.getSecondaryTextColor(
- service, true
- )
- )
- )
- )
- }
-
- override fun onLoadFailed(errorDrawable: Drawable?) {
- super.onLoadFailed(errorDrawable)
- update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
- }
-
- override fun onLoadCleared(placeholder: Drawable?) {}
-
- private fun update(bitmap: Bitmap?, color: Int) {
- // Set correct drawable for pause state
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- service.getTintedDrawable(playPauseRes, color).toBitmap()
- )
-
- // Set prev/next button drawables
- appWidgetView.setImageViewBitmap(
- R.id.button_next,
- service.getTintedDrawable(R.drawable.ic_skip_next, color).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_prev,
- service.getTintedDrawable(R.drawable.ic_skip_previous, color).toBitmap()
- )
-
- val image = getAlbumArtDrawable(service, bitmap)
- val roundedBitmap = createRoundedBitmap(
- image,
- imageSize,
- imageSize,
- cardRadius,
- cardRadius,
- cardRadius,
- cardRadius
- )
- appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
-
- pushUpdate(service, appWidgetIds, appWidgetView)
- }
- })
- }
- }
-
- /**
- * Link up various button actions using [PendingIntent].
- */
- private fun linkButtons(context: Context, views: RemoteViews) {
- val action = Intent(context, MainActivity::class.java)
- .putExtra(
- MainActivity.EXPAND_PANEL,
- PreferenceUtil.isExpandPanel
- )
-
- val serviceName = ComponentName(context, MusicService::class.java)
-
- // Home
- action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
- var pendingIntent =
- PendingIntent.getActivity(
- context, 0, action, if (VersionUtils.hasMarshmallow())
- PendingIntent.FLAG_IMMUTABLE
- else 0
- )
- views.setOnClickPendingIntent(R.id.image, pendingIntent)
- views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
-
- // Previous track
- pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
- views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
-
- // Play and pause
- pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
- views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
-
- // Next track
- pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
- views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
- }
-
- companion object {
-
- const val NAME = "app_widget_md3"
-
- private var mInstance: AppWidgetMD3? = null
- private var imageSize = 0
- private var cardRadius = 0F
-
- val instance: AppWidgetMD3
- @Synchronized get() {
- if (mInstance == null) {
- mInstance = AppWidgetMD3()
- }
- return mInstance!!
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetSmall.java b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetSmall.java
new file mode 100644
index 000000000..1d80a2d13
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetSmall.java
@@ -0,0 +1,186 @@
+package code.name.monkey.retromusic.appwidgets;
+
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.Nullable;
+import android.support.v7.graphics.Palette;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.RemoteViews;
+import code.name.monkey.appthemehelper.util.MaterialValueHelper;
+import code.name.monkey.retromusic.Constants;
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget;
+import code.name.monkey.retromusic.glide.SongGlideRequest;
+import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
+import code.name.monkey.retromusic.model.Song;
+import code.name.monkey.retromusic.service.MusicService;
+import code.name.monkey.retromusic.ui.activities.MainActivity;
+import code.name.monkey.retromusic.util.RetroUtil;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.request.animation.GlideAnimation;
+import com.bumptech.glide.request.target.SimpleTarget;
+import com.bumptech.glide.request.target.Target;
+
+public class AppWidgetSmall extends BaseAppWidget {
+
+ public static final String NAME = "app_widget_small";
+
+ private static AppWidgetSmall mInstance;
+ private static int imageSize = 0;
+ private static float cardRadius = 0f;
+ private Target target; // for cancellation
+
+ public static synchronized AppWidgetSmall getInstance() {
+ if (mInstance == null) {
+ mInstance = new AppWidgetSmall();
+ }
+ return mInstance;
+ }
+
+ /**
+ * Initialize given widgets to default state, where we launch Music on default click and hide
+ * actions if service not running.
+ */
+ protected void defaultAppWidget(final Context context, final int[] appWidgetIds) {
+ final RemoteViews appWidgetView = new RemoteViews(context.getPackageName(),
+ R.layout.app_widget_small);
+
+ appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE);
+ appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art);
+ appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(
+ RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp,
+ MaterialValueHelper.getSecondaryTextColor(context, true)), 1f));
+ appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(
+ RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp,
+ MaterialValueHelper.getSecondaryTextColor(context, true)), 1f));
+ appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(
+ RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_24dp,
+ MaterialValueHelper.getSecondaryTextColor(context, true)), 1f));
+
+ linkButtons(context, appWidgetView);
+ pushUpdate(context, appWidgetIds, appWidgetView);
+ }
+
+ /**
+ * Update all active widget instances by pushing changes
+ */
+ public void performUpdate(final MusicService service, final int[] appWidgetIds) {
+ final RemoteViews appWidgetView = new RemoteViews(service.getPackageName(),
+ R.layout.app_widget_small);
+
+ final boolean isPlaying = service.isPlaying();
+ final Song song = service.getCurrentSong();
+
+ // Set the titles and artwork
+ if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
+ appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE);
+ } else {
+ if (TextUtils.isEmpty(song.title) || TextUtils.isEmpty(song.artistName)) {
+ appWidgetView.setTextViewText(R.id.text_separator, "");
+ } else {
+ appWidgetView.setTextViewText(R.id.text_separator, "•");
+ }
+
+ appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE);
+ appWidgetView.setTextViewText(R.id.title, song.title);
+ appWidgetView.setTextViewText(R.id.text, song.artistName);
+ }
+
+ // Link actions buttons to intents
+ linkButtons(service, appWidgetView);
+
+ if (imageSize == 0) {
+ imageSize = service.getResources().getDimensionPixelSize(R.dimen.app_widget_small_image_size);
+ }
+ if (cardRadius == 0f) {
+ cardRadius = service.getResources().getDimension(R.dimen.app_widget_card_radius);
+ }
+
+ // Load the album cover async and push the update on completion
+ final Context appContext = service.getApplicationContext();
+ service.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (target != null) {
+ Glide.clear(target);
+ }
+ target = SongGlideRequest.Builder.from(Glide.with(appContext), song)
+ .checkIgnoreMediaStore(appContext)
+ .generatePalette(service).build()
+ .centerCrop()
+ .into(new SimpleTarget(imageSize, imageSize) {
+ @Override
+ public void onResourceReady(BitmapPaletteWrapper resource,
+ GlideAnimation super BitmapPaletteWrapper> glideAnimation) {
+ Palette palette = resource.getPalette();
+ update(resource.getBitmap(), palette.getVibrantColor(palette
+ .getMutedColor(MaterialValueHelper.getSecondaryTextColor(appContext, true))));
+ }
+
+ @Override
+ public void onLoadFailed(Exception e, Drawable errorDrawable) {
+ super.onLoadFailed(e, errorDrawable);
+ update(null, MaterialValueHelper.getSecondaryTextColor(appContext, true));
+ }
+
+ private void update(@Nullable Bitmap bitmap, int color) {
+ // Set correct drawable for pause state
+ int playPauseRes = isPlaying ? R.drawable.ic_pause_white_24dp
+ : R.drawable.ic_play_arrow_white_24dp;
+ appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause,
+ createBitmap(RetroUtil.getTintedVectorDrawable(service, playPauseRes, color), 1f));
+
+ // Set prev/next button drawables
+ appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(
+ RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp,
+ color), 1f));
+ appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(
+ RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp,
+ color), 1f));
+
+ final Drawable image = getAlbumArtDrawable(service.getResources(), bitmap);
+ final Bitmap roundedBitmap = createRoundedBitmap(image, imageSize, imageSize,
+ cardRadius, 0, 0, 0);
+ appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap);
+
+ pushUpdate(appContext, appWidgetIds, appWidgetView);
+ }
+ });
+ }
+ });
+ }
+
+ /**
+ * Link up various button actions using {@link PendingIntent}.
+ */
+ private void linkButtons(final Context context, final RemoteViews views) {
+ Intent action;
+ PendingIntent pendingIntent;
+
+ final ComponentName serviceName = new ComponentName(context, MusicService.class);
+
+ // Home
+ action = new Intent(context, MainActivity.class);
+ action.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ pendingIntent = PendingIntent.getActivity(context, 0, action, 0);
+ views.setOnClickPendingIntent(R.id.image, pendingIntent);
+ views.setOnClickPendingIntent(R.id.media_titles, pendingIntent);
+
+ // Previous track
+ pendingIntent = buildPendingIntent(context, Constants.ACTION_REWIND, serviceName);
+ views.setOnClickPendingIntent(R.id.button_prev, pendingIntent);
+
+ // Play and pause
+ pendingIntent = buildPendingIntent(context, Constants.ACTION_TOGGLE_PAUSE, serviceName);
+ views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent);
+
+ // Next track
+ pendingIntent = buildPendingIntent(context, Constants.ACTION_SKIP, serviceName);
+ views.setOnClickPendingIntent(R.id.button_next, pendingIntent);
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetSmall.kt b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetSmall.kt
deleted file mode 100644
index ee4e87e99..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetSmall.kt
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appwidgets
-
-import android.app.PendingIntent
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.graphics.Bitmap
-import android.graphics.drawable.Drawable
-import android.view.View
-import android.widget.RemoteViews
-import androidx.core.graphics.drawable.toBitmap
-import code.name.monkey.appthemehelper.util.MaterialValueHelper
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.MainActivity
-import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
-import code.name.monkey.retromusic.extensions.getTintedDrawable
-import code.name.monkey.retromusic.glide.RetroGlideExtension
-import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
-import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
-import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
-import code.name.monkey.retromusic.service.MusicService
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_SKIP
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_TOGGLE_PAUSE
-import code.name.monkey.retromusic.util.PreferenceUtil
-import com.bumptech.glide.Glide
-import com.bumptech.glide.request.target.CustomTarget
-import com.bumptech.glide.request.target.Target
-import com.bumptech.glide.request.transition.Transition
-
-class AppWidgetSmall : BaseAppWidget() {
- private var target: Target? = null // for cancellation
-
- /**
- * Initialize given widgets to default state, where we launch Music on default click and hide
- * actions if service not running.
- */
- override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
- val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_small)
-
- appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
- appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
- appWidgetView.setImageViewBitmap(
- R.id.button_next,
- context.getTintedDrawable(
- R.drawable.ic_skip_next,
- MaterialValueHelper.getSecondaryTextColor(context, true)
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_prev,
-
- context.getTintedDrawable(
- R.drawable.ic_skip_previous,
- MaterialValueHelper.getSecondaryTextColor(context, true)
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
-
- context.getTintedDrawable(
- R.drawable.ic_play_arrow_white_32dp,
- MaterialValueHelper.getSecondaryTextColor(context, true)
- ).toBitmap()
- )
-
- linkButtons(context, appWidgetView)
- pushUpdate(context, appWidgetIds, appWidgetView)
- }
-
- /**
- * Update all active widget instances by pushing changes
- */
- override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
- val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_small)
-
- val isPlaying = service.isPlaying
- val song = service.currentSong
-
- // Set the titles and artwork
- if (song.title.isEmpty() && song.artistName.isEmpty()) {
- appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
- } else {
- if (song.title.isEmpty() || song.artistName.isEmpty()) {
- appWidgetView.setTextViewText(R.id.text_separator, "")
- } else {
- appWidgetView.setTextViewText(R.id.text_separator, "•")
- }
-
- appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
- appWidgetView.setTextViewText(R.id.title, song.title)
- appWidgetView.setTextViewText(R.id.text, song.artistName)
- }
-
- // Link actions buttons to intents
- linkButtons(service, appWidgetView)
-
- if (imageSize == 0) {
- imageSize = service.resources.getDimensionPixelSize(R.dimen.app_widget_small_image_size)
- }
- if (cardRadius == 0f) {
- cardRadius = service.resources.getDimension(R.dimen.app_widget_card_radius)
- }
-
- // Load the album cover async and push the update on completion
- val appContext = service.applicationContext
- service.runOnUiThread {
- if (target != null) {
- Glide.with(service).clear(target)
- }
- target = Glide.with(service)
- .asBitmapPalette()
- .songCoverOptions(song)
- //.checkIgnoreMediaStore()
- .load(RetroGlideExtension.getSongModel(song))
- .centerCrop()
- .into(object : CustomTarget(imageSize, imageSize) {
- override fun onResourceReady(
- resource: BitmapPaletteWrapper,
- transition: Transition?,
- ) {
- val palette = resource.palette
- update(
- resource.bitmap, palette.getVibrantColor(
- palette.getMutedColor(
- MaterialValueHelper.getSecondaryTextColor(
- service, true
- )
- )
- )
- )
- }
-
- override fun onLoadFailed(errorDrawable: Drawable?) {
- super.onLoadFailed(errorDrawable)
- update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
- }
-
- override fun onLoadCleared(placeholder: Drawable?) {
- update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
- }
-
- private fun update(bitmap: Bitmap?, color: Int) {
- // Set correct drawable for pause state
- val playPauseRes = if (isPlaying) R.drawable.ic_pause
- else R.drawable.ic_play_arrow_white_32dp
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- service.getTintedDrawable(playPauseRes, color).toBitmap()
- )
-
- // Set prev/next button drawables
- appWidgetView.setImageViewBitmap(
- R.id.button_next,
- service.getTintedDrawable(R.drawable.ic_skip_next, color).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_prev,
- service.getTintedDrawable(R.drawable.ic_skip_previous, color).toBitmap()
- )
-
- val image = getAlbumArtDrawable(service, bitmap)
- val roundedBitmap = createRoundedBitmap(
- image, imageSize, imageSize, cardRadius, 0f, 0f, 0f
- )
- appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
-
- pushUpdate(appContext, appWidgetIds, appWidgetView)
- }
- })
- }
- }
-
- /**
- * Link up various button actions using [PendingIntent].
- */
- private fun linkButtons(context: Context, views: RemoteViews) {
- val action = Intent(context, MainActivity::class.java)
- .putExtra(
- MainActivity.EXPAND_PANEL,
- PreferenceUtil.isExpandPanel
- )
-
- val serviceName = ComponentName(context, MusicService::class.java)
-
- // Home
- action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
- var pendingIntent =
- PendingIntent.getActivity(
- context, 0, action, if (VersionUtils.hasMarshmallow())
- PendingIntent.FLAG_IMMUTABLE
- else 0
- )
- views.setOnClickPendingIntent(R.id.image, pendingIntent)
- views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
-
- // Previous track
- pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
- views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
-
- // Play and pause
- pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
- views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
-
- // Next track
- pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
- views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
- }
-
- companion object {
-
- const val NAME: String = "app_widget_small"
-
- private var mInstance: AppWidgetSmall? = null
- private var imageSize = 0
- private var cardRadius = 0f
-
- val instance: AppWidgetSmall
- @Synchronized get() {
- if (mInstance == null) {
- mInstance = AppWidgetSmall()
- }
- return mInstance!!
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetText.kt b/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetText.kt
deleted file mode 100644
index b7abb6ee5..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appwidgets/AppWidgetText.kt
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appwidgets
-
-import android.app.PendingIntent
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.view.View
-import android.widget.RemoteViews
-import androidx.core.content.ContextCompat
-import androidx.core.graphics.drawable.toBitmap
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.MainActivity
-import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
-import code.name.monkey.retromusic.extensions.getTintedDrawable
-import code.name.monkey.retromusic.service.MusicService
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_SKIP
-import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_TOGGLE_PAUSE
-import code.name.monkey.retromusic.util.PreferenceUtil
-
-class AppWidgetText : BaseAppWidget() {
- override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
- val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_text)
-
- appWidgetView.setImageViewBitmap(
- R.id.button_next,
- context.getTintedDrawable(R.drawable.ic_skip_next, ContextCompat.getColor(
- context, code.name.monkey.appthemehelper.R.color.md_white_1000
- )).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_prev,
- context.getTintedDrawable(R.drawable.ic_skip_previous, ContextCompat.getColor(
- context, code.name.monkey.appthemehelper.R.color.md_white_1000
- )
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- context.getTintedDrawable(R.drawable.ic_play_arrow_white_32dp, ContextCompat.getColor(
- context, code.name.monkey.appthemehelper.R.color.md_white_1000
- )
- ).toBitmap()
- )
-
- appWidgetView.setTextColor(
- R.id.title, ContextCompat.getColor(context, code.name.monkey.appthemehelper.R.color.md_white_1000)
- )
- appWidgetView.setTextColor(
- R.id.text, ContextCompat.getColor(context, code.name.monkey.appthemehelper.R.color.md_white_1000)
- )
-
- linkButtons(context, appWidgetView)
- pushUpdate(context, appWidgetIds, appWidgetView)
- }
-
- /**
- * Link up various button actions using [PendingIntent].
- */
- private fun linkButtons(context: Context, views: RemoteViews) {
- val action = Intent(context, MainActivity::class.java)
- .putExtra(
- MainActivity.EXPAND_PANEL,
- PreferenceUtil.isExpandPanel
- )
-
- val serviceName = ComponentName(context, MusicService::class.java)
-
- // Home
- action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
- var pendingIntent = PendingIntent.getActivity(
- context, 0, action, if (VersionUtils.hasMarshmallow())
- PendingIntent.FLAG_IMMUTABLE
- else 0
- )
- views.setOnClickPendingIntent(R.id.image, pendingIntent)
- views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
-
- // Previous track
- pendingIntent = buildPendingIntent(context, ACTION_REWIND, serviceName)
- views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
-
- // Play and pause
- pendingIntent = buildPendingIntent(context, ACTION_TOGGLE_PAUSE, serviceName)
- views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
-
- // Next track
- pendingIntent = buildPendingIntent(context, ACTION_SKIP, serviceName)
- views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
- }
-
- override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
- val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_text)
-
- val isPlaying = service.isPlaying
- val song = service.currentSong
-
- // Set the titles and artwork
- if (song.title.isEmpty() && song.artistName.isEmpty()) {
- appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
- } else {
- appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
- appWidgetView.setTextViewText(R.id.title, song.title)
- appWidgetView.setTextViewText(R.id.text, song.artistName)
- }
- // Link actions buttons to intents
- linkButtons(service, appWidgetView)
-
- // Set correct drawable for pause state
- val playPauseRes = if (isPlaying) R.drawable.ic_pause
- else R.drawable.ic_play_arrow_white_32dp
- appWidgetView.setImageViewBitmap(
- R.id.button_toggle_play_pause,
- service.getTintedDrawable(playPauseRes, ContextCompat.getColor(
- service, code.name.monkey.appthemehelper.R.color.md_white_1000)
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_next,
- service.getTintedDrawable(
- R.drawable.ic_skip_next,
- ContextCompat.getColor(
- service,
- code.name.monkey.appthemehelper.R.color.md_white_1000
- )
- ).toBitmap()
- )
- appWidgetView.setImageViewBitmap(
- R.id.button_prev,
- service.getTintedDrawable(
- R.drawable.ic_skip_previous,
- ContextCompat.getColor(
- service, code.name.monkey.appthemehelper.R.color.md_white_1000
- )
- ).toBitmap()
- )
-
- pushUpdate(service.applicationContext, appWidgetIds, appWidgetView)
- }
-
- companion object {
-
- const val NAME: String = "app_widget_text"
-
- private var mInstance: AppWidgetText? = null
-
- val instance: AppWidgetText
- @Synchronized get() {
- if (mInstance == null) {
- mInstance = AppWidgetText()
- }
- return mInstance!!
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/BootReceiver.java b/app/src/main/java/code/name/monkey/retromusic/appwidgets/BootReceiver.java
new file mode 100644
index 000000000..38fb29895
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/appwidgets/BootReceiver.java
@@ -0,0 +1,32 @@
+package code.name.monkey.retromusic.appwidgets;
+
+import android.appwidget.AppWidgetManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+
+import code.name.monkey.retromusic.service.MusicService;
+
+
+/**
+ * @author Eugene Cheung (arkon)
+ */
+public class BootReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
+
+ // Start music service if there are any existing widgets
+ if (widgetManager.getAppWidgetIds(new ComponentName(context, AppWidgetBig.class)).length > 0 ||
+ widgetManager.getAppWidgetIds(new ComponentName(context, AppWidgetClassic.class)).length > 0 ||
+ widgetManager.getAppWidgetIds(new ComponentName(context, AppWidgetSmall.class)).length > 0 ||
+ widgetManager.getAppWidgetIds(new ComponentName(context, AppWidgetCard.class)).length > 0) {
+ final Intent serviceIntent = new Intent(context, MusicService.class);
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { // not allowed on Oreo
+ context.startService(serviceIntent);
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/BootReceiver.kt b/app/src/main/java/code/name/monkey/retromusic/appwidgets/BootReceiver.kt
deleted file mode 100644
index 079e90ae6..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appwidgets/BootReceiver.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appwidgets
-
-import android.appwidget.AppWidgetManager
-import android.content.BroadcastReceiver
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.os.Build
-import code.name.monkey.retromusic.service.MusicService
-
-class BootReceiver : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- val widgetManager = AppWidgetManager.getInstance(context)
-
- // Start music service if there are any existing widgets
- if (widgetManager.getAppWidgetIds(
- ComponentName(
- context, AppWidgetBig::class.java
- )
- ).isNotEmpty() || widgetManager.getAppWidgetIds(
- ComponentName(
- context, AppWidgetClassic::class.java
- )
- ).isNotEmpty() || widgetManager.getAppWidgetIds(
- ComponentName(
- context, AppWidgetSmall::class.java
- )
- ).isNotEmpty() || widgetManager.getAppWidgetIds(
- ComponentName(
- context, AppWidgetCard::class.java
- )
- ).isNotEmpty()
- ) {
- val serviceIntent = Intent(context, MusicService::class.java)
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { // not allowed on Oreo
- context.startService(serviceIntent)
- }
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/base/BaseAppWidget.java b/app/src/main/java/code/name/monkey/retromusic/appwidgets/base/BaseAppWidget.java
new file mode 100644
index 000000000..b2944cb44
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/appwidgets/base/BaseAppWidget.java
@@ -0,0 +1,162 @@
+package code.name.monkey.retromusic.appwidgets.base;
+
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.RectF;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.text.TextUtils;
+import android.widget.RemoteViews;
+import code.name.monkey.retromusic.Constants;
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.model.Song;
+import code.name.monkey.retromusic.service.MusicService;
+
+public abstract class BaseAppWidget extends AppWidgetProvider {
+
+ public static final String NAME = "app_widget";
+
+ protected static Bitmap createBitmap(Drawable drawable, float sizeMultiplier) {
+ Bitmap bitmap = Bitmap.createBitmap((int) (drawable.getIntrinsicWidth() * sizeMultiplier),
+ (int) (drawable.getIntrinsicHeight() * sizeMultiplier), Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas(bitmap);
+ drawable.setBounds(0, 0, c.getWidth(), c.getHeight());
+ drawable.draw(c);
+ return bitmap;
+ }
+
+ protected static Bitmap createRoundedBitmap(Drawable drawable, int width, int height, float tl,
+ float tr, float bl, float br) {
+ if (drawable == null) {
+ return null;
+ }
+
+ Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas(bitmap);
+ drawable.setBounds(0, 0, width, height);
+ drawable.draw(c);
+
+ Bitmap rounded = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+
+ Canvas canvas = new Canvas(rounded);
+ Paint paint = new Paint();
+ paint.setShader(
+ new BitmapShader(bitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
+ paint.setAntiAlias(true);
+ canvas.drawPath(composeRoundedRectPath(new RectF(0, 0, width, height), tl, tr, bl, br), paint);
+
+ return rounded;
+ }
+
+ protected static Path composeRoundedRectPath(RectF rect, float tl, float tr, float bl, float br) {
+ Path path = new Path();
+ tl = tl < 0 ? 0 : tl;
+ tr = tr < 0 ? 0 : tr;
+ bl = bl < 0 ? 0 : bl;
+ br = br < 0 ? 0 : br;
+
+ path.moveTo(rect.left + tl, rect.top);
+ path.lineTo(rect.right - tr, rect.top);
+ path.quadTo(rect.right, rect.top, rect.right, rect.top + tr);
+ path.lineTo(rect.right, rect.bottom - br);
+ path.quadTo(rect.right, rect.bottom, rect.right - br, rect.bottom);
+ path.lineTo(rect.left + bl, rect.bottom);
+ path.quadTo(rect.left, rect.bottom, rect.left, rect.bottom - bl);
+ path.lineTo(rect.left, rect.top + tl);
+ path.quadTo(rect.left, rect.top, rect.left + tl, rect.top);
+ path.close();
+
+ return path;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onUpdate(final Context context, final AppWidgetManager appWidgetManager,
+ final int[] appWidgetIds) {
+ defaultAppWidget(context, appWidgetIds);
+ final Intent updateIntent = new Intent(Constants.APP_WIDGET_UPDATE);
+ updateIntent.putExtra(Constants.EXTRA_APP_WIDGET_NAME, NAME);
+ updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
+ updateIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ context.sendBroadcast(updateIntent);
+ }
+
+ /**
+ * Handle a change notification coming over from {@link MusicService}
+ */
+ public void notifyChange(final MusicService service, final String what) {
+ if (hasInstances(service)) {
+ if (Constants.META_CHANGED.equals(what) || Constants.PLAY_STATE_CHANGED.equals(what)) {
+ performUpdate(service, null);
+ }
+ }
+ }
+
+ protected void pushUpdate(final Context context, final int[] appWidgetIds,
+ final RemoteViews views) {
+ final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
+ if (appWidgetIds != null) {
+ appWidgetManager.updateAppWidget(appWidgetIds, views);
+ } else {
+ appWidgetManager.updateAppWidget(new ComponentName(context, getClass()), views);
+ }
+ }
+
+ /**
+ * Check against {@link AppWidgetManager} if there are any instances of this widget.
+ */
+ protected boolean hasInstances(final Context context) {
+ final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
+ final int[] mAppWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context,
+ getClass()));
+ return mAppWidgetIds.length > 0;
+ }
+
+ protected PendingIntent buildPendingIntent(Context context, final String action,
+ final ComponentName serviceName) {
+ Intent intent = new Intent(action);
+ intent.setComponent(serviceName);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ return PendingIntent.getForegroundService(context, 0, intent, 0);
+ } else {
+ return PendingIntent.getService(context, 0, intent, 0);
+ }
+ }
+
+ abstract protected void defaultAppWidget(final Context context, final int[] appWidgetIds);
+
+ abstract public void performUpdate(final MusicService service, final int[] appWidgetIds);
+
+ protected Drawable getAlbumArtDrawable(final Resources resources, final Bitmap bitmap) {
+ Drawable image;
+ if (bitmap == null) {
+ image = resources.getDrawable(R.drawable.default_album_art);
+ } else {
+ image = new BitmapDrawable(resources, bitmap);
+ }
+ return image;
+ }
+
+ protected String getSongArtistAndAlbum(final Song song) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(song.artistName);
+ if (!TextUtils.isEmpty(song.artistName) && !TextUtils.isEmpty(song.albumName)) {
+ builder.append(" • ");
+ }
+ builder.append(song.albumName);
+ return builder.toString();
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/appwidgets/base/BaseAppWidget.kt b/app/src/main/java/code/name/monkey/retromusic/appwidgets/base/BaseAppWidget.kt
deleted file mode 100644
index e460b7956..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/appwidgets/base/BaseAppWidget.kt
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.appwidgets.base
-
-import android.app.PendingIntent
-import android.appwidget.AppWidgetManager
-import android.appwidget.AppWidgetProvider
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.graphics.*
-import android.graphics.drawable.BitmapDrawable
-import android.graphics.drawable.Drawable
-import android.widget.RemoteViews
-import androidx.core.content.ContextCompat
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.service.MusicService
-import code.name.monkey.retromusic.service.MusicService.Companion.APP_WIDGET_UPDATE
-import code.name.monkey.retromusic.service.MusicService.Companion.EXTRA_APP_WIDGET_NAME
-import code.name.monkey.retromusic.service.MusicService.Companion.FAVORITE_STATE_CHANGED
-import code.name.monkey.retromusic.service.MusicService.Companion.META_CHANGED
-import code.name.monkey.retromusic.service.MusicService.Companion.PLAY_STATE_CHANGED
-
-abstract class BaseAppWidget : AppWidgetProvider() {
-
- /**
- * {@inheritDoc}
- */
- override fun onUpdate(
- context: Context,
- appWidgetManager: AppWidgetManager,
- appWidgetIds: IntArray
- ) {
- defaultAppWidget(context, appWidgetIds)
- val updateIntent = Intent(APP_WIDGET_UPDATE)
- updateIntent.putExtra(EXTRA_APP_WIDGET_NAME, NAME)
- updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds)
- updateIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
- context.sendBroadcast(updateIntent)
- }
-
- /**
- * Handle a change notification coming over from [MusicService]
- */
- fun notifyChange(service: MusicService, what: String) {
- if (hasInstances(service)) {
- if (META_CHANGED == what || PLAY_STATE_CHANGED == what || FAVORITE_STATE_CHANGED == what) {
- performUpdate(service, null)
- }
- }
- }
-
- protected fun pushUpdate(
- context: Context,
- appWidgetIds: IntArray?,
- views: RemoteViews
- ) {
- val appWidgetManager = AppWidgetManager.getInstance(context)
- if (appWidgetIds != null) {
- appWidgetManager.updateAppWidget(appWidgetIds, views)
- } else {
- appWidgetManager.updateAppWidget(ComponentName(context, javaClass), views)
- }
- }
-
- /**
- * Check against [AppWidgetManager] if there are any instances of this widget.
- */
- private fun hasInstances(context: Context): Boolean {
- val appWidgetManager = AppWidgetManager.getInstance(context)
- val mAppWidgetIds = appWidgetManager.getAppWidgetIds(
- ComponentName(
- context, javaClass
- )
- )
- return mAppWidgetIds.isNotEmpty()
- }
-
- protected fun buildPendingIntent(
- context: Context,
- action: String,
- serviceName: ComponentName
- ): PendingIntent {
- val intent = Intent(action)
- intent.component = serviceName
- return if (VersionUtils.hasOreo()) {
- PendingIntent.getForegroundService(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
- } else {
- PendingIntent.getService(
- context, 0, intent, if (VersionUtils.hasMarshmallow())
- PendingIntent.FLAG_IMMUTABLE
- else 0
- )
- }
- }
-
- protected abstract fun defaultAppWidget(context: Context, appWidgetIds: IntArray)
-
- abstract fun performUpdate(service: MusicService, appWidgetIds: IntArray?)
-
- protected fun getAlbumArtDrawable(context: Context, bitmap: Bitmap?): Drawable {
- return if (bitmap == null) {
- ContextCompat.getDrawable(context, R.drawable.default_audio_art)!!
- } else {
- BitmapDrawable(context.resources, bitmap)
- }
- }
-
- protected fun getSongArtistAndAlbum(song: Song): String {
- val builder = StringBuilder()
- builder.append(song.artistName)
- if (song.artistName.isNotEmpty() && song.albumName.isNotEmpty()) {
- builder.append(" • ")
- }
- builder.append(song.albumName)
- return builder.toString()
- }
-
- companion object {
-
- const val NAME: String = "app_widget"
-
- fun createRoundedBitmap(
- drawable: Drawable?,
- width: Int,
- height: Int,
- tl: Float,
- tr: Float,
- bl: Float,
- br: Float
- ): Bitmap? {
- if (drawable == null) {
- return null
- }
-
- val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
- val c = Canvas(bitmap)
- drawable.setBounds(0, 0, width, height)
- drawable.draw(c)
-
- val rounded = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
-
- val canvas = Canvas(rounded)
- val paint = Paint()
- paint.shader = BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
- paint.isAntiAlias = true
- canvas.drawPath(
- composeRoundedRectPath(
- RectF(0f, 0f, width.toFloat(), height.toFloat()), tl, tr, bl, br
- ), paint
- )
-
- return rounded
- }
-
- protected fun composeRoundedRectPath(
- rect: RectF,
- tl: Float,
- tr: Float,
- bl: Float,
- br: Float
- ): Path {
- val path = Path()
- path.moveTo(rect.left + tl, rect.top)
- path.lineTo(rect.right - tr, rect.top)
- path.quadTo(rect.right, rect.top, rect.right, rect.top + tr)
- path.lineTo(rect.right, rect.bottom - br)
- path.quadTo(rect.right, rect.bottom, rect.right - br, rect.bottom)
- path.lineTo(rect.left + bl, rect.bottom)
- path.quadTo(rect.left, rect.bottom, rect.left, rect.bottom - bl)
- path.lineTo(rect.left, rect.top + tl)
- path.quadTo(rect.left, rect.top, rect.left + tl, rect.top)
- path.close()
-
- return path
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/auto/AutoMediaIDHelper.java b/app/src/main/java/code/name/monkey/retromusic/auto/AutoMediaIDHelper.java
deleted file mode 100644
index 3d1f4815d..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/auto/AutoMediaIDHelper.java
+++ /dev/null
@@ -1,102 +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.auto;
-
-import androidx.annotation.NonNull;
-
-/**
- * Created by Beesham Sarendranauth (Beesham)
- */
-public class AutoMediaIDHelper {
-
- // Media IDs used on browseable items of MediaBrowser
- public static final String MEDIA_ID_EMPTY_ROOT = "__EMPTY_ROOT__";
- public static final String MEDIA_ID_ROOT = "__ROOT__";
- public static final String MEDIA_ID_MUSICS_BY_SEARCH = "__BY_SEARCH__"; // TODO
- public static final String MEDIA_ID_MUSICS_BY_HISTORY = "__BY_HISTORY__";
- public static final String MEDIA_ID_MUSICS_BY_TOP_TRACKS = "__BY_TOP_TRACKS__";
- public static final String MEDIA_ID_MUSICS_BY_SUGGESTIONS = "__BY_SUGGESTIONS__";
- public static final String MEDIA_ID_MUSICS_BY_PLAYLIST = "__BY_PLAYLIST__";
- public static final String MEDIA_ID_MUSICS_BY_ALBUM = "__BY_ALBUM__";
- public static final String MEDIA_ID_MUSICS_BY_ARTIST = "__BY_ARTIST__";
- public static final String MEDIA_ID_MUSICS_BY_ALBUM_ARTIST = "__BY_ALBUM_ARTIST__";
- public static final String MEDIA_ID_MUSICS_BY_GENRE = "__BY_GENRE__";
- public static final String MEDIA_ID_MUSICS_BY_SHUFFLE = "__BY_SHUFFLE__";
- public static final String MEDIA_ID_MUSICS_BY_QUEUE = "__BY_QUEUE__";
- public static final String RECENT_ROOT = "__RECENT__";
-
- private static final String CATEGORY_SEPARATOR = "__/__";
- private static final String LEAF_SEPARATOR = "__|__";
-
- /**
- * Create a String value that represents a playable or a browsable media.
- *
- * Encode the media browseable categories, if any, and the unique music ID, if any,
- * into a single String mediaID.
- *
- * MediaIDs are of the form __/____|__, to make it
- * easy to find the category (like genre) that a music was selected from, so we
- * can correctly build the playing queue. This is specially useful when
- * one music can appear in more than one list, like "by genre -> genre_1"
- * and "by artist -> artist_1".
- *
- * @param mediaID Unique ID for playable items, or null for browseable items.
- * @param categories Hierarchy of categories representing this item's browsing parents.
- * @return A hierarchy-aware media ID.
- */
- public static String createMediaID(String mediaID, String... categories) {
- StringBuilder sb = new StringBuilder();
- if (categories != null) {
- for (int i = 0; i < categories.length; i++) {
- if (!isValidCategory(categories[i])) {
- throw new IllegalArgumentException("Invalid category: " + categories[i]);
- }
- sb.append(categories[i]);
- if (i < categories.length - 1) {
- sb.append(CATEGORY_SEPARATOR);
- }
- }
- }
- if (mediaID != null) {
- sb.append(LEAF_SEPARATOR).append(mediaID);
- }
- return sb.toString();
- }
-
- public static String extractCategory(@NonNull String mediaID) {
- int pos = mediaID.indexOf(LEAF_SEPARATOR);
- if (pos >= 0) {
- return mediaID.substring(0, pos);
- }
- return mediaID;
- }
-
- public static String extractMusicID(@NonNull String mediaID) {
- int pos = mediaID.indexOf(LEAF_SEPARATOR);
- if (pos >= 0) {
- return mediaID.substring(pos + LEAF_SEPARATOR.length());
- }
- return null;
- }
-
- public static boolean isBrowseable(@NonNull String mediaID) {
- return !mediaID.contains(LEAF_SEPARATOR);
- }
-
- private static boolean isValidCategory(String category) {
- return category == null ||
- (!category.contains(CATEGORY_SEPARATOR) && !category.contains(LEAF_SEPARATOR));
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/auto/AutoMusicProvider.kt b/app/src/main/java/code/name/monkey/retromusic/auto/AutoMusicProvider.kt
deleted file mode 100644
index b6e267ed2..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/auto/AutoMusicProvider.kt
+++ /dev/null
@@ -1,283 +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.auto
-
-import android.content.Context
-import android.content.res.Resources
-import android.support.v4.media.MediaBrowserCompat
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.helper.MusicPlayerRemote
-import code.name.monkey.retromusic.model.CategoryInfo
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.repository.*
-import code.name.monkey.retromusic.service.MusicService
-import code.name.monkey.retromusic.util.MusicUtil
-import code.name.monkey.retromusic.util.PreferenceUtil
-import java.lang.ref.WeakReference
-
-
-/**
- * Created by Beesham Sarendranauth (Beesham)
- */
-class AutoMusicProvider(
- private val mContext: Context,
- private val songsRepository: SongRepository,
- private val albumsRepository: AlbumRepository,
- private val artistsRepository: ArtistRepository,
- private val genresRepository: GenreRepository,
- private val playlistsRepository: PlaylistRepository,
- private val topPlayedRepository: TopPlayedRepository
-) {
- private var mMusicService: WeakReference? = null
-
- fun setMusicService(service: MusicService) {
- mMusicService = WeakReference(service)
- }
-
- fun getChildren(mediaId: String?, resources: Resources): List {
- val mediaItems: MutableList = ArrayList()
- when (mediaId) {
- AutoMediaIDHelper.MEDIA_ID_ROOT -> {
- mediaItems.addAll(getRootChildren(resources))
- }
- AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_PLAYLIST -> for (playlist in playlistsRepository.playlists()) {
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .path(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_PLAYLIST, playlist.id)
- .icon(R.drawable.ic_playlist_play)
- .title(playlist.name)
- .subTitle(playlist.getInfoString(mContext))
- .asPlayable()
- .build()
- )
- }
- AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_ALBUM -> for (album in albumsRepository.albums()) {
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .path(mediaId, album.id)
- .title(album.title)
- .subTitle(album.albumArtist ?: album.artistName)
- .icon(MusicUtil.getMediaStoreAlbumCoverUri(album.id))
- .asPlayable()
- .build()
- )
- }
- AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_ARTIST -> for (artist in artistsRepository.artists()) {
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .asPlayable()
- .path(mediaId, artist.id)
- .title(artist.name)
- .build()
- )
- }
- AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_ALBUM_ARTIST -> for (artist in artistsRepository.albumArtists()) {
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .asPlayable()
- // we just pass album id here as we don't have album artist id's
- .path(mediaId, artist.safeGetFirstAlbum().id)
- .title(artist.name)
- .build()
- )
- }
- AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_GENRE -> for (genre in genresRepository.genres()) {
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .asPlayable()
- .path(mediaId, genre.id)
- .title(genre.name)
- .build()
- )
- }
- AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_QUEUE ->
- mMusicService?.get()?.playingQueue
- ?.let {
- for (song in it) {
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .asPlayable()
- .path(mediaId, song.id)
- .title(song.title)
- .subTitle(song.artistName)
- .icon(MusicUtil.getMediaStoreAlbumCoverUri(song.albumId))
- .build()
- )
- }
- }
- else -> {
- getPlaylistChildren(mediaId, mediaItems)
- }
- }
- return mediaItems
- }
-
- private fun getPlaylistChildren(
- mediaId: String?,
- mediaItems: MutableList
- ) {
- val songs = when (mediaId) {
- AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_TOP_TRACKS -> {
- topPlayedRepository.topTracks()
- }
- AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_HISTORY -> {
- topPlayedRepository.recentlyPlayedTracks()
- }
- AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_SUGGESTIONS -> {
- topPlayedRepository.notRecentlyPlayedTracks().take(8)
- }
- else -> {
- emptyList()
- }
- }
- songs.forEach { song ->
- mediaItems.add(
- getPlayableSong(mediaId, song)
- )
- }
- }
-
- private fun getRootChildren(resources: Resources): List {
- val mediaItems: MutableList = ArrayList()
- val libraryCategories = PreferenceUtil.libraryCategory
- libraryCategories.forEach {
- if (it.visible) {
- when (it.category) {
- CategoryInfo.Category.Albums -> {
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .asBrowsable()
- .path(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_ALBUM)
- .gridLayout(true)
- .icon(R.drawable.ic_album)
- .title(resources.getString(R.string.albums)).build()
- )
- }
- CategoryInfo.Category.Artists -> {
- if (PreferenceUtil.albumArtistsOnly) {
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .asBrowsable()
- .path(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_ALBUM_ARTIST)
- .icon(R.drawable.ic_album_artist)
- .title(resources.getString(R.string.album_artist)).build()
- )
- } else {
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .asBrowsable()
- .path(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_ARTIST)
- .icon(R.drawable.ic_artist)
- .title(resources.getString(R.string.artists)).build()
- )
- }
- }
- CategoryInfo.Category.Genres -> {
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .asBrowsable()
- .path(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_GENRE)
- .icon(R.drawable.ic_guitar)
- .title(resources.getString(R.string.genres)).build()
- )
- }
- CategoryInfo.Category.Playlists -> {
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .asBrowsable()
- .path(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_PLAYLIST)
- .icon(R.drawable.ic_playlist_play)
- .title(resources.getString(R.string.playlists)).build()
- )
- }
- else -> {
- }
- }
- }
- }
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .asPlayable()
- .path(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_SHUFFLE)
- .icon(R.drawable.ic_shuffle)
- .title(resources.getString(R.string.action_shuffle_all))
- .subTitle(MusicUtil.getPlaylistInfoString(mContext, songsRepository.songs()))
- .build()
- )
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .asBrowsable()
- .path(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_QUEUE)
- .icon(R.drawable.ic_queue_music)
- .title(resources.getString(R.string.queue))
- .subTitle(MusicUtil.getPlaylistInfoString(mContext, MusicPlayerRemote.playingQueue))
- .asBrowsable().build()
- )
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .asBrowsable()
- .path(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_TOP_TRACKS)
- .icon(R.drawable.ic_trending_up)
- .title(resources.getString(R.string.my_top_tracks))
- .subTitle(
- MusicUtil.getPlaylistInfoString(
- mContext,
- topPlayedRepository.topTracks()
- )
- )
- .asBrowsable().build()
- )
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .asBrowsable()
- .path(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_SUGGESTIONS)
- .icon(R.drawable.ic_face)
- .title(resources.getString(R.string.suggestion_songs))
- .subTitle(
- MusicUtil.getPlaylistInfoString(
- mContext,
- topPlayedRepository.notRecentlyPlayedTracks().takeIf {
- it.size > 9
- } ?: emptyList()
- )
- )
- .asBrowsable().build()
- )
- mediaItems.add(
- AutoMediaItem.with(mContext)
- .asBrowsable()
- .path(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_HISTORY)
- .icon(R.drawable.ic_history)
- .title(resources.getString(R.string.history))
- .subTitle(
- MusicUtil.getPlaylistInfoString(
- mContext,
- topPlayedRepository.recentlyPlayedTracks()
- )
- )
- .asBrowsable().build()
- )
- return mediaItems
- }
-
- private fun getPlayableSong(mediaId: String?, song: Song): MediaBrowserCompat.MediaItem {
- return AutoMediaItem.with(mContext)
- .asPlayable()
- .path(mediaId, song.id)
- .title(song.title)
- .subTitle(song.artistName)
- .icon(MusicUtil.getMediaStoreAlbumCoverUri(song.albumId))
- .build()
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/auto/MediaItemBuilder.kt b/app/src/main/java/code/name/monkey/retromusic/auto/MediaItemBuilder.kt
deleted file mode 100644
index 534b0ec52..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/auto/MediaItemBuilder.kt
+++ /dev/null
@@ -1,100 +0,0 @@
-package code.name.monkey.retromusic.auto
-
-import android.content.Context
-import android.net.Uri
-import android.support.v4.media.MediaBrowserCompat
-import android.support.v4.media.MediaDescriptionCompat
-import androidx.core.content.res.ResourcesCompat
-import androidx.core.graphics.drawable.toBitmap
-import androidx.core.os.bundleOf
-
-
-internal object AutoMediaItem {
- fun with(context: Context): Builder {
- return Builder(context)
- }
-
- internal class Builder(private val mContext: Context) {
- private var mBuilder: MediaDescriptionCompat.Builder?
- private var mFlags = 0
- fun path(fullPath: String): Builder {
- mBuilder?.setMediaId(fullPath)
- return this
- }
-
- fun path(path: String?, id: Long): Builder {
- return path(AutoMediaIDHelper.createMediaID(id.toString(), path))
- }
-
- fun title(title: String): Builder {
- mBuilder?.setTitle(title)
- return this
- }
-
- fun subTitle(subTitle: String): Builder {
- mBuilder?.setSubtitle(subTitle)
- return this
- }
-
- fun icon(uri: Uri?): Builder {
- mBuilder?.setIconUri(uri)
- return this
- }
-
- fun icon(iconDrawableId: Int): Builder {
- mBuilder?.setIconBitmap(
- ResourcesCompat.getDrawable(
- mContext.resources,
- iconDrawableId,
- mContext.theme
- )?.toBitmap()
- )
- return this
- }
-
- fun gridLayout(isGrid: Boolean): Builder {
-
- val hints = bundleOf(
- CONTENT_STYLE_SUPPORTED to true,
- CONTENT_STYLE_BROWSABLE_HINT to
- if (isGrid) CONTENT_STYLE_GRID_ITEM_HINT_VALUE
- else CONTENT_STYLE_LIST_ITEM_HINT_VALUE,
- CONTENT_STYLE_PLAYABLE_HINT to
- if (isGrid) CONTENT_STYLE_GRID_ITEM_HINT_VALUE
- else CONTENT_STYLE_LIST_ITEM_HINT_VALUE
- )
- mBuilder?.setExtras(hints)
- return this
- }
-
- fun asBrowsable(): Builder {
- mFlags = mFlags or MediaBrowserCompat.MediaItem.FLAG_BROWSABLE
- return this
- }
-
- fun asPlayable(): Builder {
- mFlags = mFlags or MediaBrowserCompat.MediaItem.FLAG_PLAYABLE
- return this
- }
-
- fun build(): MediaBrowserCompat.MediaItem {
- val result = MediaBrowserCompat.MediaItem(mBuilder!!.build(), mFlags)
- mBuilder = null
- mFlags = 0
- return result
- }
-
- init {
- mBuilder = MediaDescriptionCompat.Builder()
- }
- companion object{
- // Hints - see https://developer.android.com/training/cars/media#default-content-style
- const val CONTENT_STYLE_SUPPORTED = "android.media.browse.CONTENT_STYLE_SUPPORTED"
- const val CONTENT_STYLE_BROWSABLE_HINT = "android.media.browse.CONTENT_STYLE_BROWSABLE_HINT"
- const val CONTENT_STYLE_PLAYABLE_HINT = "android.media.browse.CONTENT_STYLE_PLAYABLE_HINT"
- const val CONTENT_STYLE_LIST_ITEM_HINT_VALUE = 1
- const val CONTENT_STYLE_GRID_ITEM_HINT_VALUE = 2
- }
-
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/BlackListStoreDao.kt b/app/src/main/java/code/name/monkey/retromusic/db/BlackListStoreDao.kt
deleted file mode 100644
index 0bf40b736..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/BlackListStoreDao.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.db
-
-import androidx.room.*
-
-@Dao
-interface BlackListStoreDao {
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insertBlacklistPath(blackListStoreEntity: BlackListStoreEntity)
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- suspend fun insertBlacklistPath(blackListStoreEntities: List)
-
- @Delete
- suspend fun deleteBlacklistPath(blackListStoreEntity: BlackListStoreEntity)
-
- @Query("DELETE FROM BlackListStoreEntity")
- suspend fun clearBlacklist()
-
- @Query("SELECT * FROM BlackListStoreEntity")
- fun blackListPaths(): List
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/BlackListStoreEntity.kt b/app/src/main/java/code/name/monkey/retromusic/db/BlackListStoreEntity.kt
deleted file mode 100644
index 8592442a2..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/BlackListStoreEntity.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.db
-
-import androidx.room.Entity
-import androidx.room.PrimaryKey
-
-@Entity
-class BlackListStoreEntity(
- @PrimaryKey
- val path: String
-)
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/HistoryDao.kt b/app/src/main/java/code/name/monkey/retromusic/db/HistoryDao.kt
deleted file mode 100644
index 2ceb309db..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/HistoryDao.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.db
-
-import androidx.lifecycle.LiveData
-import androidx.room.*
-
-@Dao
-interface HistoryDao {
- companion object {
- private const val HISTORY_LIMIT = 100
- }
-
- @Upsert
- suspend fun upsertSongInHistory(historyEntity: HistoryEntity)
-
- @Query("DELETE FROM HistoryEntity WHERE id= :songId")
- fun deleteSongInHistory(songId: Long)
-
- @Query("SELECT * FROM HistoryEntity ORDER BY time_played DESC LIMIT $HISTORY_LIMIT")
- fun historySongs(): List
-
- @Query("SELECT * FROM HistoryEntity ORDER BY time_played DESC LIMIT $HISTORY_LIMIT")
- fun observableHistorySongs(): LiveData>
-
- @Query("DELETE FROM HistoryEntity")
- suspend fun clearHistory()
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/HistoryEntity.kt b/app/src/main/java/code/name/monkey/retromusic/db/HistoryEntity.kt
deleted file mode 100644
index 535a37964..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/HistoryEntity.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.db
-
-import androidx.room.ColumnInfo
-import androidx.room.Entity
-import androidx.room.PrimaryKey
-
-@Entity
-class HistoryEntity(
- @PrimaryKey
- val id: Long,
- val title: String,
- @ColumnInfo(name = "track_number")
- val trackNumber: Int,
- val year: Int,
- val duration: Long,
- val data: String,
- @ColumnInfo(name = "date_modified")
- val dateModified: Long,
- @ColumnInfo(name = "album_id")
- val albumId: Long,
- @ColumnInfo(name = "album_name")
- val albumName: String,
- @ColumnInfo(name = "artist_id")
- val artistId: Long,
- @ColumnInfo(name = "artist_name")
- val artistName: String,
- val composer: String?,
- @ColumnInfo(name = "album_artist")
- val albumArtist: String?,
- @ColumnInfo(name = "time_played")
- val timePlayed: Long
-)
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/LyricsDao.kt b/app/src/main/java/code/name/monkey/retromusic/db/LyricsDao.kt
deleted file mode 100644
index fa14b1aca..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/LyricsDao.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.db
-
-import androidx.room.*
-
-@Dao
-interface LyricsDao {
- @Query("SELECT * FROM LyricsEntity WHERE songId =:songId LIMIT 1")
- fun lyricsWithSongId(songId: Int): LyricsEntity?
-
- @Insert
- fun insertLyrics(lyricsEntity: LyricsEntity)
-
- @Delete
- fun deleteLyrics(lyricsEntity: LyricsEntity)
-
- @Update
- fun updateLyrics(lyricsEntity: LyricsEntity)
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/LyricsEntity.kt b/app/src/main/java/code/name/monkey/retromusic/db/LyricsEntity.kt
deleted file mode 100644
index 91d987d62..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/LyricsEntity.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.db
-
-import androidx.room.Entity
-import androidx.room.PrimaryKey
-
-@Entity
-class LyricsEntity(
- @PrimaryKey val songId: Int,
- val lyrics: String
-)
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/PlayCountDao.kt b/app/src/main/java/code/name/monkey/retromusic/db/PlayCountDao.kt
deleted file mode 100644
index 087ae4faf..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/PlayCountDao.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.db
-
-import androidx.room.*
-
-@Dao
-interface PlayCountDao {
-
- @Upsert
- fun upsertSongInPlayCount(playCountEntity: PlayCountEntity)
-
- @Delete
- fun deleteSongInPlayCount(playCountEntity: PlayCountEntity)
-
- @Query("SELECT * FROM PlayCountEntity WHERE id =:songId LIMIT 1")
- fun findSongExistInPlayCount(songId: Long): PlayCountEntity?
-
- @Query("SELECT * FROM PlayCountEntity ORDER BY play_count DESC")
- fun playCountSongs(): List
-
- @Query("DELETE FROM SongEntity WHERE id =:songId")
- fun deleteSong(songId: Long)
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/PlayCountEntity.kt b/app/src/main/java/code/name/monkey/retromusic/db/PlayCountEntity.kt
deleted file mode 100644
index 2fa41b227..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/PlayCountEntity.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.db
-
-import androidx.room.ColumnInfo
-import androidx.room.Entity
-import androidx.room.PrimaryKey
-
-@Entity
-class PlayCountEntity(
- @PrimaryKey
- val id: Long,
- val title: String,
- @ColumnInfo(name = "track_number")
- val trackNumber: Int,
- val year: Int,
- val duration: Long,
- val data: String,
- @ColumnInfo(name = "date_modified")
- val dateModified: Long,
- @ColumnInfo(name = "album_id")
- val albumId: Long,
- @ColumnInfo(name = "album_name")
- val albumName: String,
- @ColumnInfo(name = "artist_id")
- val artistId: Long,
- @ColumnInfo(name = "artist_name")
- val artistName: String,
- val composer: String?,
- @ColumnInfo(name = "album_artist")
- val albumArtist: String?,
- @ColumnInfo(name = "time_played")
- val timePlayed: Long,
- @ColumnInfo(name = "play_count")
- var playCount: Int
-)
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt
deleted file mode 100644
index dea1e6b7d..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.db
-
-import androidx.lifecycle.LiveData
-import androidx.room.*
-
-@Dao
-interface PlaylistDao {
- @Insert
- suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long
-
- @Query("UPDATE PlaylistEntity SET playlist_name = :name WHERE playlist_id = :playlistId")
- suspend fun renamePlaylist(playlistId: Long, name: String)
-
- @Query("SELECT * FROM PlaylistEntity WHERE playlist_name = :name")
- fun playlist(name: String): List
-
- @Query("SELECT * FROM PlaylistEntity")
- suspend fun playlists(): List
-
- @Query("DELETE FROM SongEntity WHERE playlist_creator_id = :playlistId")
- suspend fun deletePlaylistSongs(playlistId: Long)
-
- @Query("DELETE FROM SongEntity WHERE playlist_creator_id = :playlistId AND id = :songId")
- suspend fun deleteSongFromPlaylist(playlistId: Long, songId: Long)
-
- @Transaction
- @Query("SELECT * FROM PlaylistEntity")
- suspend fun playlistsWithSongs(): List
-
- @Transaction
- @Query("SELECT * FROM PlaylistEntity WHERE playlist_id= :playlistId")
- fun getPlaylist(playlistId: Long): LiveData
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- suspend fun insertSongsToPlaylist(songEntities: List)
-
- @Query("SELECT * FROM SongEntity WHERE playlist_creator_id = :playlistId AND id = :songId")
- suspend fun isSongExistsInPlaylist(playlistId: Long, songId: Long): List
-
- @Query("SELECT * FROM SongEntity WHERE playlist_creator_id = :playlistId ORDER BY song_key asc")
- fun songsFromPlaylist(playlistId: Long): LiveData>
-
- @Delete
- suspend fun deletePlaylist(playlistEntity: PlaylistEntity)
-
- @Delete
- suspend fun deletePlaylists(playlistEntities: List)
-
- @Delete
- suspend fun deletePlaylistSongs(songs: List)
-
- @RewriteQueriesToDropUnusedColumns
- @Query("SELECT * FROM SongEntity ,(SELECT playlist_id FROM PlaylistEntity WHERE playlist_name= :playlistName LIMIT 1) AS playlist WHERE playlist_creator_id= playlist.playlist_id")
- fun favoritesSongsLiveData(playlistName: String): LiveData>
-
- @Query("SELECT * FROM SongEntity WHERE playlist_creator_id= :playlistId")
- fun favoritesSongs(playlistId: Long): List
-
- @Query("SELECT EXISTS(SELECT * FROM PlaylistEntity WHERE playlist_id = :playlistId)")
- fun checkPlaylistExists(playlistId: Long): LiveData
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistEntity.kt b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistEntity.kt
deleted file mode 100644
index 5493b1155..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistEntity.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.db
-
-import android.os.Parcelable
-import androidx.room.ColumnInfo
-import androidx.room.Entity
-import androidx.room.PrimaryKey
-import kotlinx.parcelize.Parcelize
-
-@Entity
-@Parcelize
-class PlaylistEntity(
- @PrimaryKey(autoGenerate = true)
- @ColumnInfo(name = "playlist_id")
- val playListId: Long = 0,
- @ColumnInfo(name = "playlist_name")
- val playlistName: String
-) : Parcelable
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistWithSongs.kt b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistWithSongs.kt
deleted file mode 100644
index da80d8228..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistWithSongs.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.db
-
-import android.os.Parcelable
-import androidx.room.Embedded
-import androidx.room.Relation
-import kotlinx.parcelize.Parcelize
-
-@Parcelize
-data class PlaylistWithSongs(
- @Embedded val playlistEntity: PlaylistEntity,
- @Relation(
- parentColumn = "playlist_id",
- entityColumn = "playlist_creator_id"
- )
- val songs: List
-) : Parcelable
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/RetroDatabase.kt b/app/src/main/java/code/name/monkey/retromusic/db/RetroDatabase.kt
deleted file mode 100644
index 6401766aa..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/RetroDatabase.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.db
-
-import androidx.room.Database
-import androidx.room.RoomDatabase
-
-@Database(
- entities = [PlaylistEntity::class, SongEntity::class, HistoryEntity::class, PlayCountEntity::class],
- version = 24,
- exportSchema = false
-)
-abstract class RetroDatabase : RoomDatabase() {
- abstract fun playlistDao(): PlaylistDao
- abstract fun playCountDao(): PlayCountDao
- abstract fun historyDao(): HistoryDao
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/RoomMigrations.kt b/app/src/main/java/code/name/monkey/retromusic/db/RoomMigrations.kt
deleted file mode 100644
index b8b383c31..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/RoomMigrations.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package code.name.monkey.retromusic.db
-
-import androidx.room.migration.Migration
-import androidx.sqlite.db.SupportSQLiteDatabase
-
-val MIGRATION_23_24 = object : Migration(23, 24) {
- override fun migrate(database: SupportSQLiteDatabase) {
- database.execSQL("DROP TABLE LyricsEntity")
- database.execSQL("DROP TABLE BlackListStoreEntity")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/SongEntity.kt b/app/src/main/java/code/name/monkey/retromusic/db/SongEntity.kt
deleted file mode 100644
index 206c91e27..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/SongEntity.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.db
-
-import android.os.Parcelable
-import androidx.room.ColumnInfo
-import androidx.room.Entity
-import androidx.room.Index
-import androidx.room.PrimaryKey
-import kotlinx.parcelize.Parcelize
-
-@Parcelize
-@Entity(indices = [Index(value = ["playlist_creator_id", "id"], unique = true)])
-class SongEntity(
- @PrimaryKey(autoGenerate = true)
- @ColumnInfo(name = "song_key")
- val songPrimaryKey: Long = 0L,
- @ColumnInfo(name = "playlist_creator_id")
- val playlistCreatorId: Long,
- val id: Long,
- val title: String,
- @ColumnInfo(name = "track_number")
- val trackNumber: Int,
- val year: Int,
- val duration: Long,
- val data: String,
- @ColumnInfo(name = "date_modified")
- val dateModified: Long,
- @ColumnInfo(name = "album_id")
- val albumId: Long,
- @ColumnInfo(name = "album_name")
- val albumName: String,
- @ColumnInfo(name = "artist_id")
- val artistId: Long,
- @ColumnInfo(name = "artist_name")
- val artistName: String,
- val composer: String?,
- @ColumnInfo(name = "album_artist")
- val albumArtist: String?
-) : Parcelable
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/SongExtension.kt b/app/src/main/java/code/name/monkey/retromusic/db/SongExtension.kt
deleted file mode 100644
index d6fe11b05..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/db/SongExtension.kt
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.db
-
-import code.name.monkey.retromusic.model.Song
-
-fun List.fromHistoryToSongs(): List {
- return map {
- it.toSong()
- }
-}
-
-fun List.toSongs(): List {
- return map {
- it.toSong()
- }
-}
-
-fun Song.toHistoryEntity(timePlayed: Long): HistoryEntity {
- return HistoryEntity(
- id = id,
- title = title,
- trackNumber = trackNumber,
- year = year,
- duration = duration,
- data = data,
- dateModified = dateModified,
- albumId = albumId,
- albumName = albumName,
- artistId = artistId,
- artistName = artistName,
- composer = composer,
- albumArtist = albumArtist,
- timePlayed = timePlayed
- )
-}
-
-fun Song.toSongEntity(playListId: Long): SongEntity {
- return SongEntity(
- playlistCreatorId = playListId,
- id = id,
- title = title,
- trackNumber = trackNumber,
- year = year,
- duration = duration,
- data = data,
- dateModified = dateModified,
- albumId = albumId,
- albumName = albumName,
- artistId = artistId,
- artistName = artistName,
- composer = composer,
- albumArtist = albumArtist
- )
-}
-
-fun SongEntity.toSong(): Song {
- return Song(
- id = id,
- title = title,
- trackNumber = trackNumber,
- year = year,
- duration = duration,
- data = data,
- dateModified = dateModified,
- albumId = albumId,
- albumName = albumName,
- artistId = artistId,
- artistName = artistName,
- composer = composer,
- albumArtist = albumArtist
- )
-}
-
-fun PlayCountEntity.toSong(): Song {
- return Song(
- id = id,
- title = title,
- trackNumber = trackNumber,
- year = year,
- duration = duration,
- data = data,
- dateModified = dateModified,
- albumId = albumId,
- albumName = albumName,
- artistId = artistId,
- artistName = artistName,
- composer = composer,
- albumArtist = albumArtist
- )
-}
-
-fun HistoryEntity.toSong(): Song {
- return Song(
- id = id,
- title = title,
- trackNumber = trackNumber,
- year = year,
- duration = duration,
- data = data,
- dateModified = dateModified,
- albumId = albumId,
- albumName = albumName,
- artistId = artistId,
- artistName = artistName,
- composer = composer,
- albumArtist = albumArtist
- )
-}
-
-fun Song.toPlayCount(): PlayCountEntity {
- return PlayCountEntity(
- id = id,
- title = title,
- trackNumber = trackNumber,
- year = year,
- duration = duration,
- data = data,
- dateModified = dateModified,
- albumId = albumId,
- albumName = albumName,
- artistId = artistId,
- artistName = artistName,
- composer = composer,
- albumArtist = albumArtist,
- timePlayed = System.currentTimeMillis(),
- playCount = 1
- )
-}
-
-fun List.toSongsEntity(playlistEntity: PlaylistEntity): List {
- return map {
- it.toSongEntity(playlistEntity.playListId)
- }
-}
-
-fun List.toSongsEntity(playlistId: Long): List {
- return map {
- it.toSongEntity(playlistId)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.java b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.java
new file mode 100644
index 000000000..4e84a0bcd
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.java
@@ -0,0 +1,86 @@
+package code.name.monkey.retromusic.dialogs;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.DefaultItemAnimator;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+import code.name.monkey.appthemehelper.ThemeStore;
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.loaders.PlaylistLoader;
+import code.name.monkey.retromusic.model.Playlist;
+import code.name.monkey.retromusic.model.Song;
+import code.name.monkey.retromusic.ui.adapter.playlist.AddToPlaylist;
+import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment;
+import java.util.ArrayList;
+
+/**
+ * @author Karim Abou Zeid (kabouzeid), Aidan Follestad (afollestad)
+ */
+public class AddToPlaylistDialog extends RoundedBottomSheetDialogFragment {
+
+ @BindView(R.id.playlists)
+ RecyclerView playlist;
+ @BindView(R.id.title)
+ TextView title;
+ ArrayList playlists;
+
+ @NonNull
+ public static AddToPlaylistDialog create(Song song) {
+ ArrayList list = new ArrayList<>();
+ list.add(song);
+ return create(list);
+ }
+
+ @NonNull
+ public static AddToPlaylistDialog create(ArrayList songs) {
+ AddToPlaylistDialog dialog = new AddToPlaylistDialog();
+ Bundle args = new Bundle();
+ args.putParcelableArrayList("songs", songs);
+ dialog.setArguments(args);
+ return dialog;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ View layout = inflater.inflate(R.layout.dialog_add_to_playlist, container, false);
+ ButterKnife.bind(this, layout);
+ return layout;
+ }
+
+ @SuppressWarnings("ConstantConditions")
+ @OnClick(R.id.action_add_playlist)
+ void newPlaylist() {
+ final ArrayList songs = getArguments().getParcelableArrayList("songs");
+ CreatePlaylistDialog.create(songs)
+ .show(getActivity().getSupportFragmentManager(), "ADD_TO_PLAYLIST");
+ dismiss();
+ }
+
+ @SuppressWarnings("ConstantConditions")
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ title.setTextColor(ThemeStore.textColorPrimary(getContext()));
+ final ArrayList songs = getArguments().getParcelableArrayList("songs");
+ playlists = PlaylistLoader.getAllPlaylists(getActivity()).blockingFirst();
+
+ AddToPlaylist playlistAdapter = new AddToPlaylist(getActivity(), playlists,
+ R.layout.item_playlist, songs, getDialog());
+
+ playlist.setLayoutManager(new LinearLayoutManager(getContext()));
+ playlist.setItemAnimator(new DefaultItemAnimator());
+ playlist.setAdapter(playlistAdapter);
+ }
+}
\ 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
deleted file mode 100644
index aa47f0fe2..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.dialogs
-
-import android.app.Dialog
-import android.os.Bundle
-import androidx.core.os.bundleOf
-import androidx.fragment.app.DialogFragment
-import code.name.monkey.retromusic.EXTRA_PLAYLISTS
-import code.name.monkey.retromusic.EXTRA_SONG
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.db.PlaylistEntity
-import code.name.monkey.retromusic.extensions.colorButtons
-import code.name.monkey.retromusic.extensions.extraNotNull
-import code.name.monkey.retromusic.extensions.materialDialog
-import code.name.monkey.retromusic.fragments.LibraryViewModel
-import code.name.monkey.retromusic.model.Song
-import org.koin.androidx.viewmodel.ext.android.activityViewModel
-
-class AddToPlaylistDialog : DialogFragment() {
- private val libraryViewModel by activityViewModel()
-
- companion object {
- fun create(playlistEntities: List, song: Song): AddToPlaylistDialog {
- val list: MutableList = mutableListOf()
- list.add(song)
- return create(playlistEntities, list)
- }
-
- fun create(playlistEntities: List, songs: List): AddToPlaylistDialog {
- return AddToPlaylistDialog().apply {
- arguments = bundleOf(
- EXTRA_SONG to songs,
- EXTRA_PLAYLISTS to playlistEntities
- )
- }
- }
- }
-
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- val playlistEntities = extraNotNull>(EXTRA_PLAYLISTS).value
- val songs = extraNotNull>(EXTRA_SONG).value
- val playlistNames = mutableListOf()
- playlistNames.add(requireContext().resources.getString(R.string.action_new_playlist))
- for (entity: PlaylistEntity in playlistEntities) {
- playlistNames.add(entity.playlistName)
- }
- return materialDialog(R.string.add_playlist_title)
- .setItems(playlistNames.toTypedArray()) { dialog, which ->
- if (which == 0) {
- showCreateDialog(songs)
- } else {
- libraryViewModel.addToPlaylist(requireContext(), playlistNames[which], songs)
- }
- dialog.dismiss()
- }
- .setNegativeButton(R.string.action_cancel, null)
- .create()
- .colorButtons()
- }
-
- private fun showCreateDialog(songs: List) {
- CreatePlaylistDialog.create(songs).show(requireActivity().supportFragmentManager, "Dialog")
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/BlacklistFolderChooserDialog.java b/app/src/main/java/code/name/monkey/retromusic/dialogs/BlacklistFolderChooserDialog.java
new file mode 100644
index 000000000..4602d50ba
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/BlacklistFolderChooserDialog.java
@@ -0,0 +1,159 @@
+package code.name.monkey.retromusic.dialogs;
+
+import android.Manifest;
+import android.app.Dialog;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Environment;
+import android.support.annotation.NonNull;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.app.DialogFragment;
+import android.view.View;
+
+import com.afollestad.materialdialogs.MaterialDialog;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import code.name.monkey.retromusic.R;
+
+/**
+ * @author Aidan Follestad (afollestad), modified by Karim Abou Zeid
+ */
+public class BlacklistFolderChooserDialog extends DialogFragment implements MaterialDialog.ListCallback {
+
+ private File parentFolder;
+ private File[] parentContents;
+ private boolean canGoUp = false;
+
+ private FolderCallback callback;
+
+ String initialPath = Environment.getExternalStorageDirectory().getAbsolutePath();
+
+ private String[] getContentsArray() {
+ if (parentContents == null) {
+ if (canGoUp) {
+ return new String[]{".."};
+ }
+ return new String[]{};
+ }
+ String[] results = new String[parentContents.length + (canGoUp ? 1 : 0)];
+ if (canGoUp) {
+ results[0] = "..";
+ }
+ for (int i = 0; i < parentContents.length; i++) {
+ results[canGoUp ? i + 1 : i] = parentContents[i].getName();
+ }
+ return results;
+ }
+
+ private File[] listFiles() {
+ File[] contents = parentFolder.listFiles();
+ List results = new ArrayList<>();
+ if (contents != null) {
+ for (File fi : contents) {
+ if (fi.isDirectory()) {
+ results.add(fi);
+ }
+ }
+ Collections.sort(results, new FolderSorter());
+ return results.toArray(new File[results.size()]);
+ }
+ return null;
+ }
+
+ public static BlacklistFolderChooserDialog create() {
+ return new BlacklistFolderChooserDialog();
+ }
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
+ != PackageManager.PERMISSION_GRANTED) {
+ return new MaterialDialog.Builder(getActivity())
+ .title(R.string.md_error_label)
+ .content(R.string.md_storage_perm_error)
+ .positiveText(android.R.string.ok)
+ .build();
+ }
+ if (savedInstanceState == null) {
+ savedInstanceState = new Bundle();
+ }
+ if (!savedInstanceState.containsKey("current_path")) {
+ savedInstanceState.putString("current_path", initialPath);
+ }
+ parentFolder = new File(savedInstanceState.getString("current_path", File.pathSeparator));
+ checkIfCanGoUp();
+ parentContents = listFiles();
+ MaterialDialog.Builder builder =
+ new MaterialDialog.Builder(getActivity())
+ .title(parentFolder.getAbsolutePath())
+ .items((CharSequence[]) getContentsArray())
+ .itemsCallback(this)
+ .autoDismiss(false)
+ .onPositive((dialog, which) -> {
+ dismiss();
+ callback.onFolderSelection(BlacklistFolderChooserDialog.this, parentFolder);
+ })
+ .onNegative((materialDialog, dialogAction) -> dismiss())
+ .positiveText(R.string.add_action)
+ .negativeText(android.R.string.cancel);
+ return builder.build();
+ }
+
+ @Override
+ public void onSelection(MaterialDialog materialDialog, View view, int i, CharSequence s) {
+ if (canGoUp && i == 0) {
+ parentFolder = parentFolder.getParentFile();
+ if (parentFolder.getAbsolutePath().equals("/storage/emulated")) {
+ parentFolder = parentFolder.getParentFile();
+ }
+ checkIfCanGoUp();
+ } else {
+ parentFolder = parentContents[canGoUp ? i - 1 : i];
+ canGoUp = true;
+ if (parentFolder.getAbsolutePath().equals("/storage/emulated")) {
+ parentFolder = Environment.getExternalStorageDirectory();
+ }
+ }
+ reload();
+ }
+
+ private void checkIfCanGoUp() {
+ canGoUp = parentFolder.getParent() != null;
+ }
+
+ private void reload() {
+ parentContents = listFiles();
+ MaterialDialog dialog = (MaterialDialog) getDialog();
+ dialog.setTitle(parentFolder.getAbsolutePath());
+ dialog.setItems((CharSequence[]) getContentsArray());
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putString("current_path", parentFolder.getAbsolutePath());
+ }
+
+ public void setCallback(FolderCallback callback) {
+ this.callback = callback;
+ }
+
+ public interface FolderCallback {
+ void onFolderSelection(@NonNull BlacklistFolderChooserDialog dialog, @NonNull File folder);
+ }
+
+ private static class FolderSorter implements Comparator {
+
+ @Override
+ public int compare(File lhs, File rhs) {
+ return lhs.getName().compareTo(rhs.getName());
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/BlacklistFolderChooserDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/BlacklistFolderChooserDialog.kt
deleted file mode 100644
index 5701d858b..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/BlacklistFolderChooserDialog.kt
+++ /dev/null
@@ -1,140 +0,0 @@
-package code.name.monkey.retromusic.dialogs
-
-import android.Manifest
-import android.app.Dialog
-import android.content.Context
-import android.content.pm.PackageManager
-import android.os.Bundle
-import androidx.core.app.ActivityCompat
-import androidx.fragment.app.DialogFragment
-import code.name.monkey.appthemehelper.util.VersionUtils
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.extensions.materialDialog
-import code.name.monkey.retromusic.util.getExternalStorageDirectory
-import com.afollestad.materialdialogs.MaterialDialog
-import com.afollestad.materialdialogs.list.listItems
-import com.afollestad.materialdialogs.list.updateListItems
-import java.io.File
-
-class BlacklistFolderChooserDialog : DialogFragment() {
- private var initialPath: String = getExternalStorageDirectory().absolutePath
- private var parentFolder: File? = null
- private var parentContents: Array? = null
- private var canGoUp = false
- private var callback: FolderCallback? = null
- private val contentsArray: Array
- get() {
- if (parentContents == null) {
- return if (canGoUp) {
- arrayOf("..")
- } else arrayOf()
- }
- val results = arrayOfNulls(parentContents!!.size + if (canGoUp) 1 else 0)
- if (canGoUp) {
- results[0] = ".."
- }
- for (i in parentContents!!.indices) {
- results[if (canGoUp) i + 1 else i] = parentContents?.getOrNull(i)?.name
- }
- return results
- }
-
- private fun listFiles(): Array? {
- val results = mutableListOf()
- parentFolder?.listFiles()?.let { files ->
- files.forEach { file -> if (file.isDirectory) results.add(file) }
- return results.sortedBy { it.name }.toTypedArray()
- }
- return null
- }
-
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- var mSavedInstanceState = savedInstanceState
- if (VersionUtils.hasMarshmallow()
- && ActivityCompat.checkSelfPermission(
- requireActivity(), Manifest.permission.READ_EXTERNAL_STORAGE
- )
- != PackageManager.PERMISSION_GRANTED
- ) {
- return materialDialog().show {
- title(res = R.string.md_error_label)
- message(res = R.string.md_storage_perm_error)
- positiveButton(res = android.R.string.ok)
- }
- }
- if (mSavedInstanceState == null) {
- mSavedInstanceState = Bundle()
- }
- if (!mSavedInstanceState.containsKey("current_path")) {
- mSavedInstanceState.putString("current_path", initialPath)
- }
- parentFolder = File(mSavedInstanceState.getString("current_path", File.pathSeparator))
- checkIfCanGoUp()
- parentContents = listFiles()
- return materialDialog()
- .title(text = parentFolder?.absolutePath)
- .listItems(
- items = contentsArray.toCharSequence(),
- waitForPositiveButton = false
- ) { _: MaterialDialog, i: Int, _: CharSequence ->
- onSelection(i)
- }
- .noAutoDismiss()
- .positiveButton(res = R.string.add_action) {
- callback?.onFolderSelection(requireContext(), parentFolder!!)
- dismiss()
- }
- .negativeButton(res = android.R.string.cancel) { dismiss() }
- }
-
- private fun onSelection(i: Int) {
- if (canGoUp && i == 0) {
- parentFolder = parentFolder?.parentFile
- if (parentFolder?.absolutePath == "/storage/emulated") {
- parentFolder = parentFolder?.parentFile
- }
- checkIfCanGoUp()
- } else {
- parentFolder = parentContents?.getOrNull(if (canGoUp) i - 1 else i)
- canGoUp = true
- if (parentFolder?.absolutePath == "/storage/emulated") {
- parentFolder = getExternalStorageDirectory()
- }
- }
- reload()
- }
-
- private fun checkIfCanGoUp() {
- canGoUp = parentFolder?.parent != null
- }
-
- private fun reload() {
- parentContents = listFiles()
- val dialog = dialog as MaterialDialog?
- dialog?.setTitle(parentFolder?.absolutePath)
- dialog?.updateListItems(items = contentsArray.toCharSequence())
- }
-
- private fun Array.toCharSequence(): List {
- return map { it as CharSequence }
- }
-
- override fun onSaveInstanceState(outState: Bundle) {
- super.onSaveInstanceState(outState)
- outState.putString("current_path", parentFolder?.absolutePath)
- }
-
- fun setCallback(callback: FolderCallback?) {
- this.callback = callback
- }
-
- interface FolderCallback {
- fun onFolderSelection(context: Context, folder: File)
- }
-
- companion object {
- fun create(): BlacklistFolderChooserDialog {
- return BlacklistFolderChooserDialog()
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/ClearSmartPlaylistDialog.java b/app/src/main/java/code/name/monkey/retromusic/dialogs/ClearSmartPlaylistDialog.java
new file mode 100644
index 000000000..2358c2aad
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/ClearSmartPlaylistDialog.java
@@ -0,0 +1,52 @@
+package code.name.monkey.retromusic.dialogs;
+
+import android.app.Dialog;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.DialogFragment;
+import android.text.Html;
+
+import com.afollestad.materialdialogs.DialogAction;
+import com.afollestad.materialdialogs.MaterialDialog;
+
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist;
+
+
+public class ClearSmartPlaylistDialog extends DialogFragment {
+
+ @NonNull
+ public static ClearSmartPlaylistDialog create(AbsSmartPlaylist playlist) {
+ ClearSmartPlaylistDialog dialog = new ClearSmartPlaylistDialog();
+ Bundle args = new Bundle();
+ args.putParcelable("playlist", playlist);
+ dialog.setArguments(args);
+ return dialog;
+ }
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ //noinspection unchecked
+ final AbsSmartPlaylist playlist = getArguments().getParcelable("playlist");
+ int title = R.string.clear_playlist_title;
+ //noinspection ConstantConditions
+ CharSequence content = Html.fromHtml(getString(R.string.clear_playlist_x, playlist.name));
+
+ return new MaterialDialog.Builder(getActivity())
+ .title(title)
+ .content(content)
+ .positiveText(R.string.clear_action)
+ .negativeText(android.R.string.cancel)
+ .onPositive(new MaterialDialog.SingleButtonCallback() {
+ @Override
+ public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
+ if (getActivity() == null) {
+ return;
+ }
+ playlist.clear(getActivity());
+ }
+ })
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.java b/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.java
new file mode 100644
index 000000000..a09cf4cfa
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.java
@@ -0,0 +1,103 @@
+package code.name.monkey.retromusic.dialogs;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.design.widget.BottomSheetDialogFragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
+
+import java.util.ArrayList;
+import java.util.Objects;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+import code.name.monkey.appthemehelper.ThemeStore;
+import code.name.monkey.appthemehelper.util.TintHelper;
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.model.Song;
+import code.name.monkey.retromusic.util.PlaylistsUtil;
+import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment;
+
+/**
+ * @author Karim Abou Zeid (kabouzeid), Aidan Follestad (afollestad)
+ */
+public class CreatePlaylistDialog extends RoundedBottomSheetDialogFragment {
+
+ @BindView(R.id.option_1)
+ EditText playlistName;
+ @BindView(R.id.action_cancel)
+ Button actionCancel;
+ @BindView(R.id.action_create)
+ Button actionCreate;
+
+ @NonNull
+ public static CreatePlaylistDialog create() {
+ return create((Song) null);
+ }
+
+ @NonNull
+ public static CreatePlaylistDialog create(@Nullable Song song) {
+ ArrayList list = new ArrayList<>();
+ if (song != null) {
+ list.add(song);
+ }
+ return create(list);
+ }
+
+ @NonNull
+ public static CreatePlaylistDialog create(ArrayList songs) {
+ CreatePlaylistDialog dialog = new CreatePlaylistDialog();
+ Bundle args = new Bundle();
+ args.putParcelableArrayList("songs", songs);
+ dialog.setArguments(args);
+ return dialog;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ View layout = inflater.inflate(R.layout.dialog_create_playlist, container, false);
+ ButterKnife.bind(this, layout);
+ return layout;
+ }
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ int accentColor = ThemeStore.accentColor(Objects.requireNonNull(getContext()));
+ TintHelper.setTintAuto(playlistName, accentColor, true);
+ TintHelper.setTintAuto(actionCreate, accentColor, true);
+ actionCancel.setTextColor(accentColor);
+ }
+
+ @OnClick({R.id.action_cancel, R.id.action_create})
+ void actions(View view) {
+ switch (view.getId()) {
+ case R.id.action_cancel:
+ dismiss();
+ break;
+ case R.id.action_create:
+ if (getActivity() == null) {
+ return;
+ }
+ if (!playlistName.getText().toString().trim().isEmpty()) {
+ final int playlistId = PlaylistsUtil
+ .createPlaylist(getActivity(), playlistName.getText().toString());
+ if (playlistId != -1 && getActivity() != null) {
+ //noinspection unchecked
+ ArrayList songs = getArguments().getParcelableArrayList("songs");
+ if (songs != null) {
+ PlaylistsUtil.addToPlaylist(getActivity(), songs, playlistId, true);
+ }
+ }
+ }
+ break;
+ }
+ dismiss();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.kt
deleted file mode 100644
index 7d7a01c90..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.dialogs
-
-import android.app.Dialog
-import android.os.Bundle
-import android.text.TextUtils
-import androidx.core.os.bundleOf
-import androidx.fragment.app.DialogFragment
-import code.name.monkey.retromusic.EXTRA_SONG
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.databinding.DialogPlaylistBinding
-import code.name.monkey.retromusic.extensions.colorButtons
-import code.name.monkey.retromusic.extensions.extra
-import code.name.monkey.retromusic.extensions.materialDialog
-import code.name.monkey.retromusic.fragments.LibraryViewModel
-import code.name.monkey.retromusic.model.Song
-import com.google.android.material.textfield.TextInputEditText
-import com.google.android.material.textfield.TextInputLayout
-import org.koin.androidx.viewmodel.ext.android.activityViewModel
-
-class CreatePlaylistDialog : DialogFragment() {
- private var _binding: DialogPlaylistBinding? = null
- private val binding get() = _binding!!
- private val libraryViewModel by activityViewModel()
-
- companion object {
- fun create(song: Song): CreatePlaylistDialog {
- val list = mutableListOf()
- list.add(song)
- return create(list)
- }
-
- fun create(songs: List): CreatePlaylistDialog {
- return CreatePlaylistDialog().apply {
- arguments = bundleOf(EXTRA_SONG to songs)
- }
- }
- }
-
-
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- _binding = DialogPlaylistBinding.inflate(layoutInflater)
-
- val songs: List = extra>(EXTRA_SONG).value ?: emptyList()
- val playlistView: TextInputEditText = binding.actionNewPlaylist
- val playlistContainer: TextInputLayout = binding.actionNewPlaylistContainer
- return materialDialog(R.string.new_playlist_title)
- .setView(binding.root)
- .setPositiveButton(
- R.string.create_action
- ) { _, _ ->
- val playlistName = playlistView.text.toString()
- if (!TextUtils.isEmpty(playlistName)) {
- libraryViewModel.addToPlaylist(requireContext(), playlistName, songs)
- } else {
- playlistContainer.error = "Playlist name can't be empty"
- }
- }
- .setNegativeButton(R.string.action_cancel, null)
- .create()
- .colorButtons()
- }
-
- override fun onDestroyView() {
- super.onDestroyView()
- _binding = null
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.java b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.java
new file mode 100644
index 000000000..5e408ca81
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.java
@@ -0,0 +1,89 @@
+package code.name.monkey.retromusic.dialogs;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.model.Playlist;
+import code.name.monkey.retromusic.util.PlaylistsUtil;
+import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment;
+
+
+public class DeletePlaylistDialog extends RoundedBottomSheetDialogFragment {
+
+ @BindView(R.id.action_delete)
+ TextView delete;
+ @BindView(R.id.title)
+ TextView title;
+ @BindView(R.id.action_cancel)
+ TextView cancel;
+
+ @NonNull
+ public static DeletePlaylistDialog create(Playlist playlist) {
+ ArrayList list = new ArrayList<>();
+ list.add(playlist);
+ return create(list);
+ }
+
+ @NonNull
+ public static DeletePlaylistDialog create(ArrayList playlists) {
+ DeletePlaylistDialog dialog = new DeletePlaylistDialog();
+ Bundle args = new Bundle();
+ args.putParcelableArrayList("playlists", playlists);
+ dialog.setArguments(args);
+ return dialog;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ View layout = inflater.inflate(R.layout.dialog_delete_playlist, container, false);
+ ButterKnife.bind(this, layout);
+ return layout;
+ }
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ //noinspection unchecked
+ final ArrayList playlists = getArguments().getParcelableArrayList("playlists");
+ int title;
+ CharSequence content;
+ //noinspection ConstantConditions
+ if (playlists.size() > 1) {
+ title = R.string.delete_playlists_title;
+ content = Html.fromHtml(getString(R.string.delete_x_playlists, playlists.size()));
+ } else {
+ title = R.string.delete_playlist_title;
+ content = Html.fromHtml(getString(R.string.delete_playlist_x, playlists.get(0).name));
+ }
+ this.title.setText(title);
+ this.delete.setText(content);
+ }
+
+ @OnClick({R.id.action_cancel, R.id.action_delete})
+ void actions(View view) {
+ final ArrayList playlists = getArguments().getParcelableArrayList("playlists");
+ switch (view.getId()) {
+ case R.id.action_delete:
+ if (getActivity() == null)
+ return;
+ PlaylistsUtil.deletePlaylists(getActivity(), playlists);
+ break;
+ default:
+ }
+ dismiss();
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.kt
deleted file mode 100644
index 30675d88a..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.kt
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2020 Hemanth Savarla.
- *
- * 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.dialogs
-
-import android.app.Dialog
-import android.os.Bundle
-import androidx.core.os.bundleOf
-import androidx.core.text.parseAsHtml
-import androidx.fragment.app.DialogFragment
-import code.name.monkey.retromusic.EXTRA_PLAYLIST
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.db.PlaylistEntity
-import code.name.monkey.retromusic.extensions.colorButtons
-import code.name.monkey.retromusic.extensions.extraNotNull
-import code.name.monkey.retromusic.extensions.materialDialog
-import code.name.monkey.retromusic.fragments.LibraryViewModel
-import code.name.monkey.retromusic.fragments.ReloadType
-import org.koin.androidx.viewmodel.ext.android.activityViewModel
-
-class DeletePlaylistDialog : DialogFragment() {
-
- private val libraryViewModel by activityViewModel()
-
- companion object {
-
- fun create(playlist: PlaylistEntity): DeletePlaylistDialog {
- val list = mutableListOf()
- list.add(playlist)
- return create(list)
- }
-
- fun create(playlists: List): DeletePlaylistDialog {
- return DeletePlaylistDialog().apply {
- arguments = bundleOf(EXTRA_PLAYLIST to playlists)
- }
- }
- }
-
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- val playlists = extraNotNull>(EXTRA_PLAYLIST).value
- val title: Int
- val message: CharSequence
- //noinspection ConstantConditions
- if (playlists.size > 1) {
- title = R.string.delete_playlists_title
- message =
- String.format(getString(R.string.delete_x_playlists), playlists.size).parseAsHtml()
- } else {
- title = R.string.delete_playlist_title
- message =
- String.format(getString(R.string.delete_playlist_x), playlists[0].playlistName)
- .parseAsHtml()
- }
-
- return materialDialog(title)
- .setTitle(title)
- .setMessage(message)
- .setNegativeButton(android.R.string.cancel, null)
- .setPositiveButton(R.string.action_delete) { _, _ ->
- libraryViewModel.deleteSongsFromPlaylist(playlists)
- libraryViewModel.deleteRoomPlaylist(playlists)
- libraryViewModel.forceReload(ReloadType.Playlists)
- }
- .create()
- .colorButtons()
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteSongsDialog.java b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteSongsDialog.java
new file mode 100644
index 000000000..9a30ba3f7
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteSongsDialog.java
@@ -0,0 +1,92 @@
+package code.name.monkey.retromusic.dialogs;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.model.Song;
+import code.name.monkey.retromusic.util.MusicUtil;
+import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment;
+import java.util.ArrayList;
+
+public class DeleteSongsDialog extends RoundedBottomSheetDialogFragment {
+
+ @BindView(R.id.action_delete)
+ TextView delete;
+ @BindView(R.id.title)
+ TextView title;
+ @BindView(R.id.action_cancel)
+ TextView cancel;
+
+ @NonNull
+ public static DeleteSongsDialog create(Song song) {
+ ArrayList list = new ArrayList<>();
+ list.add(song);
+ return create(list);
+ }
+
+ @NonNull
+ public static DeleteSongsDialog create(ArrayList songs) {
+ DeleteSongsDialog dialog = new DeleteSongsDialog();
+ Bundle args = new Bundle();
+ args.putParcelableArrayList("songs", songs);
+ dialog.setArguments(args);
+ return dialog;
+ }
+
+ @OnClick({R.id.action_cancel, R.id.action_delete})
+ void actions(View view) {
+ //noinspection ConstantConditions
+ final ArrayList songs = getArguments().getParcelableArrayList("songs");
+ switch (view.getId()) {
+ case R.id.action_delete:
+ if (getActivity() == null) {
+ return;
+ }
+ if (songs != null) {
+ MusicUtil.deleteTracks(getActivity(), songs);
+ }
+ break;
+ default:
+ }
+ dismiss();
+ }
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ //noinspection unchecked,ConstantConditions
+ final ArrayList