Merge branch 'dev' of https://github.com/h4h13/RetroMusicPlayer into dev
Conflicts: README.md app/build.gradle app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt app/src/main/java/code/name/monkey/retromusic/activities/SupportDevelopmentActivity.kt app/src/main/java/code/name/monkey/retromusic/fragments/player/lockscreen/LockScreenPlayerControlsFragment.kt app/src/main/java/code/name/monkey/retromusic/interfaces/CabHolder.kt app/src/main/java/code/name/monkey/retromusic/interfaces/MainActivityFragmentCallbacks.kt app/src/main/java/code/name/monkey/retromusic/interfaces/MusicServiceEventListener.kt app/src/main/java/code/name/monkey/retromusic/interfaces/PaletteColorHolder.kt app/src/main/java/code/name/monkey/retromusic/util/AppRater.kt app/src/main/java/io/github/muntashirakon/music/App.kt app/src/main/java/io/github/muntashirakon/music/Constants.kt app/src/main/java/io/github/muntashirakon/music/HomeSection.kt app/src/main/java/io/github/muntashirakon/music/MainModule.kt app/src/main/java/io/github/muntashirakon/music/activities/DriveModeActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/LicenseActivity.java app/src/main/java/io/github/muntashirakon/music/activities/LockScreenActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/LyricsActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/MainActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/PermissionActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/PlayingQueueActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/SettingsActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/ShareInstagramStory.kt app/src/main/java/io/github/muntashirakon/music/activities/UserInfoActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/WhatsNewActivity.java app/src/main/java/io/github/muntashirakon/music/activities/base/AbsBaseActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/base/AbsMusicServiceActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/base/AbsSlidingMusicPanelActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/base/AbsThemeActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/bugreport/BugReportActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/bugreport/model/DeviceInfo.java app/src/main/java/io/github/muntashirakon/music/activities/bugreport/model/Report.java app/src/main/java/io/github/muntashirakon/music/activities/saf/SAFGuideActivity.java app/src/main/java/io/github/muntashirakon/music/activities/tageditor/AbsTagEditorActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/tageditor/AlbumTagEditorActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/tageditor/SongTagEditorActivity.kt app/src/main/java/io/github/muntashirakon/music/activities/tageditor/WriteTagsAsyncTask.java app/src/main/java/io/github/muntashirakon/music/adapter/CategoryInfoAdapter.java app/src/main/java/io/github/muntashirakon/music/adapter/ContributorAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/GenreAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/HomeAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/SearchAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/SongFileAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/TranslatorsAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/album/AlbumAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/album/AlbumCoverPagerAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/album/HorizontalAlbumAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/artist/ArtistAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/base/AbsMultiSelectAdapter.java app/src/main/java/io/github/muntashirakon/music/adapter/base/MediaEntryViewHolder.java app/src/main/java/io/github/muntashirakon/music/adapter/playlist/LegacyPlaylistAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/playlist/PlaylistAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/song/AbsOffsetSongAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/song/OrderablePlaylistSongAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/song/PlayingQueueAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/song/PlaylistSongAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/song/ShuffleButtonSongAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/song/SimpleSongAdapter.kt app/src/main/java/io/github/muntashirakon/music/adapter/song/SongAdapter.kt app/src/main/java/io/github/muntashirakon/music/appshortcuts/AppShortcutIconGenerator.kt app/src/main/java/io/github/muntashirakon/music/appshortcuts/AppShortcutLauncherActivity.kt app/src/main/java/io/github/muntashirakon/music/appshortcuts/DynamicShortcutManager.kt app/src/main/java/io/github/muntashirakon/music/appshortcuts/shortcuttype/BaseShortcutType.kt app/src/main/java/io/github/muntashirakon/music/appshortcuts/shortcuttype/LastAddedShortcutType.kt app/src/main/java/io/github/muntashirakon/music/appshortcuts/shortcuttype/ShuffleAllShortcutType.kt app/src/main/java/io/github/muntashirakon/music/appshortcuts/shortcuttype/TopTracksShortcutType.kt app/src/main/java/io/github/muntashirakon/music/appwidgets/AppWidgetBig.kt app/src/main/java/io/github/muntashirakon/music/appwidgets/AppWidgetCard.kt app/src/main/java/io/github/muntashirakon/music/appwidgets/AppWidgetClassic.kt app/src/main/java/io/github/muntashirakon/music/appwidgets/AppWidgetSmall.kt app/src/main/java/io/github/muntashirakon/music/appwidgets/AppWidgetText.kt app/src/main/java/io/github/muntashirakon/music/appwidgets/BootReceiver.kt app/src/main/java/io/github/muntashirakon/music/appwidgets/base/BaseAppWidget.kt app/src/main/java/io/github/muntashirakon/music/db/BlackListStoreDao.kt app/src/main/java/io/github/muntashirakon/music/db/BlackListStoreEntity.kt app/src/main/java/io/github/muntashirakon/music/db/HistoryDao.kt app/src/main/java/io/github/muntashirakon/music/db/HistoryEntity.kt app/src/main/java/io/github/muntashirakon/music/db/LyricsDao.kt app/src/main/java/io/github/muntashirakon/music/db/LyricsEntity.kt app/src/main/java/io/github/muntashirakon/music/db/PlayCountDao.kt app/src/main/java/io/github/muntashirakon/music/db/PlayCountEntity.kt app/src/main/java/io/github/muntashirakon/music/db/PlaylistDao.kt app/src/main/java/io/github/muntashirakon/music/db/PlaylistEntity.kt app/src/main/java/io/github/muntashirakon/music/db/PlaylistWithSongs.kt app/src/main/java/io/github/muntashirakon/music/db/RetroDatabase.kt app/src/main/java/io/github/muntashirakon/music/db/SongEntity.kt app/src/main/java/io/github/muntashirakon/music/db/SongExtension.kt app/src/main/java/io/github/muntashirakon/music/dialogs/AddToPlaylistDialog.kt app/src/main/java/io/github/muntashirakon/music/dialogs/BlacklistFolderChooserDialog.java app/src/main/java/io/github/muntashirakon/music/dialogs/CreatePlaylistDialog.kt app/src/main/java/io/github/muntashirakon/music/dialogs/DeletePlaylistDialog.kt app/src/main/java/io/github/muntashirakon/music/dialogs/DeleteSongsDialog.kt app/src/main/java/io/github/muntashirakon/music/dialogs/ImportPlaylistDialog.kt app/src/main/java/io/github/muntashirakon/music/dialogs/LyricsDialog.kt app/src/main/java/io/github/muntashirakon/music/dialogs/RemoveSongFromPlaylistDialog.kt app/src/main/java/io/github/muntashirakon/music/dialogs/RenamePlaylistDialog.kt app/src/main/java/io/github/muntashirakon/music/dialogs/SavePlaylistDialog.kt app/src/main/java/io/github/muntashirakon/music/dialogs/SleepTimerDialog.kt app/src/main/java/io/github/muntashirakon/music/dialogs/SongDetailDialog.kt app/src/main/java/io/github/muntashirakon/music/dialogs/SongShareDialog.kt app/src/main/java/io/github/muntashirakon/music/extensions/ActivityEx.kt app/src/main/java/io/github/muntashirakon/music/extensions/ColorExt.kt app/src/main/java/io/github/muntashirakon/music/extensions/CursorExtensions.kt app/src/main/java/io/github/muntashirakon/music/extensions/DialogExtension.kt app/src/main/java/io/github/muntashirakon/music/extensions/DimenExtension.kt app/src/main/java/io/github/muntashirakon/music/extensions/DrawableExt.kt app/src/main/java/io/github/muntashirakon/music/extensions/FragmentExt.kt app/src/main/java/io/github/muntashirakon/music/extensions/NavigationExtensions.kt app/src/main/java/io/github/muntashirakon/music/extensions/PaletteEX.kt app/src/main/java/io/github/muntashirakon/music/extensions/Preference.kt app/src/main/java/io/github/muntashirakon/music/extensions/ViewExtensions.kt app/src/main/java/io/github/muntashirakon/music/fragments/AlbumCoverStyle.kt app/src/main/java/io/github/muntashirakon/music/fragments/CoroutineViewModel.kt app/src/main/java/io/github/muntashirakon/music/fragments/DetailListFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/LibraryViewModel.kt app/src/main/java/io/github/muntashirakon/music/fragments/MiniPlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/NowPlayingScreen.kt app/src/main/java/io/github/muntashirakon/music/fragments/VolumeFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/about/AboutFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsViewModel.kt app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistDetailsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistDetailsViewModel.kt app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsMainActivityFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsMusicServiceFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsPlayerControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsPlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsRecyclerViewCustomGridSizeFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsRecyclerViewFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/folder/FoldersFragment.java app/src/main/java/io/github/muntashirakon/music/fragments/genres/GenreDetailsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/genres/GenreDetailsViewModel.kt app/src/main/java/io/github/muntashirakon/music/fragments/genres/GenresFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/home/HomeFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/library/LibraryFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/NowPlayingPlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/PlayerAlbumCoverFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/adaptive/AdaptiveFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/adaptive/AdaptivePlaybackControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/blur/BlurPlaybackControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/blur/BlurPlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/card/CardFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/card/CardPlaybackControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/cardblur/CardBlurFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/cardblur/CardBlurPlaybackControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/circle/CirclePlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/classic/ClassicPlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/color/ColorFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/color/ColorPlaybackControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/fit/FitFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/fit/FitPlaybackControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/flat/FlatPlaybackControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/flat/FlatPlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/full/FullPlaybackControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/full/FullPlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/gradient/GradientPlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/home/HomePlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/lockscreen/LockScreenControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/lockscreen/LockScreenPlayerControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/material/MaterialControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/material/MaterialFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/normal/PlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/normal/PlayerPlaybackControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/peak/PeakPlayerControlFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/peak/PeakPlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/plain/PlainPlaybackControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/plain/PlainPlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/simple/SimplePlaybackControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/simple/SimplePlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/tiny/TinyPlaybackControlsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/player/tiny/TinyPlayerFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/playlists/PlaylistDetailsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/playlists/PlaylistDetailsViewModel.kt app/src/main/java/io/github/muntashirakon/music/fragments/playlists/PlaylistsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/search/SearchFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/search/SearchViewModel.kt app/src/main/java/io/github/muntashirakon/music/fragments/settings/AbsSettingsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/settings/AudioSettings.kt app/src/main/java/io/github/muntashirakon/music/fragments/settings/ImageSettingFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/settings/MainSettingsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/settings/NotificationSettingsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/settings/NowPlayingSettingsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/settings/OtherSettingsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/settings/PersonalizeSettingsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/settings/ThemeSettingsFragment.kt app/src/main/java/io/github/muntashirakon/music/fragments/songs/SongsFragment.kt app/src/main/java/io/github/muntashirakon/music/glide/AlbumGlideRequest.java app/src/main/java/io/github/muntashirakon/music/glide/ArtistGlideRequest.java app/src/main/java/io/github/muntashirakon/music/glide/BlurTransformation.kt app/src/main/java/io/github/muntashirakon/music/glide/ProfileBannerGlideRequest.java app/src/main/java/io/github/muntashirakon/music/glide/RetroMusicColoredTarget.kt app/src/main/java/io/github/muntashirakon/music/glide/RetroMusicGlideModule.kt app/src/main/java/io/github/muntashirakon/music/glide/SingleColorTarget.kt app/src/main/java/io/github/muntashirakon/music/glide/SongGlideRequest.java app/src/main/java/io/github/muntashirakon/music/glide/UserProfileGlideRequest.java app/src/main/java/io/github/muntashirakon/music/glide/artistimage/ArtistImageLoader.kt app/src/main/java/io/github/muntashirakon/music/glide/palette/BitmapPaletteTranscoder.java app/src/main/java/io/github/muntashirakon/music/helper/HorizontalAdapterHelper.kt app/src/main/java/io/github/muntashirakon/music/helper/MusicPlayerRemote.kt app/src/main/java/io/github/muntashirakon/music/helper/MusicProgressViewUpdateHelper.kt app/src/main/java/io/github/muntashirakon/music/helper/PlayPauseButtonOnClickHandler.kt app/src/main/java/io/github/muntashirakon/music/helper/SearchQueryHelper.kt app/src/main/java/io/github/muntashirakon/music/helper/ShuffleHelper.kt app/src/main/java/io/github/muntashirakon/music/helper/StopWatch.kt app/src/main/java/io/github/muntashirakon/music/helper/menu/GenreMenuHelper.kt app/src/main/java/io/github/muntashirakon/music/helper/menu/PlaylistMenuHelper.kt app/src/main/java/io/github/muntashirakon/music/helper/menu/SongMenuHelper.kt app/src/main/java/io/github/muntashirakon/music/helper/menu/SongsMenuHelper.kt app/src/main/java/io/github/muntashirakon/music/interfaces/CabHolder.kt app/src/main/java/io/github/muntashirakon/music/interfaces/Callbacks.kt app/src/main/java/io/github/muntashirakon/music/interfaces/ICabHolder.kt app/src/main/java/io/github/muntashirakon/music/interfaces/IMainActivityFragmentCallbacks.kt app/src/main/java/io/github/muntashirakon/music/interfaces/IMusicServiceEventListener.kt app/src/main/java/io/github/muntashirakon/music/interfaces/IPaletteColorHolder.kt app/src/main/java/io/github/muntashirakon/music/interfaces/MainActivityFragmentCallbacks.kt app/src/main/java/io/github/muntashirakon/music/interfaces/MusicServiceEventListener.kt app/src/main/java/io/github/muntashirakon/music/interfaces/PaletteColorHolder.kt app/src/main/java/io/github/muntashirakon/music/lyrics/LrcView.java app/src/main/java/io/github/muntashirakon/music/model/Artist.kt app/src/main/java/io/github/muntashirakon/music/model/lyrics/Lyrics.java app/src/main/java/io/github/muntashirakon/music/providers/BlacklistStore.java app/src/main/java/io/github/muntashirakon/music/providers/MusicPlaybackQueueStore.java app/src/main/java/io/github/muntashirakon/music/repository/GenreRepository.kt app/src/main/java/io/github/muntashirakon/music/repository/PlaylistSongsLoader.kt app/src/main/java/io/github/muntashirakon/music/repository/Repository.kt app/src/main/java/io/github/muntashirakon/music/repository/RoomRepository.kt app/src/main/java/io/github/muntashirakon/music/repository/SongRepository.kt app/src/main/java/io/github/muntashirakon/music/service/MultiPlayer.java app/src/main/java/io/github/muntashirakon/music/service/MusicService.java app/src/main/java/io/github/muntashirakon/music/service/PlaybackHandler.java app/src/main/java/io/github/muntashirakon/music/util/FileUtil.java app/src/main/java/io/github/muntashirakon/music/util/NavigationUtil.java app/src/main/java/io/github/muntashirakon/music/util/PlaylistsUtil.java app/src/main/java/io/github/muntashirakon/music/util/PreferenceUtil.kt app/src/main/java/io/github/muntashirakon/music/util/RetroUtil.java app/src/main/java/io/github/muntashirakon/music/util/SAFUtil.java app/src/main/java/io/github/muntashirakon/music/util/color/MediaNotificationProcessor.java app/src/main/java/io/github/muntashirakon/music/util/color/NotificationColorUtil.java app/src/main/java/io/github/muntashirakon/music/views/BaselineGridTextView.java app/src/main/java/io/github/muntashirakon/music/views/BreadCrumbLayout.java app/src/main/java/io/github/muntashirakon/music/views/CircularImageView.java app/src/main/java/io/github/muntashirakon/music/views/ContributorsView.java app/src/main/java/io/github/muntashirakon/music/views/NetworkImageView.java app/src/main/java/io/github/muntashirakon/music/views/SeekArc.java app/src/main/res/layout-land/fragment_home.xml app/src/main/res/layout-xlarge-land/fragment_blur.xml app/src/main/res/layout/activity_lock_screen.xml app/src/main/res/layout/activity_user_info.xml app/src/main/res/layout/fragment_banner_home.xml app/src/main/res/layout/fragment_classic_player.xml app/src/main/res/layout/fragment_folder.xml app/src/main/res/layout/fragment_home.xml app/src/main/res/layout/item_image.xml app/src/main/res/layout/sliding_music_panel_layout.xml app/src/main/res/navigation/now_playing.xml
This commit is contained in:
commit
3c0fc790d1
442 changed files with 18453 additions and 14559 deletions
19
README.md
19
README.md
|
@ -40,7 +40,7 @@ Dark and Just Black for AMOLED displays. Select your favorite accent
|
|||
color from a color palette.
|
||||
|
||||
### 🏠 Home
|
||||
Where you can have your recently/top played artists, albums and
|
||||
Where you can view your recently/top played artists, albums and
|
||||
favorite songs. No other music player has this feature.
|
||||
|
||||
### 📦 Included Features
|
||||
|
@ -49,33 +49,32 @@ favorite songs. No other music player has this feature.
|
|||
- Driving Mode
|
||||
- Headset/Bluetooth support
|
||||
- Music duration filter
|
||||
- Folder support - Play song by folder
|
||||
- Folder support - Play songs by folder
|
||||
- Gapless playback
|
||||
- Volume controls
|
||||
- Carousel effect for an album cover
|
||||
- Carousel effect for album covers
|
||||
- Home screen widgets
|
||||
- Lock screen playback controls
|
||||
- Lyrics screen (download and sync with music)
|
||||
- Sleep Timer
|
||||
- Sleep timer
|
||||
- Easy drag to sort playlist & play queue
|
||||
- Tag editor
|
||||
- Create, edit and import playlists
|
||||
- Playing queue with reorder
|
||||
- User profile
|
||||
- 30 Languages support
|
||||
- 30+ languages support
|
||||
- Browse and play your music by songs, albums, artists, playlists and
|
||||
genre
|
||||
- Smart Auto Playlists - Recently played, most played and history
|
||||
- Build your own playlist on the go
|
||||
- Build your playlist on the go
|
||||
|
||||
|
||||
We are trying our best to bring you the best user experience. The app is regulary being updated for bug fixes and new features.
|
||||
We are trying our best to bring you the best user experience. The app is regularly being updated for bug fixes and new features.
|
||||
|
||||
### 🗂️ License
|
||||
|
||||
Metro is released under the GNU General Public License v3.0
|
||||
(GPLv3), which can be found here: [License](LICENSE.md)
|
||||
(GPLv3), which can be found [here](LICENSE.md)
|
||||
|
||||
|
||||
>Please note: Retro Music player is an offline music player app. It
|
||||
>doesn't support music downloading or online music streaming.
|
||||
> Please note: Metro is an offline music player app. It doesn't support music downloading or online music streaming.
|
||||
|
|
|
@ -6,7 +6,7 @@ apply plugin: "androidx.navigation.safeargs.kotlin"
|
|||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion = '30.0.1'
|
||||
buildToolsVersion = '30.0.2'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
|
@ -16,8 +16,8 @@ android {
|
|||
vectorDrawables.useSupportLibrary = true
|
||||
|
||||
applicationId 'io.github.muntashirakon.Music'
|
||||
versionCode 10445
|
||||
versionName '3.5.11'
|
||||
versionCode 10503
|
||||
versionName '4.0.010'
|
||||
|
||||
multiDexEnabled true
|
||||
}
|
||||
|
@ -134,4 +134,6 @@ dependencies {
|
|||
implementation 'me.jorgecastillo:androidcolorx:0.2.0'
|
||||
implementation 'org.jsoup:jsoup:1.11.1'
|
||||
debugImplementation 'com.amitshekhar.android:debug-db:1.0.6'
|
||||
}
|
||||
}
|
||||
|
||||
apply from: '../spotless.gradle'
|
||||
|
|
30
app/proguard-rules.pro
vendored
30
app/proguard-rules.pro
vendored
|
@ -26,13 +26,11 @@
|
|||
|
||||
-dontwarn java.lang.invoke.*
|
||||
-dontwarn **$$Lambda$*
|
||||
-dontwarn javax.annotation.**
|
||||
|
||||
# RetroFit
|
||||
-dontwarn retrofit.**
|
||||
-keep class retrofit.** { *; }
|
||||
-keepattributes Signature
|
||||
-keepattributes Exceptions
|
||||
-dontwarn javax.annotation.**
|
||||
|
||||
# Glide
|
||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||
|
@ -41,14 +39,24 @@
|
|||
public *;
|
||||
}
|
||||
|
||||
# OkHttp
|
||||
-keepattributes Signature
|
||||
-keepattributes *Annotation*
|
||||
-keep interface com.squareup.okhttp3.** { *; }
|
||||
-dontwarn com.squareup.okhttp3.**
|
||||
|
||||
-dontwarn
|
||||
-ignorewarnings
|
||||
#-dontwarn
|
||||
#-ignorewarnings
|
||||
-dontshrink
|
||||
-dontobfuscate
|
||||
|
||||
#-dontwarn android.support.v8.renderscript.*
|
||||
#-keepclassmembers class android.support.v8.renderscript.RenderScript {
|
||||
# native *** rsn*(...);
|
||||
# native *** n*(...);
|
||||
#}
|
||||
-dontwarn org.jaudiotagger.**
|
||||
-keep class org.jaudiotagger.** { *; }
|
||||
|
||||
#-keep class org.jaudiotagger.** { *; }
|
||||
-keepclassmembers enum * { *; }
|
||||
-keepattributes *Annotation*, Signature, Exception
|
||||
-keepnames class androidx.navigation.fragment.NavHostFragment
|
||||
-keepnames class code.name.monkey.retromusic.model.Home
|
||||
-keep class * extends androidx.fragment.app.Fragment{}
|
||||
-keepnames class * extends android.os.Parcelable
|
||||
-keepnames class * extends java.io.Serializable
|
|
@ -88,4 +88,9 @@
|
|||
<item name="android:letterSpacing">0.0125</item>
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
</style>
|
||||
|
||||
<style name="circleImageView" parent="">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">5%</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -5,6 +5,7 @@
|
|||
android:installLocation="auto">
|
||||
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
@ -116,11 +117,7 @@
|
|||
<activity android:name=".activities.ShareInstagramStory" />
|
||||
<activity android:name=".activities.DriveModeActivity" />
|
||||
<activity android:name=".activities.PermissionActivity" />
|
||||
|
||||
<activity
|
||||
android:name=".activities.LockScreenActivity"
|
||||
android:noHistory="true"
|
||||
android:showOnLockScreen="true" />
|
||||
<activity android:name=".activities.LockScreenActivity" />
|
||||
|
||||
<activity
|
||||
android:name=".appshortcuts.AppShortcutLauncherActivity"
|
||||
|
|
|
@ -3,24 +3,30 @@
|
|||
"name": "Hemanth Savarala",
|
||||
"summary": "Lead Developer & Designer",
|
||||
"link": "https://github.com/h4h13",
|
||||
"profile_image": "https://i.imgur.com/AoVs9oj.jpg"
|
||||
"image": "https://i.imgur.com/AoVs9oj.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Lennart Glamann",
|
||||
"summary": "Play Store banner and Images",
|
||||
"summary": "Play Store Banner & Images",
|
||||
"link": "https://t.me/FlixbusLennart",
|
||||
"profile_image": "https://i.imgur.com/Q5Nsx1R.jpg"
|
||||
"image": "https://i.imgur.com/Q5Nsx1R.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Daksh P. Jain",
|
||||
"summary": "Support Representative & Moderator",
|
||||
"link": "https://daksh.eu.org",
|
||||
"profile_image": "https://i.imgur.com/fnYpg65.jpg"
|
||||
"image": "https://i.imgur.com/fnYpg65.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Milind Goel",
|
||||
"summary": "Support Representative & Moderator",
|
||||
"link": "https://t.me/MilindGoel15",
|
||||
"profile_image": "https://i.imgur.com/Bz4De21_d.jpg"
|
||||
"image": "https://i.imgur.com/Bz4De21_d.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Haythem Gataa",
|
||||
"summary": "App Logo Designer",
|
||||
"link": "https://dribbble.com/haythemgataa",
|
||||
"image": "https://i.imgur.com/g5RuIZq.jpg"
|
||||
}
|
||||
]
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 18 KiB |
|
@ -1,17 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music
|
||||
|
||||
import androidx.multidex.MultiDexApplication
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music
|
||||
|
||||
import android.provider.BaseColumns
|
||||
|
@ -46,9 +45,9 @@ object Constants {
|
|||
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
|
||||
MediaStore.Audio.AudioColumns.ARTIST, // 10
|
||||
MediaStore.Audio.AudioColumns.COMPOSER, // 11
|
||||
"album_artist" // 12
|
||||
)
|
||||
const val NUMBER_OF_TOP_TRACKS = 99
|
||||
}
|
||||
|
@ -76,6 +75,8 @@ 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"
|
||||
|
@ -87,6 +88,7 @@ const val BANNER_IMAGE_PATH = "banner_image_path"
|
|||
const val ADAPTIVE_COLOR_APP = "adaptive_color_app"
|
||||
const val TOGGLE_SEPARATE_LINE = "toggle_separate_line"
|
||||
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"
|
||||
|
@ -105,6 +107,7 @@ 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"
|
||||
|
@ -123,9 +126,11 @@ const val AUTO_DOWNLOAD_IMAGES_POLICY = "auto_download_images_policy"
|
|||
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_DETAIL_SONG_SORT_ORDER = "album_detail_song_sort_order"
|
||||
const val LYRICS_OPTIONS = "lyrics_tab_position"
|
||||
const val CHOOSE_EQUALIZER = "choose_equalizer"
|
||||
const val EQUALIZER = "equalizer"
|
||||
const val TOGGLE_SHUFFLE = "toggle_shuffle"
|
||||
const val SONG_GRID_STYLE = "song_grid_style"
|
||||
const val PAUSE_ON_ZERO_VOLUME = "pause_on_zero_volume"
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music
|
||||
|
||||
import androidx.annotation.IntDef
|
||||
|
@ -25,4 +39,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
|
||||
const val TOP_PLAYED_PLAYLIST = 10
|
||||
|
|
|
@ -5,39 +5,37 @@ import android.content.ContextWrapper;
|
|||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.os.LocaleList;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils;
|
||||
import java.util.Locale;
|
||||
|
||||
public class LanguageContextWrapper extends ContextWrapper {
|
||||
|
||||
public LanguageContextWrapper(Context base) {
|
||||
super(base);
|
||||
public LanguageContextWrapper(Context base) {
|
||||
super(base);
|
||||
}
|
||||
|
||||
public static LanguageContextWrapper wrap(Context context, Locale newLocale) {
|
||||
Resources res = context.getResources();
|
||||
Configuration configuration = res.getConfiguration();
|
||||
|
||||
if (VersionUtils.INSTANCE.hasNougatMR()) {
|
||||
configuration.setLocale(newLocale);
|
||||
|
||||
LocaleList localeList = new LocaleList(newLocale);
|
||||
LocaleList.setDefault(localeList);
|
||||
configuration.setLocales(localeList);
|
||||
|
||||
context = context.createConfigurationContext(configuration);
|
||||
|
||||
} else if (VersionUtils.INSTANCE.hasLollipop()) {
|
||||
configuration.setLocale(newLocale);
|
||||
context = context.createConfigurationContext(configuration);
|
||||
|
||||
} else {
|
||||
configuration.locale = newLocale;
|
||||
res.updateConfiguration(configuration, res.getDisplayMetrics());
|
||||
}
|
||||
|
||||
public static LanguageContextWrapper wrap(Context context, Locale newLocale) {
|
||||
Resources res = context.getResources();
|
||||
Configuration configuration = res.getConfiguration();
|
||||
|
||||
if (VersionUtils.INSTANCE.hasNougatMR()) {
|
||||
configuration.setLocale(newLocale);
|
||||
|
||||
LocaleList localeList = new LocaleList(newLocale);
|
||||
LocaleList.setDefault(localeList);
|
||||
configuration.setLocales(localeList);
|
||||
|
||||
context = context.createConfigurationContext(configuration);
|
||||
|
||||
} else if (VersionUtils.INSTANCE.hasLollipop()) {
|
||||
configuration.setLocale(newLocale);
|
||||
context = context.createConfigurationContext(configuration);
|
||||
|
||||
} else {
|
||||
configuration.locale = newLocale;
|
||||
res.updateConfiguration(configuration, res.getDisplayMetrics());
|
||||
}
|
||||
|
||||
return new LanguageContextWrapper(context);
|
||||
}
|
||||
}
|
||||
return new LanguageContextWrapper(context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,11 @@ import io.github.muntashirakon.music.fragments.albums.AlbumDetailsViewModel
|
|||
import io.github.muntashirakon.music.fragments.artists.ArtistDetailsViewModel
|
||||
import io.github.muntashirakon.music.fragments.genres.GenreDetailsViewModel
|
||||
import io.github.muntashirakon.music.fragments.playlists.PlaylistDetailsViewModel
|
||||
import io.github.muntashirakon.music.fragments.search.SearchViewModel
|
||||
import io.github.muntashirakon.music.model.Genre
|
||||
import io.github.muntashirakon.music.network.*
|
||||
import io.github.muntashirakon.music.network.provideDefaultCache
|
||||
import io.github.muntashirakon.music.network.provideLastFmRest
|
||||
import io.github.muntashirakon.music.network.provideLastFmRetrofit
|
||||
import io.github.muntashirakon.music.network.provideOkHttp
|
||||
import io.github.muntashirakon.music.repository.*
|
||||
import io.github.muntashirakon.music.util.FilePathUtil
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
|
@ -36,15 +38,9 @@ val networkModule = module {
|
|||
single {
|
||||
provideLastFmRetrofit(get())
|
||||
}
|
||||
single {
|
||||
provideDeezerRest(get())
|
||||
}
|
||||
single {
|
||||
provideLastFmRest(get())
|
||||
}
|
||||
single {
|
||||
provideLyrics(get())
|
||||
}
|
||||
}
|
||||
|
||||
private val roomModule = module {
|
||||
|
@ -93,7 +89,6 @@ private val mainModule = module {
|
|||
single {
|
||||
androidContext().contentResolver
|
||||
}
|
||||
|
||||
}
|
||||
private val dataModule = module {
|
||||
single {
|
||||
|
@ -109,7 +104,7 @@ private val dataModule = module {
|
|||
get(),
|
||||
get(),
|
||||
get(),
|
||||
get()
|
||||
get(),
|
||||
)
|
||||
} bind Repository::class
|
||||
|
||||
|
@ -154,6 +149,9 @@ private val dataModule = module {
|
|||
get()
|
||||
)
|
||||
}
|
||||
single {
|
||||
RealLocalDataRepository(get())
|
||||
} bind LocalDataRepository::class
|
||||
}
|
||||
|
||||
private val viewModules = module {
|
||||
|
@ -189,10 +187,6 @@ private val viewModules = module {
|
|||
genre
|
||||
)
|
||||
}
|
||||
|
||||
viewModel {
|
||||
SearchViewModel(get())
|
||||
}
|
||||
}
|
||||
|
||||
val appModules = listOf(mainModule, dataModule, viewModules, networkModule, roomModule)
|
|
@ -4,36 +4,32 @@ import android.content.Context;
|
|||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
public class RetroBottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {
|
||||
|
||||
private static final String TAG = "RetroBottomSheetBehavior";
|
||||
private static final String TAG = "RetroBottomSheetBehavior";
|
||||
|
||||
private boolean allowDragging = true;
|
||||
private boolean allowDragging = true;
|
||||
|
||||
public RetroBottomSheetBehavior() {
|
||||
public RetroBottomSheetBehavior() {}
|
||||
|
||||
public RetroBottomSheetBehavior(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public void setAllowDragging(boolean allowDragging) {
|
||||
this.allowDragging = allowDragging;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(
|
||||
@NotNull CoordinatorLayout parent, @NotNull V child, @NotNull MotionEvent event) {
|
||||
if (!allowDragging) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public RetroBottomSheetBehavior(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public void setAllowDragging(boolean allowDragging) {
|
||||
this.allowDragging = allowDragging;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(@NotNull CoordinatorLayout parent, @NotNull V child, @NotNull MotionEvent event) {
|
||||
if (!allowDragging) {
|
||||
return false;
|
||||
}
|
||||
return super.onInterceptTouchEvent(parent, child, event);
|
||||
}
|
||||
}
|
||||
return super.onInterceptTouchEvent(parent, child, event);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.activities
|
||||
|
||||
import android.animation.ObjectAnimator
|
||||
|
@ -234,4 +234,4 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback {
|
|||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,82 +18,86 @@ import android.graphics.Color;
|
|||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import io.github.muntashirakon.music.R;
|
||||
import io.github.muntashirakon.music.activities.base.AbsBaseActivity;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by hemanths on 2019-09-27.
|
||||
*/
|
||||
/** Created by hemanths on 2019-09-27. */
|
||||
public class LicenseActivity extends AbsBaseActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
setDrawUnderStatusBar();
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_license);
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
ToolbarContentTintHelper.colorBackButton(toolbar);
|
||||
toolbar.setBackgroundColor(ATHUtil.INSTANCE.resolveColor(this, R.attr.colorSurface));
|
||||
WebView webView = findViewById(R.id.license);
|
||||
try {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
InputStream json = getAssets().open("oldindex.html");
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(json, StandardCharsets.UTF_8));
|
||||
String str;
|
||||
while ((str = in.readLine()) != null) {
|
||||
buf.append(str);
|
||||
}
|
||||
in.close();
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
setDrawUnderStatusBar();
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_license);
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
ToolbarContentTintHelper.colorBackButton(toolbar);
|
||||
toolbar.setBackgroundColor(ATHUtil.INSTANCE.resolveColor(this, R.attr.colorSurface));
|
||||
WebView webView = findViewById(R.id.license);
|
||||
try {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
InputStream json = getAssets().open("oldindex.html");
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(json, StandardCharsets.UTF_8));
|
||||
String str;
|
||||
while ((str = in.readLine()) != null) {
|
||||
buf.append(str);
|
||||
}
|
||||
in.close();
|
||||
|
||||
// Inject color values for WebView body background and links
|
||||
final boolean isDark = ATHUtil.INSTANCE.isWindowBackgroundDark(this);
|
||||
final String backgroundColor = colorToCSS(ATHUtil.INSTANCE.resolveColor(this, R.attr.colorSurface,
|
||||
Color.parseColor(isDark ? "#424242" : "#ffffff")));
|
||||
final String contentColor = colorToCSS(Color.parseColor(isDark ? "#ffffff" : "#000000"));
|
||||
final String changeLog = buf.toString()
|
||||
.replace("{style-placeholder}",
|
||||
String.format("body { background-color: %s; color: %s; }", backgroundColor, contentColor))
|
||||
.replace("{link-color}", colorToCSS(ThemeStore.Companion.accentColor(this)))
|
||||
.replace("{link-color-active}",
|
||||
colorToCSS(ColorUtil.INSTANCE.lightenColor(ThemeStore.Companion.accentColor(this))));
|
||||
|
||||
webView.loadData(changeLog, "text/html", "UTF-8");
|
||||
} catch (Throwable e) {
|
||||
webView.loadData("<h1>Unable to load</h1><p>" + e.getLocalizedMessage() + "</p>", "text/html", "UTF-8");
|
||||
}
|
||||
// Inject color values for WebView body background and links
|
||||
final boolean isDark = ATHUtil.INSTANCE.isWindowBackgroundDark(this);
|
||||
final String backgroundColor =
|
||||
colorToCSS(
|
||||
ATHUtil.INSTANCE.resolveColor(
|
||||
this, R.attr.colorSurface, Color.parseColor(isDark ? "#424242" : "#ffffff")));
|
||||
final String contentColor = colorToCSS(Color.parseColor(isDark ? "#ffffff" : "#000000"));
|
||||
final String changeLog =
|
||||
buf.toString()
|
||||
.replace(
|
||||
"{style-placeholder}",
|
||||
String.format(
|
||||
"body { background-color: %s; color: %s; }", backgroundColor, contentColor))
|
||||
.replace("{link-color}", colorToCSS(ThemeStore.Companion.accentColor(this)))
|
||||
.replace(
|
||||
"{link-color-active}",
|
||||
colorToCSS(
|
||||
ColorUtil.INSTANCE.lightenColor(ThemeStore.Companion.accentColor(this))));
|
||||
|
||||
webView.loadData(changeLog, "text/html", "UTF-8");
|
||||
} catch (Throwable e) {
|
||||
webView.loadData(
|
||||
"<h1>Unable to load</h1><p>" + e.getLocalizedMessage() + "</p>", "text/html", "UTF-8");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private String colorToCSS(int color) {
|
||||
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
|
||||
}
|
||||
private String colorToCSS(int color) {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities
|
||||
|
||||
import android.app.KeyguardManager
|
||||
|
@ -9,7 +23,8 @@ import android.view.WindowManager
|
|||
import androidx.core.view.ViewCompat
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.activities.base.AbsMusicServiceActivity
|
||||
import io.github.muntashirakon.music.fragments.player.lockscreen.LockScreenPlayerControlsFragment
|
||||
import io.github.muntashirakon.music.extensions.whichFragment
|
||||
import io.github.muntashirakon.music.fragments.player.lockscreen.LockScreenControlsFragment
|
||||
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
|
||||
import io.github.muntashirakon.music.glide.SongGlideRequest
|
||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
||||
|
@ -22,21 +37,12 @@ import com.r0adkll.slidr.model.SlidrPosition
|
|||
import kotlinx.android.synthetic.main.activity_lock_screen.*
|
||||
|
||||
class LockScreenActivity : AbsMusicServiceActivity() {
|
||||
private var fragment: LockScreenPlayerControlsFragment? = null
|
||||
private var fragment: LockScreenControlsFragment? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setDrawUnderStatusBar()
|
||||
super.onCreate(savedInstanceState)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
||||
setShowWhenLocked(true)
|
||||
setTurnScreenOn(true)
|
||||
} else {
|
||||
this.window.addFlags(
|
||||
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
|
||||
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
|
||||
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
|
||||
)
|
||||
}
|
||||
lockScreenInit()
|
||||
setContentView(R.layout.activity_lock_screen)
|
||||
hideStatusBar()
|
||||
setStatusbarColorAuto()
|
||||
|
@ -67,8 +73,7 @@ class LockScreenActivity : AbsMusicServiceActivity() {
|
|||
|
||||
Slidr.attach(this, config)
|
||||
|
||||
fragment =
|
||||
supportFragmentManager.findFragmentById(R.id.playback_controls_fragment) as LockScreenPlayerControlsFragment?
|
||||
fragment = whichFragment<LockScreenControlsFragment>(R.id.playback_controls_fragment)
|
||||
|
||||
findViewById<View>(R.id.slide).apply {
|
||||
translationY = 100f
|
||||
|
@ -77,6 +82,19 @@ class LockScreenActivity : AbsMusicServiceActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun lockScreenInit() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
||||
setShowWhenLocked(true)
|
||||
val keyguardManager: KeyguardManager = getSystemService(KeyguardManager::class.java)
|
||||
keyguardManager.requestDismissKeyguard(this, null)
|
||||
} else {
|
||||
this.window.addFlags(
|
||||
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
|
||||
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged()
|
||||
updateSongs()
|
||||
|
@ -97,4 +115,4 @@ class LockScreenActivity : AbsMusicServiceActivity() {
|
|||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,25 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.WindowManager
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import io.github.muntashirakon.music.R
|
||||
|
@ -15,6 +31,10 @@ import io.github.muntashirakon.music.lyrics.LrcView
|
|||
import io.github.muntashirakon.music.model.Song
|
||||
import io.github.muntashirakon.music.util.LyricUtil
|
||||
import io.github.muntashirakon.music.util.RetroUtil
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.transition.platform.MaterialArcMotion
|
||||
import com.google.android.material.transition.platform.MaterialContainerTransform
|
||||
import com.google.android.material.transition.platform.MaterialContainerTransformSharedElementCallback
|
||||
import kotlinx.android.synthetic.main.activity_lyrics.*
|
||||
|
||||
class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.Callback {
|
||||
|
@ -31,9 +51,20 @@ class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.
|
|||
return baseUrl
|
||||
}
|
||||
|
||||
private fun buildContainerTransform(): MaterialContainerTransform {
|
||||
val transform = MaterialContainerTransform()
|
||||
transform.setAllContainerColors(
|
||||
MaterialColors.getColor(findViewById(R.id.container), R.attr.colorSurface)
|
||||
)
|
||||
transform.addTarget(R.id.container)
|
||||
transform.duration = 300
|
||||
return transform
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_lyrics)
|
||||
ViewCompat.setTransitionName(container, "lyrics")
|
||||
setStatusbarColorAuto()
|
||||
setTaskDescriptionColorAuto()
|
||||
setNavigationbarColorAuto()
|
||||
|
@ -122,4 +153,4 @@ class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.
|
|||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities
|
||||
|
||||
import android.content.Intent
|
||||
|
@ -8,17 +22,45 @@ import android.os.Bundle
|
|||
import android.provider.MediaStore
|
||||
import android.view.View
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import io.github.muntashirakon.music.*
|
||||
import androidx.navigation.ui.NavigationUI
|
||||
import io.github.muntashirakon.music.ADAPTIVE_COLOR_APP
|
||||
import io.github.muntashirakon.music.ALBUM_COVER_STYLE
|
||||
import io.github.muntashirakon.music.ALBUM_COVER_TRANSFORM
|
||||
import io.github.muntashirakon.music.BANNER_IMAGE_PATH
|
||||
import io.github.muntashirakon.music.BLACK_THEME
|
||||
import io.github.muntashirakon.music.CAROUSEL_EFFECT
|
||||
import io.github.muntashirakon.music.CIRCULAR_ALBUM_ART
|
||||
import io.github.muntashirakon.music.DESATURATED_COLOR
|
||||
import io.github.muntashirakon.music.EXTRA_SONG_INFO
|
||||
import io.github.muntashirakon.music.GENERAL_THEME
|
||||
import io.github.muntashirakon.music.HOME_ARTIST_GRID_STYLE
|
||||
import io.github.muntashirakon.music.KEEP_SCREEN_ON
|
||||
import io.github.muntashirakon.music.LANGUAGE_NAME
|
||||
import io.github.muntashirakon.music.LIBRARY_CATEGORIES
|
||||
import io.github.muntashirakon.music.NOW_PLAYING_SCREEN_ID
|
||||
import io.github.muntashirakon.music.PROFILE_IMAGE_PATH
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.ROUND_CORNERS
|
||||
import io.github.muntashirakon.music.TAB_TEXT_MODE
|
||||
import io.github.muntashirakon.music.TOGGLE_ADD_CONTROLS
|
||||
import io.github.muntashirakon.music.TOGGLE_FULL_SCREEN
|
||||
import io.github.muntashirakon.music.TOGGLE_GENRE
|
||||
import io.github.muntashirakon.music.TOGGLE_HOME_BANNER
|
||||
import io.github.muntashirakon.music.TOGGLE_SEPARATE_LINE
|
||||
import io.github.muntashirakon.music.TOGGLE_VOLUME
|
||||
import io.github.muntashirakon.music.USER_NAME
|
||||
import io.github.muntashirakon.music.activities.base.AbsSlidingMusicPanelActivity
|
||||
import io.github.muntashirakon.music.extensions.findNavController
|
||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
||||
import io.github.muntashirakon.music.helper.SearchQueryHelper.getSongs
|
||||
import io.github.muntashirakon.music.model.CategoryInfo
|
||||
import io.github.muntashirakon.music.model.Song
|
||||
import io.github.muntashirakon.music.repository.PlaylistSongsLoader
|
||||
import io.github.muntashirakon.music.service.MusicService
|
||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.android.ext.android.get
|
||||
|
||||
class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeListener {
|
||||
companion object {
|
||||
|
@ -28,21 +70,43 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
|
|||
}
|
||||
|
||||
override fun createContentView(): View {
|
||||
return wrapSlidingMusicPanel(R.layout.activity_main_content)
|
||||
return wrapSlidingMusicPanel()
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setDrawUnderStatusBar()
|
||||
super.onCreate(savedInstanceState)
|
||||
if (!hasPermissions()) {
|
||||
findNavController(R.id.fragment_container).navigate(R.id.permissionFragment)
|
||||
}
|
||||
setStatusbarColorAuto()
|
||||
setNavigationbarColorAuto()
|
||||
setLightNavigationBar(true)
|
||||
setTaskDescriptionColorAuto()
|
||||
hideStatusBar()
|
||||
updateTabs()
|
||||
|
||||
// NavigationUI.setupWithNavController(getBottomNavigationView(), findNavController(R.id.fragment_container))
|
||||
setupNavigationController()
|
||||
if (!hasPermissions()) {
|
||||
findNavController(R.id.fragment_container).navigate(R.id.permissionFragment)
|
||||
}
|
||||
|
||||
showPromotionalDialog()
|
||||
}
|
||||
|
||||
private fun showPromotionalDialog() {
|
||||
|
||||
}
|
||||
|
||||
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) {
|
||||
navGraph.startDestination = categoryInfo.category.id
|
||||
}
|
||||
navController.graph = navGraph
|
||||
NavigationUI.setupWithNavController(getBottomNavigationView(), navController)
|
||||
}
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean =
|
||||
|
@ -98,8 +162,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
|
|||
val id = parseLongFromIntent(intent, "playlistId", "playlist")
|
||||
if (id >= 0L) {
|
||||
val position: Int = intent.getIntExtra("position", 0)
|
||||
val songs: List<Song> =
|
||||
PlaylistSongsLoader.getPlaylistSongList(this@MainActivity, id)
|
||||
val songs: List<Song> = PlaylistSongsLoader.getPlaylistSongList(get(), id)
|
||||
MusicPlayerRemote.openQueue(songs, position, true)
|
||||
handled = true
|
||||
}
|
||||
|
@ -107,8 +170,9 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
|
|||
val id = parseLongFromIntent(intent, "albumId", "album")
|
||||
if (id >= 0L) {
|
||||
val position: Int = intent.getIntExtra("position", 0)
|
||||
val songs = libraryViewModel.albumById(id).songs
|
||||
MusicPlayerRemote.openQueue(
|
||||
libraryViewModel.albumById(id).songs,
|
||||
songs,
|
||||
position,
|
||||
true
|
||||
)
|
||||
|
@ -118,8 +182,9 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
|
|||
val id = parseLongFromIntent(intent, "artistId", "artist")
|
||||
if (id >= 0L) {
|
||||
val position: Int = intent.getIntExtra("position", 0)
|
||||
val songs: List<Song> = libraryViewModel.artistById(id).songs
|
||||
MusicPlayerRemote.openQueue(
|
||||
libraryViewModel.artistById(id).songs,
|
||||
songs,
|
||||
position,
|
||||
true
|
||||
)
|
||||
|
@ -130,11 +195,11 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
|
|||
setIntent(Intent())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun parseLongFromIntent(
|
||||
intent: Intent, longKey: String,
|
||||
intent: Intent,
|
||||
longKey: String,
|
||||
stringKey: String
|
||||
): Long {
|
||||
var id = intent.getLongExtra(longKey, -1)
|
||||
|
@ -150,4 +215,4 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
|
|||
}
|
||||
return id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities
|
||||
|
||||
import android.content.Intent
|
||||
|
@ -13,7 +27,6 @@ import io.github.muntashirakon.music.extensions.show
|
|||
import io.github.muntashirakon.music.util.RingtoneManager
|
||||
import kotlinx.android.synthetic.main.activity_permission.*
|
||||
|
||||
|
||||
class PermissionActivity : AbsMusicServiceActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -37,7 +50,7 @@ class PermissionActivity : AbsMusicServiceActivity() {
|
|||
}
|
||||
finish.accentBackgroundColor()
|
||||
finish.setOnClickListener {
|
||||
if (hasPermissions() && !RingtoneManager.requiresDialog(this)) {
|
||||
if (hasPermissions()) {
|
||||
startActivity(
|
||||
Intent(this, MainActivity::class.java).addFlags(
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK or
|
||||
|
@ -56,4 +69,4 @@ class PermissionActivity : AbsMusicServiceActivity() {
|
|||
)
|
||||
appNameText.text = appName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
|
|
|
@ -1,8 +1,23 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavDestination
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils
|
||||
import com.afollestad.materialdialogs.color.ColorChooserDialog
|
||||
|
@ -29,10 +44,26 @@ class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback {
|
|||
applyToolbar(toolbar)
|
||||
val navController: NavController = findNavController(R.id.contentFrame)
|
||||
navController.addOnDestinationChangedListener { _, _, _ ->
|
||||
toolbar.title = navController.currentDestination?.label
|
||||
toolbar.title = navController.currentDestination?.let { getStringFromDestination(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun getStringFromDestination(currentDestination: NavDestination): String {
|
||||
val idRes = when (currentDestination.id) {
|
||||
R.id.mainSettingsFragment -> R.string.action_settings
|
||||
R.id.audioSettings -> R.string.pref_header_audio
|
||||
R.id.imageSettingFragment -> R.string.pref_header_images
|
||||
R.id.notificationSettingsFragment -> R.string.notification
|
||||
R.id.nowPlayingSettingsFragment -> R.string.now_playing
|
||||
R.id.otherSettingsFragment -> R.string.others
|
||||
R.id.personalizeSettingsFragment -> R.string.personalize
|
||||
R.id.themeSettingsFragment -> R.string.general_settings_title
|
||||
R.id.aboutActivity -> R.string.action_about
|
||||
else -> R.id.action_settings
|
||||
}
|
||||
return getString(idRes)
|
||||
}
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean {
|
||||
return findNavController(R.id.contentFrame).navigateUp() || super.onSupportNavigateUp()
|
||||
}
|
||||
|
@ -49,7 +80,6 @@ class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback {
|
|||
}
|
||||
|
||||
override fun onColorChooserDismissed(dialog: ColorChooserDialog) {
|
||||
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
|
@ -58,4 +88,4 @@ class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback {
|
|||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.activities
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities
|
||||
|
||||
import android.app.Activity
|
||||
|
@ -11,12 +25,6 @@ import android.view.MenuItem
|
|||
import android.widget.Toast
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.github.dhaval2404.imagepicker.ImagePicker
|
||||
import com.github.dhaval2404.imagepicker.constant.ImageProvider
|
||||
import io.github.muntashirakon.music.Constants.USER_BANNER
|
||||
import io.github.muntashirakon.music.Constants.USER_PROFILE
|
||||
import io.github.muntashirakon.music.R
|
||||
|
@ -27,15 +35,21 @@ import io.github.muntashirakon.music.glide.ProfileBannerGlideRequest
|
|||
import io.github.muntashirakon.music.glide.UserProfileGlideRequest
|
||||
import io.github.muntashirakon.music.util.ImageUtil
|
||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.github.dhaval2404.imagepicker.ImagePicker
|
||||
import com.github.dhaval2404.imagepicker.constant.ImageProvider
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import kotlinx.android.synthetic.main.activity_user_info.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
|
||||
class UserInfoActivity : AbsBaseActivity() {
|
||||
|
||||
|
@ -55,7 +69,7 @@ class UserInfoActivity : AbsBaseActivity() {
|
|||
pickNewPhoto()
|
||||
}
|
||||
|
||||
bannerSelect.setOnClickListener {
|
||||
bannerImage.setOnClickListener {
|
||||
selectBannerImage()
|
||||
}
|
||||
|
||||
|
@ -114,7 +128,6 @@ class UserInfoActivity : AbsBaseActivity() {
|
|||
.start(PICK_IMAGE_REQUEST)
|
||||
}
|
||||
|
||||
|
||||
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == Activity.RESULT_OK && requestCode == PICK_IMAGE_REQUEST) {
|
||||
|
@ -209,9 +222,8 @@ class UserInfoActivity : AbsBaseActivity() {
|
|||
.into(userImage)
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
private const val PICK_IMAGE_REQUEST = 9002
|
||||
private const val PICK_BANNER_REQUEST = 9004
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,14 @@
|
|||
package io.github.muntashirakon.music.activities;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
|
@ -26,65 +17,95 @@ import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
|||
import io.github.muntashirakon.music.R;
|
||||
import io.github.muntashirakon.music.activities.base.AbsBaseActivity;
|
||||
import io.github.muntashirakon.music.util.PreferenceUtil;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
|
||||
public class WhatsNewActivity extends AbsBaseActivity {
|
||||
|
||||
private static String colorToCSS(int color) {
|
||||
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 static String colorToCSS(int color) {
|
||||
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 static void setChangelogRead(@NonNull Context context) {
|
||||
try {
|
||||
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
|
||||
int currentVersion = pInfo.versionCode;
|
||||
PreferenceUtil.INSTANCE.setLastVersion(currentVersion);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void setChangelogRead(@NonNull Context context) {
|
||||
try {
|
||||
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
|
||||
int currentVersion = pInfo.versionCode;
|
||||
PreferenceUtil.INSTANCE.setLastVersion(currentVersion);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
setDrawUnderStatusBar();
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_whats_new);
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
|
||||
WebView webView = findViewById(R.id.webView);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
toolbar.setBackgroundColor(ATHUtil.INSTANCE.resolveColor(this, R.attr.colorSurface));
|
||||
toolbar.setNavigationOnClickListener(v -> onBackPressed());
|
||||
ToolbarContentTintHelper.colorBackButton(toolbar);
|
||||
|
||||
try {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
InputStream json = getAssets().open("retro-changelog.html");
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(json, StandardCharsets.UTF_8));
|
||||
String str;
|
||||
while ((str = in.readLine()) != null) {
|
||||
buf.append(str);
|
||||
}
|
||||
in.close();
|
||||
|
||||
// Inject color values for WebView body background and links
|
||||
final boolean isDark = ATHUtil.INSTANCE.isWindowBackgroundDark(this);
|
||||
final int accentColor = ThemeStore.Companion.accentColor(this);
|
||||
final String backgroundColor =
|
||||
colorToCSS(
|
||||
ATHUtil.INSTANCE.resolveColor(
|
||||
this, R.attr.colorSurface, Color.parseColor(isDark ? "#424242" : "#ffffff")));
|
||||
final String contentColor = colorToCSS(Color.parseColor(isDark ? "#ffffff" : "#000000"));
|
||||
final String textColor = colorToCSS(Color.parseColor(isDark ? "#60FFFFFF" : "#80000000"));
|
||||
final String accentColorString = colorToCSS(ThemeStore.Companion.accentColor(this));
|
||||
final String accentTextColor =
|
||||
colorToCSS(
|
||||
MaterialValueHelper.getPrimaryTextColor(
|
||||
this, ColorUtil.INSTANCE.isColorLight(accentColor)));
|
||||
final String changeLog =
|
||||
buf.toString()
|
||||
.replace(
|
||||
"{style-placeholder}",
|
||||
String.format(
|
||||
"body { background-color: %s; color: %s; } li {color: %s;} .colorHeader {background-color: %s; color: %s;} .tag {color: %s;}",
|
||||
backgroundColor,
|
||||
contentColor,
|
||||
textColor,
|
||||
accentColorString,
|
||||
accentTextColor,
|
||||
accentColorString))
|
||||
.replace("{link-color}", colorToCSS(ThemeStore.Companion.accentColor(this)))
|
||||
.replace(
|
||||
"{link-color-active}",
|
||||
colorToCSS(
|
||||
ColorUtil.INSTANCE.lightenColor(ThemeStore.Companion.accentColor(this))));
|
||||
webView.loadData(changeLog, "text/html", "UTF-8");
|
||||
} catch (Throwable e) {
|
||||
webView.loadData(
|
||||
"<h1>Unable to load</h1><p>" + e.getLocalizedMessage() + "</p>", "text/html", "UTF-8");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
setDrawUnderStatusBar();
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_whats_new);
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
|
||||
WebView webView = findViewById(R.id.webView);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
toolbar.setBackgroundColor(ATHUtil.INSTANCE.resolveColor(this, R.attr.colorSurface));
|
||||
toolbar.setNavigationOnClickListener(v -> onBackPressed());
|
||||
ToolbarContentTintHelper.colorBackButton(toolbar);
|
||||
|
||||
try {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
InputStream json = getAssets().open("retro-changelog.html");
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(json, StandardCharsets.UTF_8));
|
||||
String str;
|
||||
while ((str = in.readLine()) != null) {
|
||||
buf.append(str);
|
||||
}
|
||||
in.close();
|
||||
|
||||
// Inject color values for WebView body background and links
|
||||
final boolean isDark = ATHUtil.INSTANCE.isWindowBackgroundDark(this);
|
||||
final int accentColor = ThemeStore.Companion.accentColor(this);
|
||||
final String backgroundColor = colorToCSS(ATHUtil.INSTANCE.resolveColor(this, R.attr.colorSurface, Color.parseColor(isDark ? "#424242" : "#ffffff")));
|
||||
final String contentColor = colorToCSS(Color.parseColor(isDark ? "#ffffff" : "#000000"));
|
||||
final String textColor = colorToCSS(Color.parseColor(isDark ? "#60FFFFFF" : "#80000000"));
|
||||
final String accentColorString = colorToCSS(ThemeStore.Companion.accentColor(this));
|
||||
final String accentTextColor = colorToCSS(MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.INSTANCE.isColorLight(accentColor)));
|
||||
final String changeLog = buf.toString()
|
||||
.replace("{style-placeholder}", String.format("body { background-color: %s; color: %s; } li {color: %s;} .colorHeader {background-color: %s; color: %s;} .tag {color: %s;}", backgroundColor, contentColor, textColor, accentColorString, accentTextColor, accentColorString))
|
||||
.replace("{link-color}", colorToCSS(ThemeStore.Companion.accentColor(this)))
|
||||
.replace("{link-color-active}", colorToCSS(ColorUtil.INSTANCE.lightenColor(ThemeStore.Companion.accentColor(this))));
|
||||
webView.loadData(changeLog, "text/html", "UTF-8");
|
||||
} catch (Throwable e) {
|
||||
webView.loadData("<h1>Unable to load</h1><p>" + e.getLocalizedMessage() + "</p>", "text/html", "UTF-8");
|
||||
}
|
||||
setChangelogRead(this);
|
||||
}
|
||||
}
|
||||
setChangelogRead(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities.base
|
||||
|
||||
import android.Manifest
|
||||
|
@ -12,8 +26,8 @@ import android.view.KeyEvent
|
|||
import android.view.View
|
||||
import androidx.core.app.ActivityCompat
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import io.github.muntashirakon.music.R
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
|
||||
abstract class AbsBaseActivity : AbsThemeActivity() {
|
||||
private var hadPermissions: Boolean = false
|
||||
|
@ -46,7 +60,7 @@ abstract class AbsBaseActivity : AbsThemeActivity() {
|
|||
override fun onPostCreate(savedInstanceState: Bundle?) {
|
||||
super.onPostCreate(savedInstanceState)
|
||||
if (!hasPermissions()) {
|
||||
//requestPermissions()
|
||||
// requestPermissions()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +121,7 @@ abstract class AbsBaseActivity : AbsThemeActivity() {
|
|||
this@AbsBaseActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
)
|
||||
) {
|
||||
//User has deny from permission dialog
|
||||
// User has deny from permission dialog
|
||||
Snackbar.make(
|
||||
snackBarContainer,
|
||||
permissionDeniedMessage!!,
|
||||
|
|
|
@ -1,25 +1,44 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities.base
|
||||
|
||||
import android.Manifest
|
||||
import android.content.*
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.ServiceConnection
|
||||
import android.os.Bundle
|
||||
import android.os.IBinder
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.db.toPlayCount
|
||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
||||
import io.github.muntashirakon.music.interfaces.MusicServiceEventListener
|
||||
import io.github.muntashirakon.music.interfaces.IMusicServiceEventListener
|
||||
import io.github.muntashirakon.music.repository.RealRepository
|
||||
import io.github.muntashirakon.music.service.MusicService.*
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.android.ext.android.inject
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
|
||||
abstract class AbsMusicServiceActivity : AbsBaseActivity(), MusicServiceEventListener {
|
||||
abstract class AbsMusicServiceActivity : AbsBaseActivity(), IMusicServiceEventListener {
|
||||
|
||||
private val mMusicServiceEventListeners = ArrayList<MusicServiceEventListener>()
|
||||
private val mMusicServiceEventListeners = ArrayList<IMusicServiceEventListener>()
|
||||
private val repository: RealRepository by inject()
|
||||
private var serviceToken: MusicPlayerRemote.ServiceToken? = null
|
||||
private var musicStateReceiver: MusicStateReceiver? = null
|
||||
|
@ -49,15 +68,15 @@ abstract class AbsMusicServiceActivity : AbsBaseActivity(), MusicServiceEventLis
|
|||
}
|
||||
}
|
||||
|
||||
fun addMusicServiceEventListener(listener: MusicServiceEventListener?) {
|
||||
if (listener != null) {
|
||||
mMusicServiceEventListeners.add(listener)
|
||||
fun addMusicServiceEventListener(listenerI: IMusicServiceEventListener?) {
|
||||
if (listenerI != null) {
|
||||
mMusicServiceEventListeners.add(listenerI)
|
||||
}
|
||||
}
|
||||
|
||||
fun removeMusicServiceEventListener(listener: MusicServiceEventListener?) {
|
||||
if (listener != null) {
|
||||
mMusicServiceEventListeners.remove(listener)
|
||||
fun removeMusicServiceEventListener(listenerI: IMusicServiceEventListener?) {
|
||||
if (listenerI != null) {
|
||||
mMusicServiceEventListeners.remove(listenerI)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,30 +1,63 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities.base
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewTreeObserver
|
||||
import android.widget.FrameLayout
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.commit
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.RetroBottomSheetBehavior
|
||||
import io.github.muntashirakon.music.extensions.hide
|
||||
import io.github.muntashirakon.music.extensions.whichFragment
|
||||
import io.github.muntashirakon.music.extensions.*
|
||||
import io.github.muntashirakon.music.fragments.LibraryViewModel
|
||||
import io.github.muntashirakon.music.fragments.MiniPlayerFragment
|
||||
import io.github.muntashirakon.music.fragments.NowPlayingScreen
|
||||
import io.github.muntashirakon.music.fragments.NowPlayingScreen.*
|
||||
import io.github.muntashirakon.music.fragments.base.AbsPlayerFragment
|
||||
import io.github.muntashirakon.music.fragments.player.adaptive.AdaptiveFragment
|
||||
import io.github.muntashirakon.music.fragments.player.blur.BlurPlayerFragment
|
||||
import io.github.muntashirakon.music.fragments.player.card.CardFragment
|
||||
import io.github.muntashirakon.music.fragments.player.cardblur.CardBlurFragment
|
||||
import io.github.muntashirakon.music.fragments.player.circle.CirclePlayerFragment
|
||||
import io.github.muntashirakon.music.fragments.player.classic.ClassicPlayerFragment
|
||||
import io.github.muntashirakon.music.fragments.player.color.ColorFragment
|
||||
import io.github.muntashirakon.music.fragments.player.fit.FitFragment
|
||||
import io.github.muntashirakon.music.fragments.player.flat.FlatPlayerFragment
|
||||
import io.github.muntashirakon.music.fragments.player.full.FullPlayerFragment
|
||||
import io.github.muntashirakon.music.fragments.player.gradient.GradientPlayerFragment
|
||||
import io.github.muntashirakon.music.fragments.player.material.MaterialFragment
|
||||
import io.github.muntashirakon.music.fragments.player.normal.PlayerFragment
|
||||
import io.github.muntashirakon.music.fragments.player.peak.PeakPlayerFragment
|
||||
import io.github.muntashirakon.music.fragments.player.plain.PlainPlayerFragment
|
||||
import io.github.muntashirakon.music.fragments.player.simple.SimplePlayerFragment
|
||||
import io.github.muntashirakon.music.fragments.player.tiny.TinyPlayerFragment
|
||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
||||
import io.github.muntashirakon.music.model.CategoryInfo
|
||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||
import io.github.muntashirakon.music.views.BottomNavigationBarTinted
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior.*
|
||||
import kotlinx.android.synthetic.main.sliding_music_panel_layout.*
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
|
||||
|
@ -34,9 +67,10 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
}
|
||||
|
||||
protected val libraryViewModel by viewModel<LibraryViewModel>()
|
||||
private lateinit var behavior: RetroBottomSheetBehavior<FrameLayout>
|
||||
private lateinit var bottomSheetBehavior: RetroBottomSheetBehavior<FrameLayout>
|
||||
private var playerFragment: AbsPlayerFragment? = null
|
||||
private var miniPlayerFragment: MiniPlayerFragment? = null
|
||||
private var cps: NowPlayingScreen? = null
|
||||
private var nowPlayingScreen: NowPlayingScreen? = null
|
||||
private var navigationBarColor: Int = 0
|
||||
private var taskColor: Int = 0
|
||||
private var lightStatusBar: Boolean = false
|
||||
|
@ -44,88 +78,90 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
private var paletteColor: Int = Color.WHITE
|
||||
protected abstract fun createContentView(): View
|
||||
private val panelState: Int
|
||||
get() = behavior.state
|
||||
get() = bottomSheetBehavior.state
|
||||
|
||||
private val bottomSheetCallbackList = object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
private val bottomSheetCallbackList = object : BottomSheetCallback() {
|
||||
|
||||
override fun onSlide(bottomSheet: View, slideOffset: Float) {
|
||||
setMiniPlayerAlphaProgress(slideOffset)
|
||||
dimBackground.show()
|
||||
dimBackground.alpha = slideOffset
|
||||
}
|
||||
|
||||
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||
when (newState) {
|
||||
BottomSheetBehavior.STATE_EXPANDED -> {
|
||||
STATE_EXPANDED -> {
|
||||
onPanelExpanded()
|
||||
}
|
||||
BottomSheetBehavior.STATE_COLLAPSED -> {
|
||||
STATE_COLLAPSED -> {
|
||||
onPanelCollapsed()
|
||||
dimBackground.hide()
|
||||
}
|
||||
else -> {
|
||||
|
||||
println("Do something")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getBottomSheetBehavior() = bottomSheetBehavior
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(createContentView())
|
||||
chooseFragmentForTheme()
|
||||
setupSlidingUpPanel()
|
||||
|
||||
setupBottomSheet()
|
||||
updateColor()
|
||||
|
||||
libraryViewModel.paletteColorLiveData.observe(this, Observer {
|
||||
this.paletteColor = it
|
||||
onPaletteColorChanged()
|
||||
})
|
||||
val themeColor = ATHUtil.resolveColor(this, android.R.attr.windowBackground, Color.GRAY)
|
||||
dimBackground.setBackgroundColor(ColorUtil.withAlpha(themeColor, 0.5f))
|
||||
dimBackground.setOnClickListener {
|
||||
println("dimBackground")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun getBottomSheetBehavior() = behavior
|
||||
|
||||
private fun setupBottomSheet() {
|
||||
behavior = BottomSheetBehavior.from(slidingPanel) as RetroBottomSheetBehavior
|
||||
behavior.addBottomSheetCallback(bottomSheetCallbackList)
|
||||
|
||||
if (behavior.state == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
setMiniPlayerAlphaProgress(1f)
|
||||
}
|
||||
bottomSheetBehavior = from(slidingPanel) as RetroBottomSheetBehavior
|
||||
bottomSheetBehavior.addBottomSheetCallback(bottomSheetCallbackList)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (cps != PreferenceUtil.nowPlayingScreen) {
|
||||
if (nowPlayingScreen != PreferenceUtil.nowPlayingScreen) {
|
||||
postRecreate()
|
||||
}
|
||||
if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
setMiniPlayerAlphaProgress(1f)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
behavior.removeBottomSheetCallback(bottomSheetCallbackList)
|
||||
bottomSheetBehavior.removeBottomSheetCallback(bottomSheetCallbackList)
|
||||
}
|
||||
|
||||
protected fun wrapSlidingMusicPanel(@LayoutRes resId: Int): View {
|
||||
@SuppressLint("InflateParams")
|
||||
protected fun wrapSlidingMusicPanel(): View {
|
||||
val slidingMusicPanelLayout =
|
||||
layoutInflater.inflate(R.layout.sliding_music_panel_layout, null)
|
||||
val contentContainer: ViewGroup =
|
||||
slidingMusicPanelLayout.findViewById(R.id.mainContentFrame)
|
||||
layoutInflater.inflate(resId, contentContainer)
|
||||
layoutInflater.inflate(R.layout.activity_main_content, contentContainer)
|
||||
return slidingMusicPanelLayout
|
||||
}
|
||||
|
||||
fun collapsePanel() {
|
||||
behavior.state = BottomSheetBehavior.STATE_COLLAPSED
|
||||
setMiniPlayerAlphaProgress(0f)
|
||||
bottomSheetBehavior.state = STATE_COLLAPSED
|
||||
}
|
||||
|
||||
fun expandPanel() {
|
||||
behavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
bottomSheetBehavior.state = STATE_EXPANDED
|
||||
setMiniPlayerAlphaProgress(1f)
|
||||
}
|
||||
|
||||
private fun setMiniPlayerAlphaProgress(progress: Float) {
|
||||
if (miniPlayerFragment?.view == null) return
|
||||
val alpha = 1 - progress
|
||||
miniPlayerFragment?.view?.alpha = alpha
|
||||
miniPlayerFragment?.view?.visibility = if (alpha == 0f) View.GONE else View.VISIBLE
|
||||
|
@ -150,11 +186,16 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
ViewTreeObserver.OnGlobalLayoutListener {
|
||||
override fun onGlobalLayout() {
|
||||
slidingPanel.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||
if (nowPlayingScreen != Peak) {
|
||||
val params = slidingPanel.layoutParams as ViewGroup.LayoutParams
|
||||
params.height = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
slidingPanel.layoutParams = params
|
||||
}
|
||||
when (panelState) {
|
||||
BottomSheetBehavior.STATE_EXPANDED -> onPanelExpanded()
|
||||
BottomSheetBehavior.STATE_COLLAPSED -> onPanelCollapsed()
|
||||
STATE_EXPANDED -> onPanelExpanded()
|
||||
STATE_COLLAPSED -> onPanelCollapsed()
|
||||
else -> {
|
||||
//playerFragment!!.onHide()
|
||||
// playerFragment!!.onHide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -165,35 +206,6 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
return bottomNavigationView
|
||||
}
|
||||
|
||||
fun hideBottomBarVisibility(visible: Boolean) {
|
||||
bottomNavigationView.isVisible = visible
|
||||
hideBottomBar(MusicPlayerRemote.playingQueue.isEmpty())
|
||||
}
|
||||
|
||||
private fun hideBottomBar(hide: Boolean) {
|
||||
val heightOfBar = bottomNavigationView.height
|
||||
val isBottomBarVisible = bottomNavigationView.isVisible
|
||||
|
||||
if (hide) {
|
||||
behavior.isHideable = true
|
||||
behavior.peekHeight = 0
|
||||
collapsePanel()
|
||||
ViewCompat.setElevation(slidingPanel, 0f)
|
||||
ViewCompat.setElevation(bottomNavigationView, 10f)
|
||||
} else {
|
||||
ViewCompat.setElevation(bottomNavigationView, 10f)
|
||||
ViewCompat.setElevation(slidingPanel, 10f)
|
||||
behavior.isHideable = false
|
||||
behavior.peekHeight = (if (isBottomBarVisible) heightOfBar * 2 else heightOfBar) - 24
|
||||
}
|
||||
}
|
||||
|
||||
private fun chooseFragmentForTheme() {
|
||||
cps = PreferenceUtil.nowPlayingScreen
|
||||
miniPlayerFragment = whichFragment<MiniPlayerFragment>(R.id.miniPlayerFragment)
|
||||
miniPlayerFragment?.view?.setOnClickListener { expandPanel() }
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {
|
||||
super.onServiceConnected()
|
||||
if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
|
||||
|
@ -216,36 +228,38 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
if (!handleBackPress()) super.onBackPressed()
|
||||
}
|
||||
|
||||
open fun handleBackPress(): Boolean {
|
||||
if (panelState == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
private fun handleBackPress(): Boolean {
|
||||
if (bottomSheetBehavior.peekHeight != 0 && playerFragment!!.onBackPressed()) return true
|
||||
if (panelState == STATE_EXPANDED) {
|
||||
collapsePanel()
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun onPaletteColorChanged() {
|
||||
if (panelState == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
if (panelState == STATE_EXPANDED) {
|
||||
super.setTaskDescriptionColor(paletteColor)
|
||||
val isColorLight = ColorUtil.isColorLight(paletteColor)
|
||||
if (PreferenceUtil.isAdaptiveColor && (cps == Normal || cps == Flat)) {
|
||||
if (PreferenceUtil.isAdaptiveColor && (nowPlayingScreen == Normal || nowPlayingScreen == Flat)) {
|
||||
super.setLightNavigationBar(true)
|
||||
super.setLightStatusbar(isColorLight)
|
||||
} else if (cps == Card || cps == Blur || cps == BlurCard) {
|
||||
} else if (nowPlayingScreen == Card || nowPlayingScreen == Blur || nowPlayingScreen == BlurCard) {
|
||||
super.setLightStatusbar(false)
|
||||
super.setLightNavigationBar(true)
|
||||
super.setNavigationbarColor(Color.BLACK)
|
||||
} else if (cps == Color || cps == Tiny || cps == Gradient) {
|
||||
} else if (nowPlayingScreen == Color || nowPlayingScreen == Tiny || nowPlayingScreen == Gradient) {
|
||||
super.setNavigationbarColor(paletteColor)
|
||||
super.setLightNavigationBar(isColorLight)
|
||||
super.setLightStatusbar(isColorLight)
|
||||
} else if (cps == Full) {
|
||||
} else if (nowPlayingScreen == Full) {
|
||||
super.setNavigationbarColor(paletteColor)
|
||||
super.setLightNavigationBar(isColorLight)
|
||||
super.setLightStatusbar(false)
|
||||
} else if (cps == Classic) {
|
||||
} else if (nowPlayingScreen == Classic) {
|
||||
super.setLightStatusbar(false)
|
||||
} else if (cps == Fit) {
|
||||
} else if (nowPlayingScreen == Fit) {
|
||||
super.setLightStatusbar(false)
|
||||
} else {
|
||||
super.setLightStatusbar(
|
||||
|
@ -263,38 +277,32 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
|
||||
override fun setLightStatusbar(enabled: Boolean) {
|
||||
lightStatusBar = enabled
|
||||
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||
if (panelState == STATE_COLLAPSED) {
|
||||
super.setLightStatusbar(enabled)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setLightNavigationBar(enabled: Boolean) {
|
||||
lightNavigationBar = enabled
|
||||
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||
if (panelState == STATE_COLLAPSED) {
|
||||
super.setLightNavigationBar(enabled)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setNavigationbarColor(color: Int) {
|
||||
navigationBarColor = color
|
||||
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||
if (panelState == STATE_COLLAPSED) {
|
||||
super.setNavigationbarColor(color)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setTaskDescriptionColor(color: Int) {
|
||||
taskColor = color
|
||||
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||
if (panelState == STATE_COLLAPSED) {
|
||||
super.setTaskDescriptionColor(color)
|
||||
}
|
||||
}
|
||||
|
||||
fun hideBottomNavigation() {
|
||||
behavior.isHideable = true
|
||||
behavior.peekHeight = 0
|
||||
hideBottomBarVisibility(false)
|
||||
}
|
||||
|
||||
fun updateTabs() {
|
||||
bottomNavigationView.menu.clear()
|
||||
val currentTabs: List<CategoryInfo> = PreferenceUtil.libraryCategory
|
||||
|
@ -308,4 +316,74 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
bottomNavigationView.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateColor() {
|
||||
libraryViewModel.paletteColor.observe(this, { color ->
|
||||
this.paletteColor = color
|
||||
onPaletteColorChanged()
|
||||
})
|
||||
}
|
||||
|
||||
fun setBottomBarVisibility(visible: Int) {
|
||||
bottomNavigationView.visibility = visible
|
||||
hideBottomBar(MusicPlayerRemote.playingQueue.isEmpty())
|
||||
}
|
||||
|
||||
private fun hideBottomBar(hide: Boolean) {
|
||||
val heightOfBar = dip(R.dimen.mini_player_height)
|
||||
val heightOfBarWithTabs = dip(R.dimen.mini_player_height_expanded)
|
||||
val isVisible = bottomNavigationView.isVisible
|
||||
if (hide) {
|
||||
bottomSheetBehavior.isHideable = true
|
||||
bottomSheetBehavior.peekHeight = 0
|
||||
ViewCompat.setElevation(slidingPanel, 0f)
|
||||
ViewCompat.setElevation(bottomNavigationView, 10f)
|
||||
collapsePanel()
|
||||
} else {
|
||||
if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
|
||||
bottomSheetBehavior.isHideable = false
|
||||
ViewCompat.setElevation(slidingPanel, 10f)
|
||||
ViewCompat.setElevation(bottomNavigationView, 10f)
|
||||
if (isVisible) {
|
||||
bottomSheetBehavior.peekHeight = heightOfBarWithTabs
|
||||
bottomNavigationView.translateYAnimate(0f)
|
||||
} else {
|
||||
bottomNavigationView.translateYAnimate(150f)
|
||||
bottomSheetBehavior.peekHeight = heightOfBar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun chooseFragmentForTheme() {
|
||||
nowPlayingScreen = PreferenceUtil.nowPlayingScreen
|
||||
|
||||
val fragment: Fragment = 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()
|
||||
Peak -> PeakPlayerFragment()
|
||||
Circle -> CirclePlayerFragment()
|
||||
Classic -> ClassicPlayerFragment()
|
||||
else -> PlayerFragment()
|
||||
} // must implement AbsPlayerFragment
|
||||
supportFragmentManager.commit {
|
||||
replace(R.id.playerFragmentContainer, fragment)
|
||||
}
|
||||
supportFragmentManager.executePendingTransactions()
|
||||
playerFragment = whichFragment<AbsPlayerFragment>(R.id.playerFragmentContainer)
|
||||
miniPlayerFragment = whichFragment<MiniPlayerFragment>(R.id.miniPlayerFragment)
|
||||
miniPlayerFragment?.view?.setOnClickListener { expandPanel() }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities.base
|
||||
|
||||
import android.content.Context
|
||||
|
@ -37,7 +51,6 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
|
|||
MaterialDialogsUtil.updateMaterialDialogsThemeSingleton(this)
|
||||
}
|
||||
|
||||
|
||||
private fun updateTheme() {
|
||||
setTheme(ThemeManager.getThemeResValue(this))
|
||||
setDefaultNightMode(ThemeManager.getNightMode(this))
|
||||
|
@ -204,4 +217,4 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
|
|||
super.attachBaseContext(LanguageContextWrapper.wrap(newBase, Locale(code)))
|
||||
} else super.attachBaseContext(newBase)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities.bugreport
|
||||
|
||||
import android.app.Activity
|
||||
|
@ -31,6 +45,7 @@ import io.github.muntashirakon.music.misc.DialogAsyncTask
|
|||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import java.io.IOException
|
||||
import kotlinx.android.synthetic.main.activity_bug_report.*
|
||||
import kotlinx.android.synthetic.main.bug_report_card_device_info.*
|
||||
import kotlinx.android.synthetic.main.bug_report_card_report.*
|
||||
|
@ -38,7 +53,6 @@ import org.eclipse.egit.github.core.Issue
|
|||
import org.eclipse.egit.github.core.client.GitHubClient
|
||||
import org.eclipse.egit.github.core.client.RequestException
|
||||
import org.eclipse.egit.github.core.service.IssueService
|
||||
import java.io.IOException
|
||||
|
||||
private const val RESULT_SUCCESS = "RESULT_OK"
|
||||
private const val RESULT_BAD_CREDENTIALS = "RESULT_BAD_CREDENTIALS"
|
||||
|
@ -306,7 +320,6 @@ open class BugReportActivity : AbsThemeActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
|
||||
fun report(
|
||||
|
|
|
@ -5,129 +5,197 @@ import android.content.Context;
|
|||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
import io.github.muntashirakon.music.util.PreferenceUtil;
|
||||
|
||||
public class DeviceInfo {
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@SuppressWarnings("deprecation")
|
||||
private final String[] abis = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ?
|
||||
Build.SUPPORTED_ABIS : new String[]{Build.CPU_ABI, Build.CPU_ABI2};
|
||||
@SuppressLint("NewApi")
|
||||
@SuppressWarnings("deprecation")
|
||||
private final String[] abis =
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
|
||||
? Build.SUPPORTED_ABIS
|
||||
: new String[] {Build.CPU_ABI, Build.CPU_ABI2};
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private final String[] abis32Bits = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ?
|
||||
Build.SUPPORTED_32_BIT_ABIS : null;
|
||||
@SuppressLint("NewApi")
|
||||
private final String[] abis32Bits =
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? Build.SUPPORTED_32_BIT_ABIS : null;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private final String[] abis64Bits = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ?
|
||||
Build.SUPPORTED_64_BIT_ABIS : null;
|
||||
@SuppressLint("NewApi")
|
||||
private final String[] abis64Bits =
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? Build.SUPPORTED_64_BIT_ABIS : null;
|
||||
|
||||
private final String baseTheme;
|
||||
private final String baseTheme;
|
||||
|
||||
private final String brand = Build.BRAND;
|
||||
private final String brand = Build.BRAND;
|
||||
|
||||
private final String buildID = Build.DISPLAY;
|
||||
private final String buildID = Build.DISPLAY;
|
||||
|
||||
private final String buildVersion = Build.VERSION.INCREMENTAL;
|
||||
private final String buildVersion = Build.VERSION.INCREMENTAL;
|
||||
|
||||
private final String device = Build.DEVICE;
|
||||
private final String device = Build.DEVICE;
|
||||
|
||||
private final String hardware = Build.HARDWARE;
|
||||
private final String hardware = Build.HARDWARE;
|
||||
|
||||
private final boolean isAdaptive;
|
||||
private final boolean isAdaptive;
|
||||
|
||||
private final String manufacturer = Build.MANUFACTURER;
|
||||
private final String manufacturer = Build.MANUFACTURER;
|
||||
|
||||
private final String model = Build.MODEL;
|
||||
private final String model = Build.MODEL;
|
||||
|
||||
private final String nowPlayingTheme;
|
||||
private final String nowPlayingTheme;
|
||||
|
||||
private final String product = Build.PRODUCT;
|
||||
private final String product = Build.PRODUCT;
|
||||
|
||||
private final String releaseVersion = Build.VERSION.RELEASE;
|
||||
private final String releaseVersion = Build.VERSION.RELEASE;
|
||||
|
||||
@IntRange(from = 0)
|
||||
private final int sdkVersion = Build.VERSION.SDK_INT;
|
||||
@IntRange(from = 0)
|
||||
private final int sdkVersion = Build.VERSION.SDK_INT;
|
||||
|
||||
private final int versionCode;
|
||||
private final int versionCode;
|
||||
|
||||
private final String versionName;
|
||||
private final String selectedLang;
|
||||
private final String versionName;
|
||||
private final String selectedLang;
|
||||
|
||||
public DeviceInfo(Context context) {
|
||||
PackageInfo packageInfo;
|
||||
try {
|
||||
packageInfo = context.getPackageManager()
|
||||
.getPackageInfo(context.getPackageName(), 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
packageInfo = null;
|
||||
}
|
||||
if (packageInfo != null) {
|
||||
versionCode = packageInfo.versionCode;
|
||||
versionName = packageInfo.versionName;
|
||||
} else {
|
||||
versionCode = -1;
|
||||
versionName = null;
|
||||
}
|
||||
baseTheme = PreferenceUtil.INSTANCE.getBaseTheme();
|
||||
nowPlayingTheme = context.getString(PreferenceUtil.INSTANCE.getNowPlayingScreen().getTitleRes());
|
||||
isAdaptive = PreferenceUtil.INSTANCE.isAdaptiveColor();
|
||||
selectedLang = PreferenceUtil.INSTANCE.getLanguageCode();
|
||||
public DeviceInfo(Context context) {
|
||||
PackageInfo packageInfo;
|
||||
try {
|
||||
packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
packageInfo = null;
|
||||
}
|
||||
|
||||
public String toMarkdown() {
|
||||
return "Device info:\n"
|
||||
+ "---\n"
|
||||
+ "<table>\n"
|
||||
+ "<tr><td><b>App version</b></td><td>" + versionName + "</td></tr>\n"
|
||||
+ "<tr><td>App version code</td><td>" + versionCode + "</td></tr>\n"
|
||||
+ "<tr><td>Android build version</td><td>" + buildVersion + "</td></tr>\n"
|
||||
+ "<tr><td>Android release version</td><td>" + releaseVersion + "</td></tr>\n"
|
||||
+ "<tr><td>Android SDK version</td><td>" + sdkVersion + "</td></tr>\n"
|
||||
+ "<tr><td>Android build ID</td><td>" + buildID + "</td></tr>\n"
|
||||
+ "<tr><td>Device brand</td><td>" + brand + "</td></tr>\n"
|
||||
+ "<tr><td>Device manufacturer</td><td>" + manufacturer + "</td></tr>\n"
|
||||
+ "<tr><td>Device name</td><td>" + device + "</td></tr>\n"
|
||||
+ "<tr><td>Device model</td><td>" + model + "</td></tr>\n"
|
||||
+ "<tr><td>Device product name</td><td>" + product + "</td></tr>\n"
|
||||
+ "<tr><td>Device hardware name</td><td>" + hardware + "</td></tr>\n"
|
||||
+ "<tr><td>ABIs</td><td>" + Arrays.toString(abis) + "</td></tr>\n"
|
||||
+ "<tr><td>ABIs (32bit)</td><td>" + Arrays.toString(abis32Bits) + "</td></tr>\n"
|
||||
+ "<tr><td>ABIs (64bit)</td><td>" + Arrays.toString(abis64Bits) + "</td></tr>\n"
|
||||
+ "<tr><td>Language</td><td>" + selectedLang + "</td></tr>\n"
|
||||
+ "</table>\n";
|
||||
if (packageInfo != null) {
|
||||
versionCode = packageInfo.versionCode;
|
||||
versionName = packageInfo.versionName;
|
||||
} else {
|
||||
versionCode = -1;
|
||||
versionName = null;
|
||||
}
|
||||
baseTheme = PreferenceUtil.INSTANCE.getBaseTheme();
|
||||
nowPlayingTheme =
|
||||
context.getString(PreferenceUtil.INSTANCE.getNowPlayingScreen().getTitleRes());
|
||||
isAdaptive = PreferenceUtil.INSTANCE.isAdaptiveColor();
|
||||
selectedLang = PreferenceUtil.INSTANCE.getLanguageCode();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String toMarkdown() {
|
||||
return "Device info:\n"
|
||||
+ "---\n"
|
||||
+ "<table>\n"
|
||||
+ "<tr><td><b>App version</b></td><td>"
|
||||
+ versionName
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>App version code</td><td>"
|
||||
+ versionCode
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>Android build version</td><td>"
|
||||
+ buildVersion
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>Android release version</td><td>"
|
||||
+ releaseVersion
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>Android SDK version</td><td>"
|
||||
+ sdkVersion
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>Android build ID</td><td>"
|
||||
+ buildID
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>Device brand</td><td>"
|
||||
+ brand
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>Device manufacturer</td><td>"
|
||||
+ manufacturer
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>Device name</td><td>"
|
||||
+ device
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>Device model</td><td>"
|
||||
+ model
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>Device product name</td><td>"
|
||||
+ product
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>Device hardware name</td><td>"
|
||||
+ hardware
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>ABIs</td><td>"
|
||||
+ Arrays.toString(abis)
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>ABIs (32bit)</td><td>"
|
||||
+ Arrays.toString(abis32Bits)
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>ABIs (64bit)</td><td>"
|
||||
+ Arrays.toString(abis64Bits)
|
||||
+ "</td></tr>\n"
|
||||
+ "<tr><td>Language</td><td>"
|
||||
+ selectedLang
|
||||
+ "</td></tr>\n"
|
||||
+ "</table>\n";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "App version: " + versionName + "\n"
|
||||
+ "App version code: " + versionCode + "\n"
|
||||
+ "Android build version: " + buildVersion + "\n"
|
||||
+ "Android release version: " + releaseVersion + "\n"
|
||||
+ "Android SDK version: " + sdkVersion + "\n"
|
||||
+ "Android build ID: " + buildID + "\n"
|
||||
+ "Device brand: " + brand + "\n"
|
||||
+ "Device manufacturer: " + manufacturer + "\n"
|
||||
+ "Device name: " + device + "\n"
|
||||
+ "Device model: " + model + "\n"
|
||||
+ "Device product name: " + product + "\n"
|
||||
+ "Device hardware name: " + hardware + "\n"
|
||||
+ "ABIs: " + Arrays.toString(abis) + "\n"
|
||||
+ "ABIs (32bit): " + Arrays.toString(abis32Bits) + "\n"
|
||||
+ "ABIs (64bit): " + Arrays.toString(abis64Bits) + "\n"
|
||||
+ "Base theme: " + baseTheme + "\n"
|
||||
+ "Now playing theme: " + nowPlayingTheme + "\n"
|
||||
+ "Adaptive: " + isAdaptive + "\n"
|
||||
+ "System language: " + Locale.getDefault().toLanguageTag() + "\n"
|
||||
+ "In-App Language: " + selectedLang;
|
||||
}
|
||||
public String toString() {
|
||||
return "App version: "
|
||||
+ versionName
|
||||
+ "\n"
|
||||
+ "App version code: "
|
||||
+ versionCode
|
||||
+ "\n"
|
||||
+ "Android build version: "
|
||||
+ buildVersion
|
||||
+ "\n"
|
||||
+ "Android release version: "
|
||||
+ releaseVersion
|
||||
+ "\n"
|
||||
+ "Android SDK version: "
|
||||
+ sdkVersion
|
||||
+ "\n"
|
||||
+ "Android build ID: "
|
||||
+ buildID
|
||||
+ "\n"
|
||||
+ "Device brand: "
|
||||
+ brand
|
||||
+ "\n"
|
||||
+ "Device manufacturer: "
|
||||
+ manufacturer
|
||||
+ "\n"
|
||||
+ "Device name: "
|
||||
+ device
|
||||
+ "\n"
|
||||
+ "Device model: "
|
||||
+ model
|
||||
+ "\n"
|
||||
+ "Device product name: "
|
||||
+ product
|
||||
+ "\n"
|
||||
+ "Device hardware name: "
|
||||
+ hardware
|
||||
+ "\n"
|
||||
+ "ABIs: "
|
||||
+ Arrays.toString(abis)
|
||||
+ "\n"
|
||||
+ "ABIs (32bit): "
|
||||
+ Arrays.toString(abis32Bits)
|
||||
+ "\n"
|
||||
+ "ABIs (64bit): "
|
||||
+ Arrays.toString(abis64Bits)
|
||||
+ "\n"
|
||||
+ "Base theme: "
|
||||
+ baseTheme
|
||||
+ "\n"
|
||||
+ "Now playing theme: "
|
||||
+ nowPlayingTheme
|
||||
+ "\n"
|
||||
+ "Adaptive: "
|
||||
+ isAdaptive
|
||||
+ "\n"
|
||||
+ "System language: "
|
||||
+ Locale.getDefault().toLanguageTag()
|
||||
+ "\n"
|
||||
+ "In-App Language: "
|
||||
+ selectedLang;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +1,34 @@
|
|||
package io.github.muntashirakon.music.activities.bugreport.model;
|
||||
|
||||
|
||||
import io.github.muntashirakon.music.activities.bugreport.model.github.ExtraInfo;
|
||||
|
||||
public class Report {
|
||||
|
||||
private final String description;
|
||||
private final String description;
|
||||
|
||||
private final DeviceInfo deviceInfo;
|
||||
private final DeviceInfo deviceInfo;
|
||||
|
||||
private final ExtraInfo extraInfo;
|
||||
private final ExtraInfo extraInfo;
|
||||
|
||||
private final String title;
|
||||
private final String title;
|
||||
|
||||
public Report(String title, String description, DeviceInfo deviceInfo, ExtraInfo extraInfo) {
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.deviceInfo = deviceInfo;
|
||||
this.extraInfo = extraInfo;
|
||||
}
|
||||
public Report(String title, String description, DeviceInfo deviceInfo, ExtraInfo extraInfo) {
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.deviceInfo = deviceInfo;
|
||||
this.extraInfo = extraInfo;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description + "\n\n"
|
||||
+ "-\n\n"
|
||||
+ deviceInfo.toMarkdown() + "\n\n"
|
||||
+ extraInfo.toMarkdown();
|
||||
}
|
||||
public String getDescription() {
|
||||
return description
|
||||
+ "\n\n"
|
||||
+ "-\n\n"
|
||||
+ deviceInfo.toMarkdown()
|
||||
+ "\n\n"
|
||||
+ extraInfo.toMarkdown();
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,58 +5,57 @@ import java.util.Map;
|
|||
|
||||
public class ExtraInfo {
|
||||
|
||||
private final Map<String, String> extraInfo = new LinkedHashMap<>();
|
||||
private final Map<String, String> extraInfo = new LinkedHashMap<>();
|
||||
|
||||
public void put(String key, String value) {
|
||||
extraInfo.put(key, value);
|
||||
public void put(String key, String value) {
|
||||
extraInfo.put(key, value);
|
||||
}
|
||||
|
||||
public void put(String key, boolean value) {
|
||||
extraInfo.put(key, Boolean.toString(value));
|
||||
}
|
||||
|
||||
public void put(String key, double value) {
|
||||
extraInfo.put(key, Double.toString(value));
|
||||
}
|
||||
|
||||
public void put(String key, float value) {
|
||||
extraInfo.put(key, Float.toString(value));
|
||||
}
|
||||
|
||||
public void put(String key, long value) {
|
||||
extraInfo.put(key, Long.toString(value));
|
||||
}
|
||||
|
||||
public void put(String key, int value) {
|
||||
extraInfo.put(key, Integer.toString(value));
|
||||
}
|
||||
|
||||
public void put(String key, Object value) {
|
||||
extraInfo.put(key, String.valueOf(value));
|
||||
}
|
||||
|
||||
public void remove(String key) {
|
||||
extraInfo.remove(key);
|
||||
}
|
||||
|
||||
public String toMarkdown() {
|
||||
if (extraInfo.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
public void put(String key, boolean value) {
|
||||
extraInfo.put(key, Boolean.toString(value));
|
||||
StringBuilder output = new StringBuilder();
|
||||
output.append("Extra info:\n" + "---\n" + "<table>\n");
|
||||
for (String key : extraInfo.keySet()) {
|
||||
output
|
||||
.append("<tr><td>")
|
||||
.append(key)
|
||||
.append("</td><td>")
|
||||
.append(extraInfo.get(key))
|
||||
.append("</td></tr>\n");
|
||||
}
|
||||
output.append("</table>\n");
|
||||
|
||||
public void put(String key, double value) {
|
||||
extraInfo.put(key, Double.toString(value));
|
||||
}
|
||||
|
||||
public void put(String key, float value) {
|
||||
extraInfo.put(key, Float.toString(value));
|
||||
}
|
||||
|
||||
public void put(String key, long value) {
|
||||
extraInfo.put(key, Long.toString(value));
|
||||
}
|
||||
|
||||
public void put(String key, int value) {
|
||||
extraInfo.put(key, Integer.toString(value));
|
||||
}
|
||||
|
||||
public void put(String key, Object value) {
|
||||
extraInfo.put(key, String.valueOf(value));
|
||||
}
|
||||
|
||||
public void remove(String key) {
|
||||
extraInfo.remove(key);
|
||||
}
|
||||
|
||||
public String toMarkdown() {
|
||||
if (extraInfo.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuilder output = new StringBuilder();
|
||||
output.append("Extra info:\n"
|
||||
+ "---\n"
|
||||
+ "<table>\n");
|
||||
for (String key : extraInfo.keySet()) {
|
||||
output.append("<tr><td>")
|
||||
.append(key)
|
||||
.append("</td><td>")
|
||||
.append(extraInfo.get(key))
|
||||
.append("</td></tr>\n");
|
||||
}
|
||||
output.append("</table>\n");
|
||||
|
||||
return output.toString();
|
||||
}
|
||||
return output.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,38 +4,37 @@ import android.text.TextUtils;
|
|||
|
||||
public class GithubLogin {
|
||||
|
||||
private final String apiToken;
|
||||
private final String apiToken;
|
||||
|
||||
private final String password;
|
||||
private final String password;
|
||||
|
||||
private final String username;
|
||||
private final String username;
|
||||
|
||||
public GithubLogin(String username, String password) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.apiToken = null;
|
||||
}
|
||||
public GithubLogin(String username, String password) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.apiToken = null;
|
||||
}
|
||||
|
||||
public GithubLogin(String apiToken) {
|
||||
this.username = null;
|
||||
this.password = null;
|
||||
this.apiToken = apiToken;
|
||||
}
|
||||
public GithubLogin(String apiToken) {
|
||||
this.username = null;
|
||||
this.password = null;
|
||||
this.apiToken = apiToken;
|
||||
}
|
||||
|
||||
public String getApiToken() {
|
||||
return apiToken;
|
||||
}
|
||||
public String getApiToken() {
|
||||
return apiToken;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public boolean shouldUseApiToken() {
|
||||
return TextUtils.isEmpty(username) || TextUtils.isEmpty(password);
|
||||
}
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public boolean shouldUseApiToken() {
|
||||
return TextUtils.isEmpty(username) || TextUtils.isEmpty(password);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,20 +2,20 @@ package io.github.muntashirakon.music.activities.bugreport.model.github;
|
|||
|
||||
public class GithubTarget {
|
||||
|
||||
private final String repository;
|
||||
private final String repository;
|
||||
|
||||
private final String username;
|
||||
private final String username;
|
||||
|
||||
public GithubTarget(String username, String repository) {
|
||||
this.username = username;
|
||||
this.repository = repository;
|
||||
}
|
||||
public GithubTarget(String username, String repository) {
|
||||
this.username = username;
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public String getRepository() {
|
||||
return repository;
|
||||
}
|
||||
public String getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,57 +16,58 @@ package io.github.muntashirakon.music.activities.saf;
|
|||
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import io.github.muntashirakon.music.R;
|
||||
import com.heinrichreimersoftware.materialintro.app.IntroActivity;
|
||||
import com.heinrichreimersoftware.materialintro.slide.SimpleSlide;
|
||||
|
||||
import io.github.muntashirakon.music.R;
|
||||
|
||||
/**
|
||||
* Created by hemanths on 2019-07-31.
|
||||
*/
|
||||
/** Created by hemanths on 2019-07-31. */
|
||||
public class SAFGuideActivity extends IntroActivity {
|
||||
|
||||
public static final int REQUEST_CODE_SAF_GUIDE = 98;
|
||||
public static final int REQUEST_CODE_SAF_GUIDE = 98;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setButtonCtaVisible(false);
|
||||
setButtonNextVisible(false);
|
||||
setButtonBackVisible(false);
|
||||
setButtonCtaVisible(false);
|
||||
setButtonNextVisible(false);
|
||||
setButtonBackVisible(false);
|
||||
|
||||
setButtonCtaTintMode(BUTTON_CTA_TINT_MODE_TEXT);
|
||||
setButtonCtaTintMode(BUTTON_CTA_TINT_MODE_TEXT);
|
||||
|
||||
String title = String.format(getString(R.string.saf_guide_slide1_title), getString(R.string.app_name));
|
||||
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(R.color.md_deep_purple_300)
|
||||
.backgroundDark(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(R.color.md_deep_purple_500)
|
||||
.backgroundDark(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(R.color.md_deep_purple_700)
|
||||
.backgroundDark(R.color.md_deep_purple_800)
|
||||
.layout(R.layout.fragment_simple_slide_large_image)
|
||||
.build());
|
||||
}
|
||||
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(R.color.md_deep_purple_300)
|
||||
.backgroundDark(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(R.color.md_deep_purple_500)
|
||||
.backgroundDark(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(R.color.md_deep_purple_700)
|
||||
.backgroundDark(R.color.md_deep_purple_800)
|
||||
.layout(R.layout.fragment_simple_slide_large_image)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,25 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities.tageditor
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.SearchManager
|
||||
import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.MenuItem
|
||||
|
@ -16,18 +28,19 @@ import android.view.animation.OvershootInterpolator
|
|||
import androidx.appcompat.app.AlertDialog
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.R.drawable
|
||||
import io.github.muntashirakon.music.activities.base.AbsBaseActivity
|
||||
import io.github.muntashirakon.music.activities.saf.SAFGuideActivity
|
||||
import io.github.muntashirakon.music.extensions.accentColor
|
||||
import io.github.muntashirakon.music.model.ArtworkInfo
|
||||
import io.github.muntashirakon.music.model.LoadingInfo
|
||||
import io.github.muntashirakon.music.repository.Repository
|
||||
import io.github.muntashirakon.music.util.RetroUtil
|
||||
import io.github.muntashirakon.music.util.SAFUtil
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.android.synthetic.main.activity_album_tag_editor.*
|
||||
import org.jaudiotagger.audio.AudioFile
|
||||
import org.jaudiotagger.audio.AudioFileIO
|
||||
|
@ -49,6 +62,8 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
|||
private val currentSongPath: String? = null
|
||||
private var savedTags: Map<FieldKey, String>? = null
|
||||
private var savedArtworkInfo: ArtworkInfo? = null
|
||||
protected abstract val contentViewLayout: Int
|
||||
protected abstract fun loadImageFromFile(selectedFile: Uri?)
|
||||
|
||||
protected val show: AlertDialog
|
||||
get() =
|
||||
|
@ -62,7 +77,6 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
|||
}
|
||||
}
|
||||
.show()
|
||||
protected abstract val contentViewLayout: Int
|
||||
|
||||
internal val albumArtist: String?
|
||||
get() {
|
||||
|
@ -182,6 +196,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
|||
getIntentExtras()
|
||||
|
||||
songPaths = getSongPaths()
|
||||
println(songPaths?.size)
|
||||
if (songPaths!!.isEmpty()) {
|
||||
finish()
|
||||
}
|
||||
|
@ -198,9 +213,9 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
|||
private fun setUpImageView() {
|
||||
loadCurrentImage()
|
||||
items = listOf(
|
||||
getString(io.github.muntashirakon.music.R.string.pick_from_local_storage),
|
||||
getString(io.github.muntashirakon.music.R.string.web_search),
|
||||
getString(io.github.muntashirakon.music.R.string.remove_cover)
|
||||
getString(R.string.pick_from_local_storage),
|
||||
getString(R.string.web_search),
|
||||
getString(R.string.remove_cover)
|
||||
)
|
||||
editorImage?.setOnClickListener { show }
|
||||
}
|
||||
|
@ -211,7 +226,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
|||
startActivityForResult(
|
||||
Intent.createChooser(
|
||||
intent,
|
||||
getString(io.github.muntashirakon.music.R.string.pick_from_local_storage)
|
||||
getString(R.string.pick_from_local_storage)
|
||||
), REQUEST_CODE_SELECT_IMAGE
|
||||
)
|
||||
}
|
||||
|
@ -223,20 +238,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
|||
protected abstract fun deleteImage()
|
||||
|
||||
private fun setUpFab() {
|
||||
saveFab.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
|
||||
ColorStateList.valueOf(
|
||||
MaterialValueHelper.getPrimaryTextColor(
|
||||
this,
|
||||
ColorUtil.isColorLight(
|
||||
ThemeStore.accentColor(
|
||||
this
|
||||
)
|
||||
)
|
||||
)
|
||||
).apply {
|
||||
saveFab.setTextColor(this)
|
||||
saveFab.iconTint = this
|
||||
}
|
||||
saveFab.accentColor()
|
||||
saveFab.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
|
@ -324,35 +326,25 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
|||
}
|
||||
|
||||
protected fun writeValuesToFiles(
|
||||
fieldKeyValueMap: Map<FieldKey, String>, artworkInfo: ArtworkInfo?
|
||||
fieldKeyValueMap: Map<FieldKey, String>,
|
||||
artworkInfo: ArtworkInfo?
|
||||
) {
|
||||
RetroUtil.hideSoftKeyboard(this)
|
||||
|
||||
hideFab()
|
||||
|
||||
savedSongPaths = songPaths
|
||||
savedTags = fieldKeyValueMap
|
||||
savedArtworkInfo = artworkInfo
|
||||
|
||||
if (!SAFUtil.isSAFRequired(savedSongPaths)) {
|
||||
writeTags(savedSongPaths)
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (SAFUtil.isSDCardAccessGranted(this)) {
|
||||
writeTags(savedSongPaths)
|
||||
} else {
|
||||
startActivityForResult(
|
||||
Intent(this, SAFGuideActivity::class.java),
|
||||
SAFGuideActivity.REQUEST_CODE_SAF_GUIDE
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
println(fieldKeyValueMap)
|
||||
WriteTagsAsyncTask(this).execute(
|
||||
LoadingInfo(
|
||||
songPaths,
|
||||
fieldKeyValueMap,
|
||||
artworkInfo
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun writeTags(paths: List<String>?) {
|
||||
WriteTagsAsyncTask(this).execute(
|
||||
WriteTagsAsyncTask.LoadingInfo(
|
||||
LoadingInfo(
|
||||
paths,
|
||||
savedTags,
|
||||
savedArtworkInfo
|
||||
|
@ -360,6 +352,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, intent)
|
||||
when (requestCode) {
|
||||
|
@ -385,7 +378,6 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract fun loadImageFromFile(selectedFile: Uri?)
|
||||
|
||||
private fun getAudioFile(path: String): AudioFile {
|
||||
return try {
|
||||
|
@ -396,7 +388,6 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
class ArtworkInfo constructor(val albumId: Long, val artwork: Bitmap?)
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -405,5 +396,4 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
|||
private val TAG = AbsTagEditorActivity::class.java.simpleName
|
||||
private const val REQUEST_CODE_SELECT_IMAGE = 1000
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities.tageditor
|
||||
|
||||
import android.app.Activity
|
||||
|
@ -18,6 +32,7 @@ import io.github.muntashirakon.music.R
|
|||
import io.github.muntashirakon.music.extensions.appHandleColor
|
||||
import io.github.muntashirakon.music.glide.palette.BitmapPaletteTranscoder
|
||||
import io.github.muntashirakon.music.glide.palette.BitmapPaletteWrapper
|
||||
import io.github.muntashirakon.music.model.ArtworkInfo
|
||||
import io.github.muntashirakon.music.model.Song
|
||||
import io.github.muntashirakon.music.util.ImageUtil
|
||||
import io.github.muntashirakon.music.util.RetroColorUtil.generatePalette
|
||||
|
@ -26,9 +41,9 @@ import com.bumptech.glide.Glide
|
|||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.request.animation.GlideAnimation
|
||||
import com.bumptech.glide.request.target.SimpleTarget
|
||||
import java.util.*
|
||||
import kotlinx.android.synthetic.main.activity_album_tag_editor.*
|
||||
import org.jaudiotagger.tag.FieldKey
|
||||
import java.util.*
|
||||
|
||||
class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||
|
||||
|
@ -155,7 +170,7 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
|||
override fun save() {
|
||||
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
||||
fieldKeyValueMap[FieldKey.ALBUM] = albumText.text.toString()
|
||||
//android seems not to recognize album_artist field so we additionally write the normal artist field
|
||||
// android seems not to recognize album_artist field so we additionally write the normal artist field
|
||||
fieldKeyValueMap[FieldKey.ARTIST] = albumArtistText.text.toString()
|
||||
fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = albumArtistText.text.toString()
|
||||
fieldKeyValueMap[FieldKey.GENRE] = genreTitle.text.toString()
|
||||
|
@ -163,8 +178,11 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
|||
|
||||
writeValuesToFiles(
|
||||
fieldKeyValueMap,
|
||||
if (deleteAlbumArt) ArtworkInfo(id, null)
|
||||
else if (albumArtBitmap == null) null else ArtworkInfo(id, albumArtBitmap!!)
|
||||
when {
|
||||
deleteAlbumArt -> ArtworkInfo(id, null)
|
||||
albumArtBitmap == null -> null
|
||||
else -> ArtworkInfo(id, albumArtBitmap!!)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.activities.tageditor
|
||||
|
||||
import android.net.Uri
|
||||
|
@ -88,11 +102,7 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
|||
writeValuesToFiles(fieldKeyValueMap, null)
|
||||
}
|
||||
|
||||
override fun getSongPaths(): List<String> {
|
||||
val paths = ArrayList<String>(1)
|
||||
paths.add(songRepository.song(id).data)
|
||||
return paths
|
||||
}
|
||||
override fun getSongPaths(): List<String> = listOf(songRepository.song(id).data)
|
||||
|
||||
override fun loadImageFromFile(selectedFile: Uri?) {
|
||||
}
|
||||
|
@ -111,5 +121,3 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
|||
val TAG: String = SongTagEditorActivity::class.java.simpleName
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5,67 +5,54 @@ import android.app.Dialog;
|
|||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
|
||||
import org.jaudiotagger.audio.AudioFile;
|
||||
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.FieldKey;
|
||||
import org.jaudiotagger.tag.Tag;
|
||||
import org.jaudiotagger.tag.TagException;
|
||||
import org.jaudiotagger.tag.images.Artwork;
|
||||
import org.jaudiotagger.tag.images.ArtworkFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.github.muntashirakon.music.R;
|
||||
import io.github.muntashirakon.music.misc.DialogAsyncTask;
|
||||
import io.github.muntashirakon.music.misc.UpdateToastMediaScannerCompletionListener;
|
||||
import io.github.muntashirakon.music.model.LoadingInfo;
|
||||
import io.github.muntashirakon.music.util.MusicUtil;
|
||||
import io.github.muntashirakon.music.util.SAFUtil;
|
||||
|
||||
public class WriteTagsAsyncTask extends DialogAsyncTask<WriteTagsAsyncTask.LoadingInfo, Integer, String[]> {
|
||||
public class WriteTagsAsyncTask extends DialogAsyncTask<LoadingInfo, Integer, List<String>> {
|
||||
|
||||
private WeakReference<Activity> activity;
|
||||
|
||||
public WriteTagsAsyncTask(@NonNull Activity activity) {
|
||||
super(activity);
|
||||
this.activity = new WeakReference<>(activity);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Dialog createDialog(@NonNull Context context) {
|
||||
|
||||
return new MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.saving_changes)
|
||||
.setCancelable(false)
|
||||
.setView(R.layout.loading)
|
||||
.create();
|
||||
public WriteTagsAsyncTask(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] doInBackground(LoadingInfo... params) {
|
||||
protected List<String> doInBackground(LoadingInfo... params) {
|
||||
try {
|
||||
LoadingInfo info = params[0];
|
||||
|
||||
Artwork artwork = null;
|
||||
File albumArtFile = null;
|
||||
if (info.artworkInfo != null && info.artworkInfo.getArtwork() != null) {
|
||||
if (info.getArtworkInfo() != null && info.getArtworkInfo().getArtwork() != null) {
|
||||
try {
|
||||
albumArtFile = MusicUtil.INSTANCE.createAlbumArtFile().getCanonicalFile();
|
||||
info.artworkInfo.getArtwork()
|
||||
.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
|
||||
info.getArtworkInfo().getArtwork().compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
|
||||
artwork = ArtworkFactory.createArtworkFromFile(albumArtFile);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -75,21 +62,14 @@ public class WriteTagsAsyncTask extends DialogAsyncTask<WriteTagsAsyncTask.Loadi
|
|||
int counter = 0;
|
||||
boolean wroteArtwork = false;
|
||||
boolean deletedArtwork = false;
|
||||
for (String filePath : info.filePaths) {
|
||||
publishProgress(++counter, info.filePaths.size());
|
||||
for (String filePath : info.getFilePaths()) {
|
||||
publishProgress(++counter, info.getFilePaths().size());
|
||||
try {
|
||||
Uri safUri = null;
|
||||
if (filePath.contains(SAFUtil.SEPARATOR)) {
|
||||
String[] fragments = filePath.split(SAFUtil.SEPARATOR);
|
||||
filePath = fragments[0];
|
||||
safUri = Uri.parse(fragments[1]);
|
||||
}
|
||||
|
||||
AudioFile audioFile = AudioFileIO.read(new File(filePath));
|
||||
Tag tag = audioFile.getTagOrCreateAndSetDefault();
|
||||
|
||||
if (info.fieldKeyValueMap != null) {
|
||||
for (Map.Entry<FieldKey, String> entry : info.fieldKeyValueMap.entrySet()) {
|
||||
if (info.getFieldKeyValueMap() != null) {
|
||||
for (Map.Entry<FieldKey, String> entry : info.getFieldKeyValueMap().entrySet()) {
|
||||
try {
|
||||
tag.setField(entry.getKey(), entry.getValue());
|
||||
} catch (Exception e) {
|
||||
|
@ -98,8 +78,8 @@ public class WriteTagsAsyncTask extends DialogAsyncTask<WriteTagsAsyncTask.Loadi
|
|||
}
|
||||
}
|
||||
|
||||
if (info.artworkInfo != null) {
|
||||
if (info.artworkInfo.getArtwork() == null) {
|
||||
if (info.getArtworkInfo() != null) {
|
||||
if (info.getArtworkInfo().getArtwork() == null) {
|
||||
tag.deleteArtworkField();
|
||||
deletedArtwork = true;
|
||||
} else if (artwork != null) {
|
||||
|
@ -109,10 +89,8 @@ public class WriteTagsAsyncTask extends DialogAsyncTask<WriteTagsAsyncTask.Loadi
|
|||
}
|
||||
}
|
||||
|
||||
Activity activity = this.activity.get();
|
||||
SAFUtil.write(activity, audioFile, safUri);
|
||||
|
||||
} catch (@NonNull Exception e) {
|
||||
audioFile.commit();
|
||||
} catch (@NonNull CannotReadException | IOException | CannotWriteException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -120,24 +98,13 @@ public class WriteTagsAsyncTask extends DialogAsyncTask<WriteTagsAsyncTask.Loadi
|
|||
Context context = getContext();
|
||||
if (context != null) {
|
||||
if (wroteArtwork) {
|
||||
MusicUtil.INSTANCE.insertAlbumArt(context, info.artworkInfo.getAlbumId(), albumArtFile.getPath());
|
||||
MusicUtil.INSTANCE.insertAlbumArt(context, info.getArtworkInfo().getAlbumId(), albumArtFile.getPath());
|
||||
} else if (deletedArtwork) {
|
||||
MusicUtil.INSTANCE.deleteAlbumArt(context, info.artworkInfo.getAlbumId());
|
||||
MusicUtil.INSTANCE.deleteAlbumArt(context, info.getArtworkInfo().getAlbumId());
|
||||
}
|
||||
}
|
||||
|
||||
Collection<String> paths = info.filePaths;
|
||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
|
||||
paths = new ArrayList<>(info.filePaths.size());
|
||||
for (String path : info.filePaths) {
|
||||
if (path.contains(SAFUtil.SEPARATOR)) {
|
||||
path = path.split(SAFUtil.SEPARATOR)[0];
|
||||
}
|
||||
paths.add(path);
|
||||
}
|
||||
}
|
||||
|
||||
return paths.toArray(new String[paths.size()]);
|
||||
return info.getFilePaths();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
|
@ -145,48 +112,40 @@ public class WriteTagsAsyncTask extends DialogAsyncTask<WriteTagsAsyncTask.Loadi
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled(String[] toBeScanned) {
|
||||
super.onCancelled(toBeScanned);
|
||||
scan(toBeScanned);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String[] toBeScanned) {
|
||||
protected void onPostExecute(List<String> toBeScanned) {
|
||||
super.onPostExecute(toBeScanned);
|
||||
scan(toBeScanned);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled(List<String> toBeScanned) {
|
||||
super.onCancelled(toBeScanned);
|
||||
scan(toBeScanned);
|
||||
}
|
||||
|
||||
private void scan(List<String> toBeScanned) {
|
||||
Context context = getContext();
|
||||
if (toBeScanned == null || toBeScanned.isEmpty()) {
|
||||
Log.i("scan", "scan: Empty");
|
||||
Toast.makeText(context, "Scan file from folder", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
MediaScannerConnection.scanFile(context, toBeScanned.toArray(new String[0]), null, context instanceof Activity ? new UpdateToastMediaScannerCompletionListener((Activity) context, toBeScanned) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog createDialog(@NonNull Context context) {
|
||||
return new MaterialDialog.Builder(context)
|
||||
.title(R.string.saving_changes)
|
||||
.cancelable(false)
|
||||
.progress(false, 0)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(@NonNull Dialog dialog, Integer... values) {
|
||||
super.onProgressUpdate(dialog, values);
|
||||
//((MaterialDialog) dialog).setMaxProgress(values[1]);
|
||||
//((MaterialDialog) dialog).setProgress(values[0]);
|
||||
((MaterialDialog) dialog).setMaxProgress(values[1]);
|
||||
((MaterialDialog) dialog).setProgress(values[0]);
|
||||
}
|
||||
|
||||
private void scan(String[] toBeScanned) {
|
||||
Activity activity = this.activity.get();
|
||||
if (activity != null) {
|
||||
MediaScannerConnection.scanFile(activity, toBeScanned, null,
|
||||
new UpdateToastMediaScannerCompletionListener(activity, toBeScanned));
|
||||
}
|
||||
}
|
||||
|
||||
public static class LoadingInfo {
|
||||
|
||||
@Nullable
|
||||
final Map<FieldKey, String> fieldKeyValueMap;
|
||||
|
||||
final Collection<String> filePaths;
|
||||
|
||||
@Nullable
|
||||
private AbsTagEditorActivity.ArtworkInfo artworkInfo;
|
||||
|
||||
public LoadingInfo(Collection<String> filePaths,
|
||||
@Nullable Map<FieldKey, String> fieldKeyValueMap,
|
||||
@Nullable AbsTagEditorActivity.ArtworkInfo artworkInfo) {
|
||||
this.filePaths = filePaths;
|
||||
this.fieldKeyValueMap = fieldKeyValueMap;
|
||||
this.artworkInfo = artworkInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,116 +22,119 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.checkbox.MaterialCheckBox;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import io.github.muntashirakon.music.R;
|
||||
import io.github.muntashirakon.music.model.CategoryInfo;
|
||||
import io.github.muntashirakon.music.util.SwipeAndDragHelper;
|
||||
import com.google.android.material.checkbox.MaterialCheckBox;
|
||||
import java.util.List;
|
||||
|
||||
public class CategoryInfoAdapter extends RecyclerView.Adapter<CategoryInfoAdapter.ViewHolder>
|
||||
implements SwipeAndDragHelper.ActionCompletionContract {
|
||||
implements SwipeAndDragHelper.ActionCompletionContract {
|
||||
|
||||
private List<CategoryInfo> categoryInfos;
|
||||
private ItemTouchHelper touchHelper;
|
||||
private List<CategoryInfo> categoryInfos;
|
||||
private ItemTouchHelper touchHelper;
|
||||
|
||||
public CategoryInfoAdapter() {
|
||||
SwipeAndDragHelper swipeAndDragHelper = new SwipeAndDragHelper(this);
|
||||
touchHelper = new ItemTouchHelper(swipeAndDragHelper);
|
||||
}
|
||||
public CategoryInfoAdapter() {
|
||||
SwipeAndDragHelper swipeAndDragHelper = new SwipeAndDragHelper(this);
|
||||
touchHelper = new ItemTouchHelper(swipeAndDragHelper);
|
||||
}
|
||||
|
||||
public void attachToRecyclerView(RecyclerView recyclerView) {
|
||||
touchHelper.attachToRecyclerView(recyclerView);
|
||||
}
|
||||
public void attachToRecyclerView(RecyclerView recyclerView) {
|
||||
touchHelper.attachToRecyclerView(recyclerView);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<CategoryInfo> getCategoryInfos() {
|
||||
return categoryInfos;
|
||||
}
|
||||
@NonNull
|
||||
public List<CategoryInfo> getCategoryInfos() {
|
||||
return categoryInfos;
|
||||
}
|
||||
|
||||
public void setCategoryInfos(@NonNull List<CategoryInfo> categoryInfos) {
|
||||
this.categoryInfos = categoryInfos;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
public void setCategoryInfos(@NonNull List<CategoryInfo> categoryInfos) {
|
||||
this.categoryInfos = categoryInfos;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return categoryInfos.size();
|
||||
}
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return categoryInfos.size();
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull CategoryInfoAdapter.ViewHolder holder, int position) {
|
||||
CategoryInfo categoryInfo = categoryInfos.get(position);
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull CategoryInfoAdapter.ViewHolder holder, int position) {
|
||||
CategoryInfo categoryInfo = categoryInfos.get(position);
|
||||
|
||||
holder.checkBox.setChecked(categoryInfo.isVisible());
|
||||
holder.title.setText(holder.title.getResources().getString(categoryInfo.getCategory().getStringRes()));
|
||||
holder.checkBox.setChecked(categoryInfo.isVisible());
|
||||
holder.title.setText(
|
||||
holder.title.getResources().getString(categoryInfo.getCategory().getStringRes()));
|
||||
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
if (!(categoryInfo.isVisible() && isLastCheckedCategory(categoryInfo))) {
|
||||
categoryInfo.setVisible(!categoryInfo.isVisible());
|
||||
holder.checkBox.setChecked(categoryInfo.isVisible());
|
||||
} else {
|
||||
Toast.makeText(holder.itemView.getContext(), R.string.you_have_to_select_at_least_one_category,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
holder.itemView.setOnClickListener(
|
||||
v -> {
|
||||
if (!(categoryInfo.isVisible() && isLastCheckedCategory(categoryInfo))) {
|
||||
categoryInfo.setVisible(!categoryInfo.isVisible());
|
||||
holder.checkBox.setChecked(categoryInfo.isVisible());
|
||||
} else {
|
||||
Toast.makeText(
|
||||
holder.itemView.getContext(),
|
||||
R.string.you_have_to_select_at_least_one_category,
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
});
|
||||
|
||||
holder.dragView.setOnTouchListener((view, event) -> {
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
||||
touchHelper.startDrag(holder);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
holder.dragView.setOnTouchListener(
|
||||
(view, event) -> {
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
||||
touchHelper.startDrag(holder);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public CategoryInfoAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.preference_dialog_library_categories_listitem, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
@Override
|
||||
@NonNull
|
||||
public CategoryInfoAdapter.ViewHolder onCreateViewHolder(
|
||||
@NonNull ViewGroup parent, int viewType) {
|
||||
View view =
|
||||
LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.preference_dialog_library_categories_listitem, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewMoved(int oldPosition, int newPosition) {
|
||||
CategoryInfo categoryInfo = categoryInfos.get(oldPosition);
|
||||
categoryInfos.remove(oldPosition);
|
||||
categoryInfos.add(newPosition, categoryInfo);
|
||||
notifyItemMoved(oldPosition, newPosition);
|
||||
}
|
||||
@Override
|
||||
public void onViewMoved(int oldPosition, int newPosition) {
|
||||
CategoryInfo categoryInfo = categoryInfos.get(oldPosition);
|
||||
categoryInfos.remove(oldPosition);
|
||||
categoryInfos.add(newPosition, categoryInfo);
|
||||
notifyItemMoved(oldPosition, newPosition);
|
||||
}
|
||||
|
||||
private boolean isLastCheckedCategory(CategoryInfo categoryInfo) {
|
||||
if (categoryInfo.isVisible()) {
|
||||
for (CategoryInfo c : categoryInfos) {
|
||||
if (c != categoryInfo && c.isVisible()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private boolean isLastCheckedCategory(CategoryInfo categoryInfo) {
|
||||
if (categoryInfo.isVisible()) {
|
||||
for (CategoryInfo c : categoryInfos) {
|
||||
if (c != categoryInfo && c.isVisible()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
private MaterialCheckBox checkBox;
|
||||
private View dragView;
|
||||
private TextView title;
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
private MaterialCheckBox checkBox;
|
||||
private View dragView;
|
||||
private TextView title;
|
||||
|
||||
ViewHolder(View view) {
|
||||
super(view);
|
||||
checkBox = view.findViewById(R.id.checkbox);
|
||||
checkBox.setButtonTintList(
|
||||
ColorStateList.valueOf(ThemeStore.Companion.accentColor(checkBox.getContext())));
|
||||
title = view.findViewById(R.id.title);
|
||||
dragView = view.findViewById(R.id.drag_view);
|
||||
}
|
||||
ViewHolder(View view) {
|
||||
super(view);
|
||||
checkBox = view.findViewById(R.id.checkbox);
|
||||
checkBox.setButtonTintList(
|
||||
ColorStateList.valueOf(ThemeStore.Companion.accentColor(checkBox.getContext())));
|
||||
title = view.findViewById(R.id.title);
|
||||
dragView = view.findViewById(R.id.drag_view);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter
|
||||
|
||||
import android.app.Activity
|
||||
|
@ -59,6 +73,11 @@ class ContributorAdapter(
|
|||
return contributors.size
|
||||
}
|
||||
|
||||
fun swapData(it: List<Contributor>) {
|
||||
contributors = it
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val title: TextView = itemView.findViewById(R.id.title)
|
||||
val text: TextView = itemView.findViewById(R.id.text)
|
||||
|
@ -68,7 +87,7 @@ class ContributorAdapter(
|
|||
title.text = contributor.name
|
||||
text.text = contributor.summary
|
||||
Glide.with(image.context)
|
||||
.load(contributor.profileImage)
|
||||
.load(contributor.image)
|
||||
.error(R.drawable.ic_account)
|
||||
.placeholder(R.drawable.ic_account)
|
||||
.dontAnimate()
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter
|
||||
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -23,14 +36,12 @@ class GenreAdapter(
|
|||
var dataSet: List<Genre>,
|
||||
private val mItemLayoutRes: Int
|
||||
) : RecyclerView.Adapter<GenreAdapter.ViewHolder>() {
|
||||
val colors = listOf<Int>(Color.RED, Color.BLUE)
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
return ViewHolder(LayoutInflater.from(activity).inflate(mItemLayoutRes, parent, false))
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val genre = dataSet[position]
|
||||
|
||||
holder.title?.text = genre.name
|
||||
holder.text?.text = String.format(
|
||||
Locale.getDefault(),
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter
|
||||
|
||||
import android.view.LayoutInflater
|
||||
|
@ -15,23 +29,23 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||
import androidx.recyclerview.widget.RecyclerView
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import io.github.muntashirakon.music.*
|
||||
import io.github.muntashirakon.music.adapter.album.AlbumAdapter
|
||||
import io.github.muntashirakon.music.adapter.artist.ArtistAdapter
|
||||
import io.github.muntashirakon.music.adapter.song.SongAdapter
|
||||
import io.github.muntashirakon.music.extensions.hide
|
||||
import io.github.muntashirakon.music.fragments.albums.AlbumClickListener
|
||||
import io.github.muntashirakon.music.fragments.artists.ArtistClickListener
|
||||
import io.github.muntashirakon.music.glide.SongGlideRequest
|
||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
||||
import io.github.muntashirakon.music.interfaces.IAlbumClickListener
|
||||
import io.github.muntashirakon.music.interfaces.IArtistClickListener
|
||||
import io.github.muntashirakon.music.model.*
|
||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
|
||||
class HomeAdapter(
|
||||
private val activity: AppCompatActivity
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), ArtistClickListener, AlbumClickListener {
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), IArtistClickListener, IAlbumClickListener {
|
||||
|
||||
private var list = listOf<Home>()
|
||||
|
||||
|
@ -121,7 +135,6 @@ class HomeAdapter(
|
|||
viewHolder.bind(home)
|
||||
}
|
||||
PLAYLISTS -> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +194,6 @@ class HomeAdapter(
|
|||
.asBitmap()
|
||||
.build()
|
||||
.into(itemView.findViewById(id))
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -225,21 +237,22 @@ class HomeAdapter(
|
|||
}
|
||||
|
||||
fun artistsAdapter(artists: List<Artist>) =
|
||||
ArtistAdapter(activity, artists, PreferenceUtil.homeGridStyle, null, this)
|
||||
ArtistAdapter(activity, artists, PreferenceUtil.homeArtistGridStyle, null, this)
|
||||
|
||||
fun albumAdapter(albums: List<Album>) =
|
||||
AlbumAdapter(activity, albums, R.layout.item_image, null, this)
|
||||
AlbumAdapter(activity, albums, PreferenceUtil.homeAlbumGridStyle, null, this)
|
||||
|
||||
fun gridLayoutManager() = GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
|
||||
|
||||
fun linearLayoutManager() = LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
|
||||
|
||||
override fun onArtist(artistId: Long, imageView: ImageView) {
|
||||
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(
|
||||
imageView to activity.getString(R.string.transition_album_art)
|
||||
view to "artist"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -250,7 +263,7 @@ class HomeAdapter(
|
|||
bundleOf(EXTRA_ALBUM_ID to albumId),
|
||||
null,
|
||||
FragmentNavigatorExtras(
|
||||
view to activity.getString(R.string.transition_album_art)
|
||||
view to "album"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,16 +1,32 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.os.bundleOf
|
||||
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 com.bumptech.glide.Glide
|
||||
import io.github.muntashirakon.music.*
|
||||
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
|
||||
import io.github.muntashirakon.music.db.PlaylistWithSongs
|
||||
import io.github.muntashirakon.music.glide.AlbumGlideRequest
|
||||
import io.github.muntashirakon.music.glide.ArtistGlideRequest
|
||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
||||
|
@ -19,13 +35,15 @@ import io.github.muntashirakon.music.model.*
|
|||
import io.github.muntashirakon.music.model.smartplaylist.AbsSmartPlaylist
|
||||
import io.github.muntashirakon.music.repository.PlaylistSongsLoader
|
||||
import io.github.muntashirakon.music.util.MusicUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import java.util.*
|
||||
|
||||
class SearchAdapter(
|
||||
private val activity: FragmentActivity,
|
||||
private var dataSet: List<Any>
|
||||
) : RecyclerView.Adapter<SearchAdapter.ViewHolder>() {
|
||||
|
||||
fun swapDataSet(dataSet: MutableList<Any>) {
|
||||
fun swapDataSet(dataSet: List<Any>) {
|
||||
this.dataSet = dataSet
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
@ -34,7 +52,7 @@ class SearchAdapter(
|
|||
if (dataSet[position] is Album) return ALBUM
|
||||
if (dataSet[position] is Artist) return ARTIST
|
||||
if (dataSet[position] is Genre) return GENRE
|
||||
if (dataSet[position] is Playlist) return PLAYLIST
|
||||
if (dataSet[position] is PlaylistWithSongs) return PLAYLIST
|
||||
return if (dataSet[position] is Song) SONG else HEADER
|
||||
}
|
||||
|
||||
|
@ -56,42 +74,52 @@ class SearchAdapter(
|
|||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
when (getItemViewType(position)) {
|
||||
ALBUM -> {
|
||||
val album = dataSet.get(position) as Album
|
||||
holder.imageTextContainer?.isVisible = true
|
||||
val album = dataSet[position] as Album
|
||||
holder.title?.text = album.title
|
||||
holder.text?.text = album.artistName
|
||||
AlbumGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||
.checkIgnoreMediaStore().build().into(holder.image)
|
||||
}
|
||||
ARTIST -> {
|
||||
val artist = dataSet.get(position) as Artist
|
||||
holder.imageTextContainer?.isVisible = true
|
||||
val artist = dataSet[position] as Artist
|
||||
holder.title?.text = artist.name
|
||||
holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
|
||||
ArtistGlideRequest.Builder.from(Glide.with(activity), artist).build()
|
||||
.into(holder.image)
|
||||
}
|
||||
SONG -> {
|
||||
val song = dataSet.get(position) as Song
|
||||
val song = dataSet[position] as Song
|
||||
holder.title?.text = song.title
|
||||
holder.text?.text = song.albumName
|
||||
}
|
||||
GENRE -> {
|
||||
val genre = dataSet.get(position) as 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.get(position) as Playlist
|
||||
holder.title?.text = playlist.name
|
||||
holder.text?.text = MusicUtil.getPlaylistInfoString(activity, getSongs(playlist))
|
||||
val playlist = dataSet[position] as PlaylistWithSongs
|
||||
holder.title?.text = playlist.playlistEntity.playlistName
|
||||
holder.text?.text = MusicUtil.playlistInfoString(activity, playlist.songs)
|
||||
}
|
||||
else -> {
|
||||
holder.title?.text = dataSet.get(position).toString()
|
||||
holder.title?.text = dataSet[position].toString()
|
||||
holder.title?.setTextColor(ThemeStore.accentColor(activity))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSongs(playlist: Playlist): java.util.ArrayList<Song> {
|
||||
val songs = java.util.ArrayList<Song>()
|
||||
private fun getSongs(playlist: Playlist): List<Song> {
|
||||
val songs = mutableListOf<Song>()
|
||||
if (playlist is AbsSmartPlaylist) {
|
||||
songs.addAll(playlist.getSongs())
|
||||
} else {
|
||||
|
@ -107,7 +135,7 @@ class SearchAdapter(
|
|||
inner class ViewHolder(itemView: View, itemViewType: Int) : MediaEntryViewHolder(itemView) {
|
||||
init {
|
||||
itemView.setOnLongClickListener(null)
|
||||
|
||||
imageTextContainer?.isInvisible = true
|
||||
if (itemViewType == SONG) {
|
||||
menu?.visibility = View.VISIBLE
|
||||
menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
|
||||
|
@ -151,12 +179,12 @@ class SearchAdapter(
|
|||
}
|
||||
PLAYLIST -> {
|
||||
activity.findNavController(R.id.fragment_container).navigate(
|
||||
R.id.artistDetailsFragment,
|
||||
bundleOf(EXTRA_PLAYLIST to (item as Playlist))
|
||||
R.id.playlistDetailsFragment,
|
||||
bundleOf(EXTRA_PLAYLIST to (item as PlaylistWithSongs))
|
||||
)
|
||||
}
|
||||
SONG -> {
|
||||
val playList = ArrayList<Song>()
|
||||
val playList = mutableListOf<Song>()
|
||||
playList.add(item as Song)
|
||||
MusicPlayerRemote.openQueue(playList, 0, true)
|
||||
}
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
/*
|
||||
* Copyright 2019 Google LLC
|
||||
* Copyright (c) 2020 Hemanth Savarla.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* Licensed under the GNU General Public License v3
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.github.muntashirakon.music.adapter
|
||||
|
||||
|
@ -22,31 +21,31 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.signature.MediaStoreSignature
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
||||
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
|
||||
import io.github.muntashirakon.music.glide.audiocover.AudioFileCover
|
||||
import io.github.muntashirakon.music.interfaces.CabHolder
|
||||
import io.github.muntashirakon.music.interfaces.Callbacks
|
||||
import io.github.muntashirakon.music.interfaces.ICabHolder
|
||||
import io.github.muntashirakon.music.interfaces.ICallbacks
|
||||
import io.github.muntashirakon.music.util.MusicUtil
|
||||
import io.github.muntashirakon.music.util.RetroUtil
|
||||
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.signature.MediaStoreSignature
|
||||
import java.io.File
|
||||
import java.text.DecimalFormat
|
||||
import kotlin.math.log10
|
||||
import kotlin.math.pow
|
||||
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||
|
||||
class SongFileAdapter(
|
||||
private val activity: AppCompatActivity,
|
||||
private var dataSet: List<File>,
|
||||
private val itemLayoutRes: Int,
|
||||
private val callbacks: Callbacks?,
|
||||
cabHolder: CabHolder?
|
||||
private val ICallbacks: ICallbacks?,
|
||||
ICabHolder: ICabHolder?
|
||||
) : AbsMultiSelectAdapter<SongFileAdapter.ViewHolder, File>(
|
||||
activity, cabHolder, R.menu.menu_media_selection
|
||||
activity, ICabHolder, R.menu.menu_media_selection
|
||||
), PopupTextProvider {
|
||||
|
||||
init {
|
||||
|
@ -136,8 +135,8 @@ class SongFileAdapter(
|
|||
}
|
||||
|
||||
override fun onMultipleItemAction(menuItem: MenuItem, selection: List<File>) {
|
||||
if (callbacks == null) return
|
||||
callbacks.onMultipleItemAction(menuItem, selection as ArrayList<File>)
|
||||
if (ICallbacks == null) return
|
||||
ICallbacks.onMultipleItemAction(menuItem, selection as ArrayList<File>)
|
||||
}
|
||||
|
||||
override fun getPopupText(position: Int): String {
|
||||
|
@ -148,15 +147,14 @@ class SongFileAdapter(
|
|||
return MusicUtil.getSectionName(dataSet[position].name)
|
||||
}
|
||||
|
||||
|
||||
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
||||
|
||||
init {
|
||||
if (menu != null && callbacks != null) {
|
||||
if (menu != null && ICallbacks != null) {
|
||||
menu?.setOnClickListener { v ->
|
||||
val position = layoutPosition
|
||||
if (isPositionInRange(position)) {
|
||||
callbacks.onFileMenuClicked(dataSet[position], v)
|
||||
ICallbacks.onFileMenuClicked(dataSet[position], v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +169,7 @@ class SongFileAdapter(
|
|||
if (isInQuickSelectMode) {
|
||||
toggleChecked(position)
|
||||
} else {
|
||||
callbacks?.onFileSelected(dataSet[position])
|
||||
ICallbacks?.onFileSelected(dataSet[position])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -198,4 +196,4 @@ class SongFileAdapter(
|
|||
return DecimalFormat("#,##0.##").format(size / 1024.0.pow(digitGroups.toDouble())) + " " + units[digitGroups]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter
|
||||
|
||||
import android.app.Activity
|
||||
|
@ -49,4 +63,4 @@ class TranslatorsAdapter(
|
|||
image.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter.album
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
|
@ -6,7 +20,23 @@ import android.view.LayoutInflater
|
|||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
||||
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
|
||||
import io.github.muntashirakon.music.glide.AlbumGlideRequest
|
||||
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
|
||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
||||
import io.github.muntashirakon.music.helper.SortOrder
|
||||
import io.github.muntashirakon.music.helper.menu.SongsMenuHelper
|
||||
import io.github.muntashirakon.music.interfaces.IAlbumClickListener
|
||||
import io.github.muntashirakon.music.interfaces.ICabHolder
|
||||
import io.github.muntashirakon.music.model.Album
|
||||
import io.github.muntashirakon.music.model.Song
|
||||
import io.github.muntashirakon.music.util.MusicUtil
|
||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
|
||||
import com.bumptech.glide.Glide
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
||||
|
@ -29,11 +59,11 @@ open class AlbumAdapter(
|
|||
protected val activity: FragmentActivity,
|
||||
var dataSet: List<Album>,
|
||||
protected var itemLayoutRes: Int,
|
||||
cabHolder: CabHolder?,
|
||||
private val albumClickListener: AlbumClickListener?
|
||||
ICabHolder: ICabHolder?,
|
||||
private val albumClickListener: IAlbumClickListener?
|
||||
) : AbsMultiSelectAdapter<AlbumAdapter.ViewHolder, Album>(
|
||||
activity,
|
||||
cabHolder,
|
||||
ICabHolder,
|
||||
R.menu.menu_media_selection
|
||||
), PopupTextProvider {
|
||||
|
||||
|
@ -75,7 +105,7 @@ open class AlbumAdapter(
|
|||
holder.title?.text = getAlbumTitle(album)
|
||||
holder.text?.text = getAlbumText(album)
|
||||
holder.playSongs?.setOnClickListener {
|
||||
album.songs?.let { songs ->
|
||||
album.songs.let { songs ->
|
||||
MusicPlayerRemote.openQueue(
|
||||
songs,
|
||||
0,
|
||||
|
@ -116,7 +146,7 @@ open class AlbumAdapter(
|
|||
}
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
return dataSet[position].id.toLong()
|
||||
return dataSet[position].id
|
||||
}
|
||||
|
||||
override fun getIdentifier(position: Int): Album? {
|
||||
|
@ -128,7 +158,8 @@ open class AlbumAdapter(
|
|||
}
|
||||
|
||||
override fun onMultipleItemAction(
|
||||
menuItem: MenuItem, selection: List<Album>
|
||||
menuItem: MenuItem,
|
||||
selection: List<Album>
|
||||
) {
|
||||
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
|
||||
}
|
||||
|
@ -161,7 +192,7 @@ open class AlbumAdapter(
|
|||
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
||||
|
||||
init {
|
||||
setImageTransitionName(activity.getString(R.string.transition_album_art))
|
||||
setImageTransitionName("Album")
|
||||
menu?.visibility = View.GONE
|
||||
}
|
||||
|
||||
|
@ -170,6 +201,7 @@ open class AlbumAdapter(
|
|||
if (isInQuickSelectMode) {
|
||||
toggleChecked(layoutPosition)
|
||||
} else {
|
||||
ViewCompat.setTransitionName(itemView, "album")
|
||||
albumClickListener?.onAlbumClick(dataSet[layoutPosition].id, itemView)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter.album
|
||||
|
||||
import android.os.Bundle
|
||||
|
@ -5,6 +19,7 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
|
@ -88,9 +103,9 @@ class AlbumCoverPagerAdapter(
|
|||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val view = inflater.inflate(getLayoutWithPlayerTheme(), container, false)
|
||||
ViewCompat.setTransitionName(view, "lyrics")
|
||||
albumCover = view.findViewById(R.id.player_image)
|
||||
albumCover.setOnClickListener {
|
||||
//LyricsDialog().show(childFragmentManager, "LyricsDialog")
|
||||
view.setOnClickListener {
|
||||
showLyricsDialog()
|
||||
}
|
||||
return view
|
||||
|
@ -98,14 +113,14 @@ class AlbumCoverPagerAdapter(
|
|||
|
||||
private fun showLyricsDialog() {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val data: String = MusicUtil.getLyrics(song) ?: "No lyrics found"
|
||||
val data: String? = MusicUtil.getLyrics(song)
|
||||
withContext(Dispatchers.Main) {
|
||||
MaterialAlertDialogBuilder(
|
||||
requireContext(),
|
||||
R.style.ThemeOverlay_MaterialComponents_Dialog_Alert
|
||||
).apply {
|
||||
setTitle(song.title)
|
||||
setMessage(data)
|
||||
setMessage(if (data.isNullOrEmpty()) "No lyrics found" else data)
|
||||
setNegativeButton(R.string.synced_lyrics) { _, _ ->
|
||||
NavigationUtil.goToLyrics(requireActivity())
|
||||
}
|
||||
|
@ -197,4 +212,3 @@ class AlbumCoverPagerAdapter(
|
|||
val TAG: String = AlbumCoverPagerAdapter::class.java.simpleName
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,27 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter.album
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import io.github.muntashirakon.music.fragments.albums.AlbumClickListener
|
||||
import io.github.muntashirakon.music.glide.AlbumGlideRequest
|
||||
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
|
||||
import io.github.muntashirakon.music.helper.HorizontalAdapterHelper
|
||||
import io.github.muntashirakon.music.interfaces.CabHolder
|
||||
import io.github.muntashirakon.music.interfaces.IAlbumClickListener
|
||||
import io.github.muntashirakon.music.interfaces.ICabHolder
|
||||
import io.github.muntashirakon.music.model.Album
|
||||
import io.github.muntashirakon.music.util.MusicUtil
|
||||
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
|
||||
|
@ -16,10 +30,10 @@ import com.bumptech.glide.Glide
|
|||
class HorizontalAlbumAdapter(
|
||||
activity: FragmentActivity,
|
||||
dataSet: List<Album>,
|
||||
cabHolder: CabHolder?,
|
||||
albumClickListener: AlbumClickListener
|
||||
ICabHolder: ICabHolder?,
|
||||
albumClickListener: IAlbumClickListener
|
||||
) : AlbumAdapter(
|
||||
activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, cabHolder, albumClickListener
|
||||
activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, ICabHolder, albumClickListener
|
||||
) {
|
||||
|
||||
override fun createViewHolder(view: View, viewType: Int): ViewHolder {
|
||||
|
@ -29,8 +43,8 @@ class HorizontalAlbumAdapter(
|
|||
}
|
||||
|
||||
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))
|
||||
// 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) {
|
||||
|
@ -51,7 +65,7 @@ class HorizontalAlbumAdapter(
|
|||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return HorizontalAdapterHelper.getItemViewtype(position, itemCount)
|
||||
return HorizontalAdapterHelper.getItemViewType(position, itemCount)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter.artist
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
|
@ -8,31 +22,31 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.bumptech.glide.Glide
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
||||
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
|
||||
import io.github.muntashirakon.music.extensions.hide
|
||||
import io.github.muntashirakon.music.fragments.artists.ArtistClickListener
|
||||
import io.github.muntashirakon.music.glide.ArtistGlideRequest
|
||||
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
|
||||
import io.github.muntashirakon.music.helper.menu.SongsMenuHelper
|
||||
import io.github.muntashirakon.music.interfaces.CabHolder
|
||||
import io.github.muntashirakon.music.interfaces.IArtistClickListener
|
||||
import io.github.muntashirakon.music.interfaces.ICabHolder
|
||||
import io.github.muntashirakon.music.model.Artist
|
||||
import io.github.muntashirakon.music.model.Song
|
||||
import io.github.muntashirakon.music.util.MusicUtil
|
||||
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
|
||||
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||
import com.bumptech.glide.Glide
|
||||
import java.util.*
|
||||
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||
|
||||
class ArtistAdapter(
|
||||
val activity: FragmentActivity,
|
||||
var dataSet: List<Artist>,
|
||||
var itemLayoutRes: Int,
|
||||
cabHolder: CabHolder?,
|
||||
private val artistClickListener: ArtistClickListener
|
||||
val ICabHolder: ICabHolder?,
|
||||
val IArtistClickListener: IArtistClickListener
|
||||
) : AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist>(
|
||||
activity, cabHolder, R.menu.menu_media_selection
|
||||
activity, ICabHolder, R.menu.menu_media_selection
|
||||
), PopupTextProvider {
|
||||
|
||||
init {
|
||||
|
@ -45,7 +59,7 @@ class ArtistAdapter(
|
|||
}
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
return dataSet[position].id.toLong()
|
||||
return dataSet[position].id
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
|
@ -107,7 +121,8 @@ class ArtistAdapter(
|
|||
}
|
||||
|
||||
override fun onMultipleItemAction(
|
||||
menuItem: MenuItem, selection: List<Artist>
|
||||
menuItem: MenuItem,
|
||||
selection: List<Artist>
|
||||
) {
|
||||
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
|
||||
}
|
||||
|
@ -140,11 +155,8 @@ class ArtistAdapter(
|
|||
toggleChecked(layoutPosition)
|
||||
} else {
|
||||
image?.let {
|
||||
ViewCompat.setTransitionName(
|
||||
it,
|
||||
activity.getString(R.string.transition_artist_image)
|
||||
)
|
||||
artistClickListener.onArtist(dataSet[layoutPosition].id, it)
|
||||
ViewCompat.setTransitionName(itemView, "album")
|
||||
IArtistClickListener.onArtist(dataSet[layoutPosition].id, itemView)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,132 +3,127 @@ package io.github.muntashirakon.music.adapter.base;
|
|||
import android.content.Context;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.annotation.MenuRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import io.github.muntashirakon.music.R;
|
||||
import io.github.muntashirakon.music.interfaces.ICabHolder;
|
||||
import com.afollestad.materialcab.MaterialCab;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.github.muntashirakon.music.R;
|
||||
import io.github.muntashirakon.music.interfaces.CabHolder;
|
||||
public abstract class AbsMultiSelectAdapter<V extends RecyclerView.ViewHolder, I>
|
||||
extends RecyclerView.Adapter<V> implements MaterialCab.Callback {
|
||||
|
||||
@Nullable private final ICabHolder ICabHolder;
|
||||
private final Context context;
|
||||
private MaterialCab cab;
|
||||
private List<I> checked;
|
||||
private int menuRes;
|
||||
|
||||
public abstract class AbsMultiSelectAdapter<V extends RecyclerView.ViewHolder, I> extends RecyclerView.Adapter<V>
|
||||
implements MaterialCab.Callback {
|
||||
public AbsMultiSelectAdapter(
|
||||
@NonNull Context context, @Nullable ICabHolder ICabHolder, @MenuRes int menuRes) {
|
||||
this.ICabHolder = ICabHolder;
|
||||
checked = new ArrayList<>();
|
||||
this.menuRes = menuRes;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private final CabHolder cabHolder;
|
||||
private final Context context;
|
||||
private MaterialCab cab;
|
||||
private List<I> checked;
|
||||
private int menuRes;
|
||||
@Override
|
||||
public boolean onCabCreated(MaterialCab materialCab, Menu menu) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public AbsMultiSelectAdapter(@NonNull Context context, @Nullable CabHolder cabHolder, @MenuRes int menuRes) {
|
||||
this.cabHolder = cabHolder;
|
||||
checked = new ArrayList<>();
|
||||
this.menuRes = menuRes;
|
||||
this.context = context;
|
||||
@Override
|
||||
public boolean onCabFinished(MaterialCab materialCab) {
|
||||
clearChecked();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCabItemClicked(MenuItem menuItem) {
|
||||
if (menuItem.getItemId() == R.id.action_multi_select_adapter_check_all) {
|
||||
checkAll();
|
||||
} else {
|
||||
onMultipleItemAction(menuItem, new ArrayList<>(checked));
|
||||
cab.finish();
|
||||
clearChecked();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCabCreated(MaterialCab materialCab, Menu menu) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCabFinished(MaterialCab materialCab) {
|
||||
clearChecked();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCabItemClicked(MenuItem menuItem) {
|
||||
if (menuItem.getItemId() == R.id.action_multi_select_adapter_check_all) {
|
||||
checkAll();
|
||||
} else {
|
||||
onMultipleItemAction(menuItem, new ArrayList<>(checked));
|
||||
cab.finish();
|
||||
clearChecked();
|
||||
protected void checkAll() {
|
||||
if (ICabHolder != null) {
|
||||
checked.clear();
|
||||
for (int i = 0; i < getItemCount(); i++) {
|
||||
I identifier = getIdentifier(i);
|
||||
if (identifier != null) {
|
||||
checked.add(identifier);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
updateCab();
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkAll() {
|
||||
if (cabHolder != null) {
|
||||
checked.clear();
|
||||
for (int i = 0; i < getItemCount(); i++) {
|
||||
I identifier = getIdentifier(i);
|
||||
if (identifier != null) {
|
||||
checked.add(identifier);
|
||||
}
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
updateCab();
|
||||
}
|
||||
}
|
||||
@Nullable
|
||||
protected abstract I getIdentifier(int position);
|
||||
|
||||
@Nullable
|
||||
protected abstract I getIdentifier(int position);
|
||||
protected String getName(I object) {
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
protected String getName(I object) {
|
||||
return object.toString();
|
||||
}
|
||||
protected boolean isChecked(I identifier) {
|
||||
return checked.contains(identifier);
|
||||
}
|
||||
|
||||
protected boolean isChecked(I identifier) {
|
||||
return checked.contains(identifier);
|
||||
}
|
||||
protected boolean isInQuickSelectMode() {
|
||||
return cab != null && cab.isActive();
|
||||
}
|
||||
|
||||
protected boolean isInQuickSelectMode() {
|
||||
return cab != null && cab.isActive();
|
||||
}
|
||||
protected abstract void onMultipleItemAction(MenuItem menuItem, List<I> selection);
|
||||
|
||||
protected abstract void onMultipleItemAction(MenuItem menuItem, List<I> selection);
|
||||
protected void setMultiSelectMenuRes(@MenuRes int menuRes) {
|
||||
this.menuRes = menuRes;
|
||||
}
|
||||
|
||||
protected void setMultiSelectMenuRes(@MenuRes int menuRes) {
|
||||
this.menuRes = menuRes;
|
||||
}
|
||||
|
||||
protected boolean toggleChecked(final int position) {
|
||||
if (cabHolder != null) {
|
||||
I identifier = getIdentifier(position);
|
||||
if (identifier == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!checked.remove(identifier)) {
|
||||
checked.add(identifier);
|
||||
}
|
||||
|
||||
notifyItemChanged(position);
|
||||
updateCab();
|
||||
return true;
|
||||
}
|
||||
protected boolean toggleChecked(final int position) {
|
||||
if (ICabHolder != null) {
|
||||
I identifier = getIdentifier(position);
|
||||
if (identifier == null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void clearChecked() {
|
||||
checked.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
if (!checked.remove(identifier)) {
|
||||
checked.add(identifier);
|
||||
}
|
||||
|
||||
private void updateCab() {
|
||||
if (cabHolder != null) {
|
||||
if (cab == null || !cab.isActive()) {
|
||||
cab = cabHolder.openCab(menuRes, this);
|
||||
}
|
||||
final int size = checked.size();
|
||||
if (size <= 0) {
|
||||
cab.finish();
|
||||
} else if (size == 1) {
|
||||
cab.setTitle(getName(checked.get(0)));
|
||||
} else {
|
||||
cab.setTitle(context.getString(R.string.x_selected, size));
|
||||
}
|
||||
}
|
||||
notifyItemChanged(position);
|
||||
updateCab();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void clearChecked() {
|
||||
checked.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void updateCab() {
|
||||
if (ICabHolder != null) {
|
||||
if (cab == null || !cab.isActive()) {
|
||||
cab = ICabHolder.openCab(menuRes, this);
|
||||
}
|
||||
final int size = checked.size();
|
||||
if (size <= 0) {
|
||||
cab.finish();
|
||||
} else if (size == 1) {
|
||||
cab.setTitle(getName(checked.get(0)));
|
||||
} else {
|
||||
cab.setTitle(context.getString(R.string.x_selected, size));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,126 +16,104 @@ package io.github.muntashirakon.music.adapter.base;
|
|||
|
||||
import android.graphics.Color;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import io.github.muntashirakon.music.R;
|
||||
import com.google.android.material.card.MaterialCardView;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractDraggableSwipeableItemViewHolder;
|
||||
|
||||
import io.github.muntashirakon.music.R;
|
||||
|
||||
public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHolder
|
||||
implements View.OnLongClickListener, View.OnClickListener {
|
||||
implements View.OnLongClickListener, View.OnClickListener {
|
||||
|
||||
@Nullable
|
||||
public View dragView;
|
||||
@Nullable public View dragView;
|
||||
|
||||
@Nullable
|
||||
public View dummyContainer;
|
||||
@Nullable public View dummyContainer;
|
||||
|
||||
@Nullable
|
||||
public ImageView image;
|
||||
@Nullable
|
||||
public ImageView artistImage;
|
||||
@Nullable public ImageView image;
|
||||
|
||||
@Nullable
|
||||
public ImageView playerImage;
|
||||
@Nullable public ImageView artistImage;
|
||||
|
||||
@Nullable
|
||||
public ViewGroup imageContainer;
|
||||
@Nullable public ImageView playerImage;
|
||||
|
||||
@Nullable
|
||||
public MaterialCardView imageContainerCard;
|
||||
@Nullable public MaterialCardView imageContainerCard;
|
||||
|
||||
@Nullable
|
||||
public TextView imageText;
|
||||
@Nullable public TextView imageText;
|
||||
|
||||
@Nullable
|
||||
public MaterialCardView imageTextContainer;
|
||||
@Nullable public MaterialCardView imageTextContainer;
|
||||
|
||||
@Nullable
|
||||
public View mask;
|
||||
@Nullable public View mask;
|
||||
|
||||
@Nullable
|
||||
public View menu;
|
||||
@Nullable public View menu;
|
||||
|
||||
@Nullable
|
||||
public View paletteColorContainer;
|
||||
@Nullable public View paletteColorContainer;
|
||||
|
||||
@Nullable
|
||||
public ImageButton playSongs;
|
||||
@Nullable public ImageButton playSongs;
|
||||
|
||||
@Nullable
|
||||
public RecyclerView recyclerView;
|
||||
@Nullable public RecyclerView recyclerView;
|
||||
|
||||
@Nullable
|
||||
public TextView text;
|
||||
@Nullable public TextView text;
|
||||
|
||||
@Nullable
|
||||
public TextView time;
|
||||
@Nullable public TextView text2;
|
||||
|
||||
@Nullable
|
||||
public TextView title;
|
||||
@Nullable public TextView time;
|
||||
|
||||
public MediaEntryViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
title = itemView.findViewById(R.id.title);
|
||||
text = itemView.findViewById(R.id.text);
|
||||
@Nullable public TextView title;
|
||||
|
||||
image = itemView.findViewById(R.id.image);
|
||||
artistImage = itemView.findViewById(R.id.artistImage);
|
||||
playerImage = itemView.findViewById(R.id.player_image);
|
||||
time = itemView.findViewById(R.id.time);
|
||||
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);
|
||||
|
||||
imageText = itemView.findViewById(R.id.imageText);
|
||||
imageContainer = itemView.findViewById(R.id.imageContainer);
|
||||
imageTextContainer = itemView.findViewById(R.id.imageTextContainer);
|
||||
imageContainerCard = itemView.findViewById(R.id.imageContainerCard);
|
||||
image = itemView.findViewById(R.id.image);
|
||||
artistImage = itemView.findViewById(R.id.artistImage);
|
||||
playerImage = itemView.findViewById(R.id.player_image);
|
||||
time = itemView.findViewById(R.id.time);
|
||||
|
||||
menu = itemView.findViewById(R.id.menu);
|
||||
dragView = itemView.findViewById(R.id.drag_view);
|
||||
paletteColorContainer = itemView.findViewById(R.id.paletteColorContainer);
|
||||
recyclerView = itemView.findViewById(R.id.recycler_view);
|
||||
mask = itemView.findViewById(R.id.mask);
|
||||
playSongs = itemView.findViewById(R.id.playSongs);
|
||||
dummyContainer = itemView.findViewById(R.id.dummy_view);
|
||||
imageText = itemView.findViewById(R.id.imageText);
|
||||
imageTextContainer = itemView.findViewById(R.id.imageTextContainer);
|
||||
imageContainerCard = itemView.findViewById(R.id.imageContainerCard);
|
||||
|
||||
if (imageContainerCard != null) {
|
||||
imageContainerCard.setCardBackgroundColor(Color.TRANSPARENT);
|
||||
}
|
||||
itemView.setOnClickListener(this);
|
||||
itemView.setOnLongClickListener(this);
|
||||
menu = itemView.findViewById(R.id.menu);
|
||||
dragView = itemView.findViewById(R.id.drag_view);
|
||||
paletteColorContainer = itemView.findViewById(R.id.paletteColorContainer);
|
||||
recyclerView = itemView.findViewById(R.id.recycler_view);
|
||||
mask = itemView.findViewById(R.id.mask);
|
||||
playSongs = itemView.findViewById(R.id.playSongs);
|
||||
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);
|
||||
}*/
|
||||
@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);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter.playlist
|
||||
|
||||
import android.view.LayoutInflater
|
||||
|
@ -49,4 +63,4 @@ class LegacyPlaylistAdapter(
|
|||
interface PlaylistClickListener {
|
||||
fun onPlaylistClick(playlist: Playlist)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,32 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter.playlist
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.AsyncTask
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import io.github.muntashirakon.music.EXTRA_PLAYLIST
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
||||
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
|
||||
|
@ -27,22 +38,25 @@ import io.github.muntashirakon.music.extensions.hide
|
|||
import io.github.muntashirakon.music.extensions.show
|
||||
import io.github.muntashirakon.music.helper.menu.PlaylistMenuHelper
|
||||
import io.github.muntashirakon.music.helper.menu.SongsMenuHelper
|
||||
import io.github.muntashirakon.music.interfaces.CabHolder
|
||||
import io.github.muntashirakon.music.model.Playlist
|
||||
import io.github.muntashirakon.music.interfaces.ICabHolder
|
||||
import io.github.muntashirakon.music.interfaces.IPlaylistClickListener
|
||||
import io.github.muntashirakon.music.model.Song
|
||||
import io.github.muntashirakon.music.repository.PlaylistSongsLoader
|
||||
import io.github.muntashirakon.music.util.AutoGeneratedPlaylistBitmap
|
||||
import io.github.muntashirakon.music.util.MusicUtil
|
||||
import io.github.muntashirakon.music.util.RetroColorUtil
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class PlaylistAdapter(
|
||||
private val activity: FragmentActivity,
|
||||
var dataSet: List<PlaylistWithSongs>,
|
||||
private var dataSet: List<PlaylistWithSongs>,
|
||||
private var itemLayoutRes: Int,
|
||||
cabHolder: CabHolder?
|
||||
ICabHolder: ICabHolder?,
|
||||
private val listener: IPlaylistClickListener
|
||||
) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, PlaylistWithSongs>(
|
||||
activity,
|
||||
cabHolder,
|
||||
ICabHolder,
|
||||
R.menu.menu_playlists_selection
|
||||
) {
|
||||
|
||||
|
@ -56,7 +70,7 @@ class PlaylistAdapter(
|
|||
}
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
return dataSet[position].playlistEntity.playListId.toLong()
|
||||
return dataSet[position].playlistEntity.playListId
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
|
@ -88,7 +102,7 @@ class PlaylistAdapter(
|
|||
} else {
|
||||
holder.menu?.show()
|
||||
}
|
||||
//PlaylistBitmapLoader(this, holder, playlist).execute()
|
||||
//playlistBitmapLoader(activity, holder, playlist)
|
||||
}
|
||||
|
||||
private fun getIconRes(): Drawable = TintHelper.createTintedDrawable(
|
||||
|
@ -158,10 +172,8 @@ class PlaylistAdapter(
|
|||
if (isInQuickSelectMode) {
|
||||
toggleChecked(layoutPosition)
|
||||
} else {
|
||||
activity.findNavController(R.id.fragment_container).navigate(
|
||||
R.id.playlistDetailsFragment,
|
||||
bundleOf(EXTRA_PLAYLIST to dataSet[layoutPosition])
|
||||
)
|
||||
ViewCompat.setTransitionName(itemView, "playlist")
|
||||
listener.onPlaylistClick(dataSet[layoutPosition], itemView)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,28 +183,35 @@ class PlaylistAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
class PlaylistBitmapLoader(
|
||||
private var adapter: PlaylistAdapter,
|
||||
private var viewHolder: ViewHolder,
|
||||
private var playlist: Playlist
|
||||
) : AsyncTask<Void, Void, Bitmap>() {
|
||||
private fun playlistBitmapLoader(
|
||||
activity: FragmentActivity,
|
||||
viewHolder: ViewHolder,
|
||||
playlist: PlaylistWithSongs
|
||||
) {
|
||||
|
||||
override fun doInBackground(vararg params: Void?): Bitmap {
|
||||
val songs = PlaylistSongsLoader.getPlaylistSongList(adapter.activity, playlist)
|
||||
return AutoGeneratedPlaylistBitmap.getBitmap(adapter.activity, songs, false, false)
|
||||
activity.lifecycleScope.launch(IO) {
|
||||
val songs = playlist.songs.toSongs()
|
||||
val bitmap = AutoGeneratedPlaylistBitmap.getBitmap(activity, songs, false, false)
|
||||
withContext(Main) { viewHolder.image?.setImageBitmap(bitmap) }
|
||||
}
|
||||
|
||||
override fun onPostExecute(result: Bitmap?) {
|
||||
super.onPostExecute(result)
|
||||
viewHolder.image?.setImageBitmap(result)
|
||||
val color = RetroColorUtil.getColor(
|
||||
RetroColorUtil.generatePalette(
|
||||
result
|
||||
),
|
||||
ATHUtil.resolveColor(adapter.activity, R.attr.colorSurface)
|
||||
)
|
||||
viewHolder.paletteColorContainer?.setBackgroundColor(color)
|
||||
}
|
||||
/*
|
||||
override fun doInBackground(vararg params: Void?): Bitmap {
|
||||
val songs = playlist.songs.toSongs()
|
||||
return AutoGeneratedPlaylistBitmap.getBitmap(activity, songs, false, false)
|
||||
}
|
||||
|
||||
override fun onPostExecute(result: Bitmap?) {
|
||||
super.onPostExecute(result)
|
||||
viewHolder.image?.setImageBitmap(result)
|
||||
val color = RetroColorUtil.getColor(
|
||||
RetroColorUtil.generatePalette(
|
||||
result
|
||||
),
|
||||
ATHUtil.resolveColor(activity, R.attr.colorSurface)
|
||||
)
|
||||
viewHolder.paletteColorContainer?.setBackgroundColor(color)
|
||||
}*/
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -1,21 +1,35 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter.song
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
||||
import io.github.muntashirakon.music.interfaces.CabHolder
|
||||
import io.github.muntashirakon.music.interfaces.ICabHolder
|
||||
import io.github.muntashirakon.music.model.Song
|
||||
|
||||
abstract class AbsOffsetSongAdapter(
|
||||
activity: AppCompatActivity,
|
||||
activity: FragmentActivity,
|
||||
dataSet: MutableList<Song>,
|
||||
@LayoutRes itemLayoutRes: Int,
|
||||
cabHolder: CabHolder?
|
||||
) : SongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {
|
||||
ICabHolder: ICabHolder?
|
||||
) : SongAdapter(activity, dataSet, itemLayoutRes, ICabHolder) {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongAdapter.ViewHolder {
|
||||
if (viewType == OFFSET_ITEM) {
|
||||
|
@ -76,4 +90,4 @@ abstract class AbsOffsetSongAdapter(
|
|||
const val OFFSET_ITEM = 0
|
||||
const val SONG = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter.song
|
||||
|
||||
import android.view.MenuItem
|
||||
|
@ -9,7 +23,7 @@ import io.github.muntashirakon.music.db.PlaylistEntity
|
|||
import io.github.muntashirakon.music.db.toSongEntity
|
||||
import io.github.muntashirakon.music.db.toSongs
|
||||
import io.github.muntashirakon.music.dialogs.RemoveSongFromPlaylistDialog
|
||||
import io.github.muntashirakon.music.interfaces.CabHolder
|
||||
import io.github.muntashirakon.music.interfaces.ICabHolder
|
||||
import io.github.muntashirakon.music.model.PlaylistSong
|
||||
import io.github.muntashirakon.music.model.Song
|
||||
import io.github.muntashirakon.music.util.ViewUtil
|
||||
|
@ -23,13 +37,13 @@ class OrderablePlaylistSongAdapter(
|
|||
activity: FragmentActivity,
|
||||
dataSet: ArrayList<Song>,
|
||||
itemLayoutRes: Int,
|
||||
cabHolder: CabHolder?,
|
||||
ICabHolder: ICabHolder?,
|
||||
private val onMoveItemListener: OnMoveItemListener?
|
||||
) : SongAdapter(
|
||||
activity,
|
||||
dataSet,
|
||||
itemLayoutRes,
|
||||
cabHolder
|
||||
ICabHolder
|
||||
), DraggableItemAdapter<OrderablePlaylistSongAdapter.ViewHolder> {
|
||||
|
||||
init {
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter.song
|
||||
|
||||
import android.view.MenuItem
|
||||
|
@ -5,6 +19,8 @@ import android.view.View
|
|||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
|
||||
import io.github.muntashirakon.music.glide.SongGlideRequest
|
||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote.isPlaying
|
||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote.playNextSong
|
||||
|
@ -12,6 +28,8 @@ import io.github.muntashirakon.music.helper.MusicPlayerRemote.removeFromQueue
|
|||
import io.github.muntashirakon.music.model.Song
|
||||
import io.github.muntashirakon.music.util.MusicUtil
|
||||
import io.github.muntashirakon.music.util.ViewUtil
|
||||
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
|
||||
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
|
||||
|
@ -41,8 +59,8 @@ class PlayingQueueAdapter(
|
|||
|
||||
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
|
||||
super.onBindViewHolder(holder, position)
|
||||
holder.imageText?.text = (position - current).toString()
|
||||
holder.time?.text = MusicUtil.getReadableDurationString(dataSet[position].duration)
|
||||
val song = dataSet[position]
|
||||
holder.time?.text = MusicUtil.getReadableDurationString(song.duration)
|
||||
if (holder.itemViewType == HISTORY || holder.itemViewType == CURRENT) {
|
||||
setAlpha(holder, 0.5f)
|
||||
}
|
||||
|
@ -58,7 +76,17 @@ class PlayingQueueAdapter(
|
|||
}
|
||||
|
||||
override fun loadAlbumCover(song: Song, holder: SongAdapter.ViewHolder) {
|
||||
// We don't want to load it in this adapter
|
||||
if (holder.image == null) {
|
||||
return
|
||||
}
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), song)
|
||||
.checkIgnoreMediaStore(activity)
|
||||
.generatePalette(activity).build()
|
||||
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
||||
override fun onColorReady(colors: MediaNotificationProcessor) {
|
||||
//setColors(colors, holder)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun swapDataSet(dataSet: List<Song>, position: Int) {
|
||||
|
@ -76,7 +104,6 @@ class PlayingQueueAdapter(
|
|||
holder.image?.alpha = alpha
|
||||
holder.title?.alpha = alpha
|
||||
holder.text?.alpha = alpha
|
||||
holder.imageText?.alpha = alpha
|
||||
holder.paletteColorContainer?.alpha = alpha
|
||||
holder.dragView?.alpha = alpha
|
||||
holder.menu?.alpha = alpha
|
||||
|
@ -129,7 +156,6 @@ class PlayingQueueAdapter(
|
|||
}
|
||||
|
||||
init {
|
||||
imageText?.visibility = View.VISIBLE
|
||||
dragView?.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
|
@ -173,7 +199,7 @@ class PlayingQueueAdapter(
|
|||
}
|
||||
|
||||
override fun onGetSwipeReactionType(holder: ViewHolder, position: Int, x: Int, y: Int): Int {
|
||||
return if (onCheckCanStartDrag(holder!!, position, x, y)) {
|
||||
return if (onCheckCanStartDrag(holder, position, x, y)) {
|
||||
SwipeableItemConstants.REACTION_CAN_NOT_SWIPE_BOTH_H
|
||||
} else {
|
||||
SwipeableItemConstants.REACTION_CAN_SWIPE_BOTH_H
|
||||
|
@ -196,17 +222,17 @@ class PlayingQueueAdapter(
|
|||
private val isPlaying: Boolean = MusicPlayerRemote.isPlaying
|
||||
private val songProgressMillis = 0
|
||||
override fun onPerformAction() {
|
||||
//currentlyShownSnackbar = null
|
||||
// currentlyShownSnackbar = null
|
||||
}
|
||||
|
||||
override fun onSlideAnimationEnd() {
|
||||
//initializeSnackBar(adapter, position, activity, isPlaying)
|
||||
// initializeSnackBar(adapter, position, activity, isPlaying)
|
||||
songToRemove = adapter.dataSet[position]
|
||||
//If song removed was the playing song, then play the next song
|
||||
// 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
|
||||
// Swipe animation is much smoother when we do the heavy lifting after it's completed
|
||||
adapter.setSongToRemove(songToRemove!!)
|
||||
removeFromQueue(songToRemove!!)
|
||||
}
|
||||
|
|
|
@ -1,23 +1,37 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter.song
|
||||
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.navigation.findNavController
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import io.github.muntashirakon.music.EXTRA_ALBUM_ID
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
||||
import io.github.muntashirakon.music.interfaces.CabHolder
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import io.github.muntashirakon.music.db.PlaylistEntity
|
||||
import io.github.muntashirakon.music.db.toSongEntity
|
||||
import io.github.muntashirakon.music.dialogs.RemoveSongFromPlaylistDialog
|
||||
import io.github.muntashirakon.music.interfaces.ICabHolder
|
||||
import io.github.muntashirakon.music.model.Song
|
||||
|
||||
open class PlaylistSongAdapter(
|
||||
activity: AppCompatActivity,
|
||||
private val playlist: PlaylistEntity,
|
||||
activity: FragmentActivity,
|
||||
dataSet: MutableList<Song>,
|
||||
itemLayoutRes: Int,
|
||||
cabHolder: CabHolder?
|
||||
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {
|
||||
ICabHolder: ICabHolder?
|
||||
) : SongAdapter(activity, dataSet, itemLayoutRes, ICabHolder) {
|
||||
|
||||
init {
|
||||
this.setMultiSelectMenuRes(R.menu.menu_cannot_delete_single_songs_playlist_songs_selection)
|
||||
|
@ -27,45 +41,23 @@ open class PlaylistSongAdapter(
|
|||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
viewHolder.shuffleAction?.let {
|
||||
it.setOnClickListener {
|
||||
MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
super.onBindViewHolder(holder, position - 1)
|
||||
}
|
||||
}
|
||||
|
||||
open inner class ViewHolder(itemView: View) : AbsOffsetSongAdapter.ViewHolder(itemView) {
|
||||
|
||||
val playAction: MaterialButton? = itemView.findViewById(R.id.playAction)
|
||||
val shuffleAction: MaterialButton? = itemView.findViewById(R.id.shuffleAction)
|
||||
open inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) {
|
||||
|
||||
override var songMenuRes: Int
|
||||
get() = R.menu.menu_item_cannot_delete_single_songs_playlist_song
|
||||
get() = R.menu.menu_item_playlist_song
|
||||
set(value) {
|
||||
super.songMenuRes = value
|
||||
}
|
||||
|
||||
override fun onSongMenuItemClick(item: MenuItem): Boolean {
|
||||
if (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
|
||||
when (item.itemId) {
|
||||
R.id.action_remove_from_playlist -> {
|
||||
RemoveSongFromPlaylistDialog.create(song.toSongEntity(playlist.playListId))
|
||||
.show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST")
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onSongMenuItemClick(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,24 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter.song
|
||||
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
||||
import io.github.muntashirakon.music.interfaces.CabHolder
|
||||
import io.github.muntashirakon.music.interfaces.ICabHolder
|
||||
import io.github.muntashirakon.music.model.Song
|
||||
import com.google.android.material.button.MaterialButton
|
||||
|
||||
|
@ -12,8 +26,8 @@ class ShuffleButtonSongAdapter(
|
|||
activity: AppCompatActivity,
|
||||
dataSet: MutableList<Song>,
|
||||
itemLayoutRes: Int,
|
||||
cabHolder: CabHolder?
|
||||
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {
|
||||
ICabHolder: ICabHolder?
|
||||
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, ICabHolder) {
|
||||
|
||||
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
||||
return ViewHolder(view)
|
||||
|
@ -49,4 +63,4 @@ class ShuffleButtonSongAdapter(
|
|||
super.onClick(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,23 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter.song
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import io.github.muntashirakon.music.interfaces.CabHolder
|
||||
import io.github.muntashirakon.music.interfaces.ICabHolder
|
||||
import io.github.muntashirakon.music.model.Song
|
||||
import io.github.muntashirakon.music.util.MusicUtil
|
||||
import java.util.*
|
||||
|
@ -12,8 +26,8 @@ class SimpleSongAdapter(
|
|||
context: FragmentActivity,
|
||||
songs: ArrayList<Song>,
|
||||
layoutRes: Int,
|
||||
cabHolder: CabHolder?
|
||||
) : SongAdapter(context, songs, layoutRes, cabHolder) {
|
||||
ICabHolder: ICabHolder?
|
||||
) : SongAdapter(context, songs, layoutRes, ICabHolder) {
|
||||
|
||||
override fun swapDataSet(dataSet: List<Song>) {
|
||||
this.dataSet = dataSet.toMutableList()
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.adapter.song
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
|
@ -7,10 +21,9 @@ import android.view.MenuItem
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.navigation.findNavController
|
||||
import com.afollestad.materialcab.MaterialCab
|
||||
import com.bumptech.glide.Glide
|
||||
import io.github.muntashirakon.music.EXTRA_ALBUM_ID
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
||||
|
@ -23,11 +36,13 @@ import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
|||
import io.github.muntashirakon.music.helper.SortOrder
|
||||
import io.github.muntashirakon.music.helper.menu.SongMenuHelper
|
||||
import io.github.muntashirakon.music.helper.menu.SongsMenuHelper
|
||||
import io.github.muntashirakon.music.interfaces.CabHolder
|
||||
import io.github.muntashirakon.music.interfaces.ICabHolder
|
||||
import io.github.muntashirakon.music.model.Song
|
||||
import io.github.muntashirakon.music.util.MusicUtil
|
||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
|
||||
import com.afollestad.materialcab.MaterialCab
|
||||
import com.bumptech.glide.Glide
|
||||
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||
|
||||
/**
|
||||
|
@ -38,11 +53,11 @@ open class SongAdapter(
|
|||
protected val activity: FragmentActivity,
|
||||
var dataSet: MutableList<Song>,
|
||||
protected var itemLayoutRes: Int,
|
||||
cabHolder: CabHolder?,
|
||||
ICabHolder: ICabHolder?,
|
||||
showSectionName: Boolean = true
|
||||
) : AbsMultiSelectAdapter<SongAdapter.ViewHolder, Song>(
|
||||
activity,
|
||||
cabHolder,
|
||||
ICabHolder,
|
||||
R.menu.menu_media_selection
|
||||
), MaterialCab.Callback, PopupTextProvider {
|
||||
|
||||
|
@ -59,7 +74,7 @@ open class SongAdapter(
|
|||
}
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
return dataSet[position].id.toLong()
|
||||
return dataSet[position].id
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
|
@ -87,6 +102,7 @@ open class SongAdapter(
|
|||
}
|
||||
holder.title?.text = getSongTitle(song)
|
||||
holder.text?.text = getSongText(song)
|
||||
holder.text2?.text = getSongText(song)
|
||||
loadAlbumCover(song, holder)
|
||||
}
|
||||
|
||||
|
@ -121,6 +137,10 @@ open class SongAdapter(
|
|||
return song.artistName
|
||||
}
|
||||
|
||||
private fun getSongText2(song: Song): String? {
|
||||
return song.albumName
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return dataSet.size
|
||||
}
|
||||
|
@ -157,7 +177,6 @@ open class SongAdapter(
|
|||
get() = dataSet[layoutPosition]
|
||||
|
||||
init {
|
||||
setImageTransitionName(activity.getString(R.string.transition_album_art))
|
||||
menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
|
||||
override val song: Song
|
||||
get() = this@ViewHolder.song
|
||||
|
@ -172,7 +191,7 @@ open class SongAdapter(
|
|||
}
|
||||
|
||||
protected open fun onSongMenuItemClick(item: MenuItem): Boolean {
|
||||
if (image != null && image!!.visibility == View.VISIBLE) {
|
||||
if (image != null && image!!.isVisible) {
|
||||
when (item.itemId) {
|
||||
R.id.action_go_to_album -> {
|
||||
activity.findNavController(R.id.fragment_container)
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.appshortcuts
|
||||
|
||||
import android.content.Context
|
||||
|
@ -60,7 +60,10 @@ object AppShortcutIconGenerator {
|
|||
}
|
||||
|
||||
private fun generateThemedIcon(
|
||||
context: Context, iconId: Int, foregroundColor: Int, backgroundColor: Int
|
||||
context: Context,
|
||||
iconId: Int,
|
||||
foregroundColor: Int,
|
||||
backgroundColor: Int
|
||||
): Icon {
|
||||
// Get and tint foreground and background drawables
|
||||
val vectorDrawable = RetroUtil.getTintedVectorDrawable(context, iconId, foregroundColor)
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.appshortcuts
|
||||
|
||||
import android.app.Activity
|
||||
|
@ -20,6 +20,7 @@ import android.os.Bundle
|
|||
import io.github.muntashirakon.music.appshortcuts.shortcuttype.LastAddedShortcutType
|
||||
import io.github.muntashirakon.music.appshortcuts.shortcuttype.ShuffleAllShortcutType
|
||||
import io.github.muntashirakon.music.appshortcuts.shortcuttype.TopTracksShortcutType
|
||||
import io.github.muntashirakon.music.extensions.extraNotNull
|
||||
import io.github.muntashirakon.music.model.Playlist
|
||||
import io.github.muntashirakon.music.model.smartplaylist.LastAddedPlaylist
|
||||
import io.github.muntashirakon.music.model.smartplaylist.ShuffleAllPlaylist
|
||||
|
@ -31,16 +32,7 @@ class AppShortcutLauncherActivity : Activity() {
|
|||
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
var shortcutType = SHORTCUT_TYPE_NONE
|
||||
|
||||
// Set shortcutType from the intent extras
|
||||
val extras = intent.extras
|
||||
if (extras != null) {
|
||||
shortcutType = extras.getInt(KEY_SHORTCUT_TYPE, SHORTCUT_TYPE_NONE)
|
||||
}
|
||||
|
||||
when (shortcutType) {
|
||||
when (extraNotNull(KEY_SHORTCUT_TYPE, SHORTCUT_TYPE_NONE).value) {
|
||||
SHORTCUT_TYPE_SHUFFLE_ALL -> {
|
||||
startServiceWithPlaylist(
|
||||
SHUFFLE_MODE_SHUFFLE, ShuffleAllPlaylist()
|
||||
|
@ -78,9 +70,9 @@ class AppShortcutLauncherActivity : Activity() {
|
|||
|
||||
companion object {
|
||||
const val KEY_SHORTCUT_TYPE = "io.github.muntashirakon.Music.appshortcuts.ShortcutType"
|
||||
const val SHORTCUT_TYPE_SHUFFLE_ALL = 0
|
||||
const val SHORTCUT_TYPE_TOP_TRACKS = 1
|
||||
const val SHORTCUT_TYPE_LAST_ADDED = 2
|
||||
const val SHORTCUT_TYPE_NONE = 4
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.appshortcuts
|
||||
|
||||
import android.annotation.TargetApi
|
||||
|
@ -32,16 +32,16 @@ class DynamicShortcutManager(private val context: Context) {
|
|||
this.context.getSystemService(ShortcutManager::class.java)
|
||||
|
||||
private val defaultShortcuts: List<ShortcutInfo>
|
||||
get() = Arrays.asList(
|
||||
get() = listOf(
|
||||
ShuffleAllShortcutType(context).shortcutInfo,
|
||||
TopTracksShortcutType(context).shortcutInfo,
|
||||
LastAddedShortcutType(context).shortcutInfo
|
||||
)
|
||||
|
||||
fun initDynamicShortcuts() {
|
||||
//if (shortcutManager.dynamicShortcuts.size == 0) {
|
||||
// if (shortcutManager.dynamicShortcuts.size == 0) {
|
||||
shortcutManager.dynamicShortcuts = defaultShortcuts
|
||||
//}
|
||||
// }
|
||||
}
|
||||
|
||||
fun updateDynamicShortcuts() {
|
||||
|
@ -58,8 +58,12 @@ class DynamicShortcutManager(private val context: Context) {
|
|||
icon: Icon,
|
||||
intent: Intent
|
||||
): ShortcutInfo {
|
||||
return ShortcutInfo.Builder(context, id).setShortLabel(shortLabel)
|
||||
.setLongLabel(longLabel).setIcon(icon).setIntent(intent).build()
|
||||
return ShortcutInfo.Builder(context, id)
|
||||
.setShortLabel(shortLabel)
|
||||
.setLongLabel(longLabel)
|
||||
.setIcon(icon)
|
||||
.setIntent(intent)
|
||||
.build()
|
||||
}
|
||||
|
||||
fun reportShortcutUsed(context: Context, shortcutId: String) {
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.appshortcuts.shortcuttype
|
||||
|
||||
import android.annotation.TargetApi
|
||||
|
@ -33,11 +33,11 @@ abstract class BaseShortcutType(internal var context: Context) {
|
|||
* @param shortcutType Describes the type of shortcut to create (ShuffleAll, TopTracks, custom playlist, etc.)
|
||||
* @return
|
||||
*/
|
||||
internal fun getPlaySongsIntent(shortcutType: Int): Intent {
|
||||
internal fun getPlaySongsIntent(shortcutType: Long): Intent {
|
||||
val intent = Intent(context, AppShortcutLauncherActivity::class.java)
|
||||
intent.action = Intent.ACTION_VIEW
|
||||
val b = Bundle()
|
||||
b.putInt(AppShortcutLauncherActivity.KEY_SHORTCUT_TYPE, shortcutType)
|
||||
b.putLong(AppShortcutLauncherActivity.KEY_SHORTCUT_TYPE, shortcutType)
|
||||
intent.putExtras(b)
|
||||
return intent
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.appshortcuts.shortcuttype
|
||||
|
||||
import android.annotation.TargetApi
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.appshortcuts.shortcuttype
|
||||
|
||||
import android.annotation.TargetApi
|
||||
|
@ -26,20 +26,16 @@ import io.github.muntashirakon.music.appshortcuts.AppShortcutLauncherActivity
|
|||
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))
|
||||
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() = BaseShortcutType.ID_PREFIX + "shuffle_all"
|
||||
get() = ID_PREFIX + "shuffle_all"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.appshortcuts.shortcuttype
|
||||
|
||||
import android.annotation.TargetApi
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.appwidgets
|
||||
|
||||
import android.app.PendingIntent
|
||||
|
@ -30,6 +30,7 @@ import io.github.muntashirakon.music.appwidgets.base.BaseAppWidget
|
|||
import io.github.muntashirakon.music.glide.SongGlideRequest
|
||||
import io.github.muntashirakon.music.service.MusicService
|
||||
import io.github.muntashirakon.music.service.MusicService.*
|
||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||
import io.github.muntashirakon.music.util.RetroUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.animation.GlideAnimation
|
||||
|
@ -193,8 +194,11 @@ class AppWidgetBig : BaseAppWidget() {
|
|||
* 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, true)
|
||||
val action = Intent(context, MainActivity::class.java)
|
||||
.putExtra(
|
||||
MainActivity.EXPAND_PANEL,
|
||||
PreferenceUtil.isExpandPanel
|
||||
)
|
||||
var pendingIntent: PendingIntent
|
||||
|
||||
val serviceName = ComponentName(context, MusicService::class.java)
|
||||
|
@ -229,6 +233,5 @@ class AppWidgetBig : BaseAppWidget() {
|
|||
}
|
||||
return mInstance!!
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.appwidgets
|
||||
|
||||
import android.app.PendingIntent
|
||||
|
@ -32,6 +32,7 @@ import io.github.muntashirakon.music.glide.palette.BitmapPaletteWrapper
|
|||
import io.github.muntashirakon.music.service.MusicService
|
||||
import io.github.muntashirakon.music.service.MusicService.*
|
||||
import io.github.muntashirakon.music.util.ImageUtil
|
||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||
import io.github.muntashirakon.music.util.RetroUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.animation.GlideAnimation
|
||||
|
@ -217,7 +218,11 @@ class AppWidgetCard : BaseAppWidget() {
|
|||
* Link up various button actions using [PendingIntent].
|
||||
*/
|
||||
private fun linkButtons(context: Context, views: RemoteViews) {
|
||||
val action: Intent = Intent(context, MainActivity::class.java).putExtra("expand", true)
|
||||
val action = Intent(context, MainActivity::class.java)
|
||||
.putExtra(
|
||||
MainActivity.EXPAND_PANEL,
|
||||
PreferenceUtil.isExpandPanel
|
||||
)
|
||||
var pendingIntent: PendingIntent
|
||||
|
||||
val serviceName = ComponentName(context, MusicService::class.java)
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.appwidgets
|
||||
|
||||
import android.app.PendingIntent
|
||||
|
@ -33,6 +33,7 @@ import io.github.muntashirakon.music.glide.palette.BitmapPaletteWrapper
|
|||
import io.github.muntashirakon.music.service.MusicService
|
||||
import io.github.muntashirakon.music.service.MusicService.*
|
||||
import io.github.muntashirakon.music.util.ImageUtil
|
||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||
import io.github.muntashirakon.music.util.RetroUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.animation.GlideAnimation
|
||||
|
@ -49,7 +50,6 @@ class AppWidgetClassic : BaseAppWidget() {
|
|||
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(
|
||||
|
@ -208,7 +208,11 @@ class AppWidgetClassic : BaseAppWidget() {
|
|||
* Link up various button actions using [PendingIntent].
|
||||
*/
|
||||
private fun linkButtons(context: Context, views: RemoteViews) {
|
||||
val action = Intent(context, MainActivity::class.java).putExtra("expand", true)
|
||||
val action = Intent(context, MainActivity::class.java)
|
||||
.putExtra(
|
||||
MainActivity.EXPAND_PANEL,
|
||||
PreferenceUtil.isExpandPanel
|
||||
)
|
||||
var pendingIntent: PendingIntent
|
||||
|
||||
val serviceName = ComponentName(context, MusicService::class.java)
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.appwidgets
|
||||
|
||||
import android.app.PendingIntent
|
||||
|
@ -31,6 +31,7 @@ import io.github.muntashirakon.music.glide.SongGlideRequest
|
|||
import io.github.muntashirakon.music.glide.palette.BitmapPaletteWrapper
|
||||
import io.github.muntashirakon.music.service.MusicService
|
||||
import io.github.muntashirakon.music.service.MusicService.*
|
||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||
import io.github.muntashirakon.music.util.RetroUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.animation.GlideAnimation
|
||||
|
@ -192,7 +193,11 @@ class AppWidgetSmall : BaseAppWidget() {
|
|||
* Link up various button actions using [PendingIntent].
|
||||
*/
|
||||
private fun linkButtons(context: Context, views: RemoteViews) {
|
||||
val action = Intent(context, MainActivity::class.java).putExtra("expand", true)
|
||||
val action = Intent(context, MainActivity::class.java)
|
||||
.putExtra(
|
||||
MainActivity.EXPAND_PANEL,
|
||||
PreferenceUtil.isExpandPanel
|
||||
)
|
||||
var pendingIntent: PendingIntent
|
||||
|
||||
val serviceName = ComponentName(context, MusicService::class.java)
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.appwidgets
|
||||
|
||||
import android.app.PendingIntent
|
||||
|
@ -28,6 +28,7 @@ import io.github.muntashirakon.music.activities.MainActivity
|
|||
import io.github.muntashirakon.music.appwidgets.base.BaseAppWidget
|
||||
import io.github.muntashirakon.music.service.MusicService
|
||||
import io.github.muntashirakon.music.service.MusicService.*
|
||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||
import io.github.muntashirakon.music.util.RetroUtil
|
||||
|
||||
class AppWidgetText : BaseAppWidget() {
|
||||
|
@ -77,7 +78,11 @@ class AppWidgetText : BaseAppWidget() {
|
|||
* Link up various button actions using [PendingIntent].
|
||||
*/
|
||||
private fun linkButtons(context: Context, views: RemoteViews) {
|
||||
val action = Intent(context, MainActivity::class.java).putExtra("expand", true)
|
||||
val action = Intent(context, MainActivity::class.java)
|
||||
.putExtra(
|
||||
MainActivity.EXPAND_PANEL,
|
||||
PreferenceUtil.isExpandPanel
|
||||
)
|
||||
var pendingIntent: PendingIntent
|
||||
|
||||
val serviceName = ComponentName(context, MusicService::class.java)
|
||||
|
@ -153,10 +158,7 @@ class AppWidgetText : BaseAppWidget() {
|
|||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
pushUpdate(service.applicationContext, appWidgetIds, appWidgetView)
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.appwidgets
|
||||
|
||||
import android.appwidget.AppWidgetManager
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.appwidgets.base
|
||||
|
||||
import android.app.PendingIntent
|
||||
|
@ -40,7 +40,9 @@ abstract class BaseAppWidget : AppWidgetProvider() {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
override fun onUpdate(
|
||||
context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray
|
||||
context: Context,
|
||||
appWidgetManager: AppWidgetManager,
|
||||
appWidgetIds: IntArray
|
||||
) {
|
||||
defaultAppWidget(context, appWidgetIds)
|
||||
val updateIntent = Intent(APP_WIDGET_UPDATE)
|
||||
|
@ -62,7 +64,9 @@ abstract class BaseAppWidget : AppWidgetProvider() {
|
|||
}
|
||||
|
||||
protected fun pushUpdate(
|
||||
context: Context, appWidgetIds: IntArray?, views: RemoteViews
|
||||
context: Context,
|
||||
appWidgetIds: IntArray?,
|
||||
views: RemoteViews
|
||||
) {
|
||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||
if (appWidgetIds != null) {
|
||||
|
@ -86,7 +90,9 @@ abstract class BaseAppWidget : AppWidgetProvider() {
|
|||
}
|
||||
|
||||
protected fun buildPendingIntent(
|
||||
context: Context, action: String, serviceName: ComponentName
|
||||
context: Context,
|
||||
action: String,
|
||||
serviceName: ComponentName
|
||||
): PendingIntent {
|
||||
val intent = Intent(action)
|
||||
intent.component = serviceName
|
||||
|
@ -169,7 +175,11 @@ abstract class BaseAppWidget : AppWidgetProvider() {
|
|||
}
|
||||
|
||||
protected fun composeRoundedRectPath(
|
||||
rect: RectF, tl: Float, tr: Float, bl: Float, br: Float
|
||||
rect: RectF,
|
||||
tl: Float,
|
||||
tr: Float,
|
||||
bl: Float,
|
||||
br: Float
|
||||
): Path {
|
||||
val path = Path()
|
||||
path.moveTo(rect.left + tl, rect.top)
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.db
|
||||
|
||||
import androidx.room.*
|
||||
|
@ -18,4 +32,4 @@ interface BlackListStoreDao {
|
|||
|
||||
@Query("SELECT * FROM BlackListStoreEntity")
|
||||
fun blackListPaths(): List<BlackListStoreEntity>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.db
|
||||
|
||||
import androidx.room.Entity
|
||||
|
@ -7,4 +21,4 @@ import androidx.room.PrimaryKey
|
|||
class BlackListStoreEntity(
|
||||
@PrimaryKey
|
||||
val path: String
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.db
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
|
@ -23,4 +37,4 @@ interface HistoryDao {
|
|||
|
||||
@Query("SELECT * FROM HistoryEntity ORDER BY time_played DESC LIMIT $HISTORY_LIMIT")
|
||||
fun observableHistorySongs(): LiveData<List<HistoryEntity>>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.db
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
|
@ -29,4 +43,4 @@ class HistoryEntity(
|
|||
val albumArtist: String?,
|
||||
@ColumnInfo(name = "time_played")
|
||||
val timePlayed: Long
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.db
|
||||
|
||||
import androidx.room.*
|
||||
|
@ -15,4 +29,4 @@ interface LyricsDao {
|
|||
|
||||
@Update
|
||||
fun updateLyrics(lyricsEntity: LyricsEntity)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.db
|
||||
|
||||
import androidx.room.Entity
|
||||
|
@ -7,4 +21,4 @@ import androidx.room.PrimaryKey
|
|||
class LyricsEntity(
|
||||
@PrimaryKey val songId: Int,
|
||||
val lyrics: String
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.db
|
||||
|
||||
import androidx.room.*
|
||||
|
@ -24,4 +38,4 @@ interface PlayCountDao {
|
|||
|
||||
@Query("UPDATE PlayCountEntity SET play_count = play_count + 1 WHERE id = :id")
|
||||
fun updateQuantity(id: Long)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.db
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
|
@ -31,4 +45,4 @@ class PlayCountEntity(
|
|||
val timePlayed: Long,
|
||||
@ColumnInfo(name = "play_count")
|
||||
var playCount: Int
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,10 +1,21 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.db
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.room.*
|
||||
import io.github.muntashirakon.music.db.PlaylistEntity
|
||||
import io.github.muntashirakon.music.db.PlaylistWithSongs
|
||||
import io.github.muntashirakon.music.db.SongEntity
|
||||
|
||||
@Dao
|
||||
interface PlaylistDao {
|
||||
|
@ -48,12 +59,9 @@ interface PlaylistDao {
|
|||
@Delete
|
||||
suspend fun deletePlaylistSongs(songs: List<SongEntity>)
|
||||
|
||||
|
||||
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id= :playlistId")
|
||||
fun favoritesSongsLiveData(playlistId: Long): LiveData<List<SongEntity>>
|
||||
|
||||
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id= :playlistId")
|
||||
fun favoritesSongs(playlistId: Long): List<SongEntity>
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.db
|
||||
|
||||
import android.os.Parcelable
|
||||
|
@ -14,4 +28,4 @@ class PlaylistEntity(
|
|||
val playListId: Long = 0,
|
||||
@ColumnInfo(name = "playlist_name")
|
||||
val playlistName: String
|
||||
) : Parcelable
|
||||
) : Parcelable
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.db
|
||||
|
||||
import android.os.Parcelable
|
||||
|
@ -14,4 +28,3 @@ data class PlaylistWithSongs(
|
|||
)
|
||||
val songs: List<SongEntity>
|
||||
) : Parcelable
|
||||
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.db
|
||||
|
||||
import androidx.room.Database
|
||||
|
@ -14,4 +28,4 @@ abstract class RetroDatabase : RoomDatabase() {
|
|||
abstract fun playCountDao(): PlayCountDao
|
||||
abstract fun historyDao(): HistoryDao
|
||||
abstract fun lyricsDao(): LyricsDao
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.db
|
||||
|
||||
import android.os.Parcelable
|
||||
|
@ -36,4 +50,3 @@ class SongEntity(
|
|||
@ColumnInfo(name = "album_artist")
|
||||
val albumArtist: String?
|
||||
) : Parcelable
|
||||
|
||||
|
|
|
@ -1,7 +1,27 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.db
|
||||
|
||||
import io.github.muntashirakon.music.model.Song
|
||||
|
||||
fun List<HistoryEntity>.fromHistoryToSongs(): List<Song> {
|
||||
return map {
|
||||
it.toSong()
|
||||
}
|
||||
}
|
||||
|
||||
fun List<SongEntity>.toSongs(): List<Song> {
|
||||
return map {
|
||||
it.toSong()
|
||||
|
|
|
@ -1,7 +1,22 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
|
@ -9,7 +24,6 @@ import io.github.muntashirakon.music.EXTRA_PLAYLISTS
|
|||
import io.github.muntashirakon.music.EXTRA_SONG
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.db.PlaylistEntity
|
||||
import io.github.muntashirakon.music.db.SongEntity
|
||||
import io.github.muntashirakon.music.db.toSongsEntity
|
||||
import io.github.muntashirakon.music.extensions.colorButtons
|
||||
import io.github.muntashirakon.music.extensions.extraNotNull
|
||||
|
@ -41,30 +55,39 @@ class AddToPlaylistDialog : DialogFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun playlistAdapter(playlists: List<String>): ArrayAdapter<String> {
|
||||
val adapter = ArrayAdapter<String>(requireContext(), R.layout.item_simple_text, R.id.title)
|
||||
adapter.addAll(playlists)
|
||||
return adapter
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val playlistEntities: List<PlaylistEntity> =
|
||||
extraNotNull<List<PlaylistEntity>>(EXTRA_PLAYLISTS).value
|
||||
val songs: List<Song> = extraNotNull<List<Song>>(EXTRA_SONG).value
|
||||
val playlistNames: MutableList<String> = mutableListOf()
|
||||
val playlistEntities = extraNotNull<List<PlaylistEntity>>(EXTRA_PLAYLISTS).value
|
||||
val songs = extraNotNull<List<Song>>(EXTRA_SONG).value
|
||||
val playlistNames = mutableListOf<String>()
|
||||
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()) { _, which ->
|
||||
.setAdapter(
|
||||
playlistAdapter(playlistNames)
|
||||
) { dialog, which ->
|
||||
if (which == 0) {
|
||||
CreatePlaylistDialog.create(songs)
|
||||
.show(requireActivity().supportFragmentManager, "Dialog")
|
||||
showCreateDialog(songs)
|
||||
} else {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val songEntities: List<SongEntity> =
|
||||
songs.toSongsEntity(playlistEntities[which - 1])
|
||||
val songEntities = songs.toSongsEntity(playlistEntities[which - 1])
|
||||
libraryViewModel.insertSongs(songEntities)
|
||||
libraryViewModel.forceReload(Playlists)
|
||||
}
|
||||
}
|
||||
dismiss()
|
||||
dialog.dismiss()
|
||||
}
|
||||
.create().colorButtons()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showCreateDialog(songs: List<Song>) {
|
||||
CreatePlaylistDialog.create(songs).show(requireActivity().supportFragmentManager, "Dialog")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,150 +7,149 @@ import android.os.Build;
|
|||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
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 io.github.muntashirakon.music.R;
|
||||
public class BlacklistFolderChooserDialog extends DialogFragment
|
||||
implements MaterialDialog.ListCallback {
|
||||
|
||||
public class BlacklistFolderChooserDialog extends DialogFragment implements MaterialDialog.ListCallback {
|
||||
String initialPath = Environment.getExternalStorageDirectory().getAbsolutePath();
|
||||
private File parentFolder;
|
||||
private File[] parentContents;
|
||||
private boolean canGoUp = false;
|
||||
private FolderCallback callback;
|
||||
|
||||
String initialPath = Environment.getExternalStorageDirectory().getAbsolutePath();
|
||||
private File parentFolder;
|
||||
private File[] parentContents;
|
||||
private boolean canGoUp = false;
|
||||
private FolderCallback callback;
|
||||
public static BlacklistFolderChooserDialog create() {
|
||||
return new BlacklistFolderChooserDialog();
|
||||
}
|
||||
|
||||
public static BlacklistFolderChooserDialog create() {
|
||||
return new BlacklistFolderChooserDialog();
|
||||
private String[] getContentsArray() {
|
||||
if (parentContents == null) {
|
||||
if (canGoUp) {
|
||||
return new String[] {".."};
|
||||
}
|
||||
return new String[] {};
|
||||
}
|
||||
|
||||
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;
|
||||
String[] results = new String[parentContents.length + (canGoUp ? 1 : 0)];
|
||||
if (canGoUp) {
|
||||
results[0] = "..";
|
||||
}
|
||||
|
||||
private File[] listFiles() {
|
||||
File[] contents = parentFolder.listFiles();
|
||||
List<File> 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;
|
||||
for (int i = 0; i < parentContents.length; i++) {
|
||||
results[canGoUp ? i + 1 : i] = parentContents[i].getName();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& ActivityCompat.checkSelfPermission(
|
||||
private File[] listFiles() {
|
||||
File[] contents = parentFolder.listFiles();
|
||||
List<File> 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;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& ActivityCompat.checkSelfPermission(
|
||||
requireActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
return new MaterialDialog.Builder(requireActivity())
|
||||
.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(requireContext())
|
||||
.title(parentFolder.getAbsolutePath())
|
||||
.items((CharSequence[]) getContentsArray())
|
||||
.itemsCallback(this)
|
||||
.autoDismiss(false)
|
||||
.onPositive((dialog, which) -> {
|
||||
callback.onFolderSelection(BlacklistFolderChooserDialog.this, parentFolder);
|
||||
dismiss();
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
return new MaterialDialog.Builder(requireActivity())
|
||||
.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(requireContext())
|
||||
.title(parentFolder.getAbsolutePath())
|
||||
.items((CharSequence[]) getContentsArray())
|
||||
.itemsCallback(this)
|
||||
.autoDismiss(false)
|
||||
.onPositive(
|
||||
(dialog, which) -> {
|
||||
callback.onFolderSelection(BlacklistFolderChooserDialog.this, parentFolder);
|
||||
dismiss();
|
||||
})
|
||||
.onNegative((materialDialog, dialogAction) -> dismiss())
|
||||
.positiveText(R.string.add_action)
|
||||
.negativeText(android.R.string.cancel);
|
||||
return builder.build();
|
||||
.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<File> {
|
||||
|
||||
@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();
|
||||
public int compare(File lhs, File rhs) {
|
||||
return lhs.getName().compareTo(rhs.getName());
|
||||
}
|
||||
|
||||
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<File> {
|
||||
|
||||
@Override
|
||||
public int compare(File lhs, File rhs) {
|
||||
return lhs.getName().compareTo(rhs.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
|
@ -26,7 +40,7 @@ import kotlinx.coroutines.launch
|
|||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
|
||||
class CreatePlaylistDialog : DialogFragment() {
|
||||
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
|
||||
private val io.github.muntashirakon.music by sharedViewModel<LibraryViewModel>()
|
||||
|
||||
companion object {
|
||||
fun create(song: Song): CreatePlaylistDialog {
|
||||
|
@ -54,17 +68,8 @@ class CreatePlaylistDialog : DialogFragment() {
|
|||
) { _, _ ->
|
||||
val playlistName = playlistView.text.toString()
|
||||
if (!TextUtils.isEmpty(playlistName)) {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
if (libraryViewModel.checkPlaylistExists(playlistName).isEmpty()) {
|
||||
val playlistId: Long =
|
||||
libraryViewModel.createPlaylist(PlaylistEntity(playlistName = playlistName))
|
||||
libraryViewModel.insertSongs(songs.map { it.toSongEntity(playlistId) })
|
||||
libraryViewModel.forceReload(Playlists)
|
||||
} else {
|
||||
Toast.makeText(requireContext(), "Playlist exists", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
io.github.muntashirakon.music.addToPlaylist(playlistName, songs)
|
||||
|
||||
} else {
|
||||
playlistContainer.error = "Playlist is can't be empty"
|
||||
}
|
||||
|
@ -72,4 +77,4 @@ class CreatePlaylistDialog : DialogFragment() {
|
|||
.create()
|
||||
.colorButtons()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
|
@ -65,5 +79,4 @@ class DeletePlaylistDialog : DialogFragment() {
|
|||
.create()
|
||||
.colorButtons()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
|
@ -67,4 +81,4 @@ class DeleteSongsDialog : DialogFragment() {
|
|||
.create()
|
||||
.colorButtons()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
|
@ -21,4 +35,4 @@ class ImportPlaylistDialog : DialogFragment() {
|
|||
.create()
|
||||
.colorButtons()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
package io.github.muntashirakon.music.dialogs
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import io.github.muntashirakon.music.R
|
||||
import io.github.muntashirakon.music.extensions.accentTextColor
|
||||
import io.github.muntashirakon.music.extensions.hide
|
||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
||||
import io.github.muntashirakon.music.network.Result
|
||||
import io.github.muntashirakon.music.repository.Repository
|
||||
import kotlinx.android.synthetic.main.lyrics_dialog.*
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
class LyricsDialog : DialogFragment() {
|
||||
override fun getTheme(): Int {
|
||||
return R.style.MaterialAlertDialogTheme
|
||||
}
|
||||
|
||||
private val repository by inject<Repository>()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.lyrics_dialog, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
dialogTitle.text = song.title
|
||||
syncedLyrics.accentTextColor()
|
||||
lifecycleScope.launch(IO) {
|
||||
val result: Result<String> = repository.lyrics(
|
||||
song.artistName,
|
||||
song.title
|
||||
)
|
||||
withContext(Main) {
|
||||
|
||||
when (result) {
|
||||
is Result.Error -> progressBar.hide()
|
||||
is Result.Loading -> println("Loading")
|
||||
is Result.Success -> {
|
||||
progressBar.hide()
|
||||
lyricsText.text = result.data
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
|
@ -12,7 +26,6 @@ import io.github.muntashirakon.music.extensions.colorButtons
|
|||
import io.github.muntashirakon.music.extensions.extraNotNull
|
||||
import io.github.muntashirakon.music.extensions.materialDialog
|
||||
import io.github.muntashirakon.music.fragments.LibraryViewModel
|
||||
import io.github.muntashirakon.music.fragments.ReloadType.Playlists
|
||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
|
||||
class RemoveSongFromPlaylistDialog : DialogFragment() {
|
||||
|
@ -60,10 +73,9 @@ class RemoveSongFromPlaylistDialog : DialogFragment() {
|
|||
.setMessage(pair.second)
|
||||
.setPositiveButton(R.string.remove_action) { _, _ ->
|
||||
libraryViewModel.deleteSongsInPlaylist(songs)
|
||||
libraryViewModel.forceReload(Playlists)
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.create()
|
||||
.colorButtons()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
|
@ -54,4 +68,4 @@ class RenamePlaylistDialog : DialogFragment() {
|
|||
.create()
|
||||
.colorButtons()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,21 @@
|
|||
/*
|
||||
* 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 io.github.muntashirakon.music.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
import android.media.MediaScannerConnection
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.core.os.bundleOf
|
||||
|
@ -18,7 +33,6 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
|
||||
class SavePlaylistDialog : DialogFragment() {
|
||||
companion object {
|
||||
fun create(playlistWithSongs: PlaylistWithSongs): SavePlaylistDialog {
|
||||
|
@ -33,9 +47,14 @@ class SavePlaylistDialog : DialogFragment() {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val playlistWithSongs: PlaylistWithSongs =
|
||||
extraNotNull<PlaylistWithSongs>(EXTRA_PLAYLIST).value
|
||||
val file = PlaylistsUtil.savePlaylistWithSongs(requireContext(), playlistWithSongs)
|
||||
val playlistWithSongs = extraNotNull<PlaylistWithSongs>(EXTRA_PLAYLIST).value
|
||||
val file = PlaylistsUtil.savePlaylistWithSongs(playlistWithSongs)
|
||||
MediaScannerConnection.scanFile(
|
||||
requireActivity(),
|
||||
arrayOf<String>(file.path),
|
||||
null
|
||||
) { _, _ ->
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
requireContext(),
|
||||
|
@ -52,4 +71,4 @@ class SavePlaylistDialog : DialogFragment() {
|
|||
.setView(R.layout.loading)
|
||||
.create().colorButtons()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
* 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 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 io.github.muntashirakon.music.dialogs
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
|
@ -130,7 +130,6 @@ class SleepTimerDialog : DialogFragment() {
|
|||
}
|
||||
.create()
|
||||
.colorButtons()
|
||||
|
||||
}
|
||||
|
||||
private fun updateTimeDisplayTime() {
|
||||
|
@ -173,4 +172,4 @@ class SleepTimerDialog : DialogFragment() {
|
|||
updateCancelButton()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue