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.
|
color from a color palette.
|
||||||
|
|
||||||
### 🏠 Home
|
### 🏠 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.
|
favorite songs. No other music player has this feature.
|
||||||
|
|
||||||
### 📦 Included Features
|
### 📦 Included Features
|
||||||
|
@ -49,33 +49,32 @@ favorite songs. No other music player has this feature.
|
||||||
- Driving Mode
|
- Driving Mode
|
||||||
- Headset/Bluetooth support
|
- Headset/Bluetooth support
|
||||||
- Music duration filter
|
- Music duration filter
|
||||||
- Folder support - Play song by folder
|
- Folder support - Play songs by folder
|
||||||
- Gapless playback
|
- Gapless playback
|
||||||
- Volume controls
|
- Volume controls
|
||||||
- Carousel effect for an album cover
|
- Carousel effect for album covers
|
||||||
- Home screen widgets
|
- Home screen widgets
|
||||||
- Lock screen playback controls
|
- Lock screen playback controls
|
||||||
- Lyrics screen (download and sync with music)
|
- Lyrics screen (download and sync with music)
|
||||||
- Sleep Timer
|
- Sleep timer
|
||||||
- Easy drag to sort playlist & play queue
|
- Easy drag to sort playlist & play queue
|
||||||
- Tag editor
|
- Tag editor
|
||||||
- Create, edit and import playlists
|
- Create, edit and import playlists
|
||||||
- Playing queue with reorder
|
- Playing queue with reorder
|
||||||
- User profile
|
- User profile
|
||||||
- 30 Languages support
|
- 30+ languages support
|
||||||
- Browse and play your music by songs, albums, artists, playlists and
|
- Browse and play your music by songs, albums, artists, playlists and
|
||||||
genre
|
genre
|
||||||
- Smart Auto Playlists - Recently played, most played and history
|
- 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
|
### 🗂️ License
|
||||||
|
|
||||||
Metro is released under the GNU General Public License v3.0
|
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
|
> Please note: Metro is an offline music player app. It doesn't support music downloading or online music streaming.
|
||||||
>doesn't support music downloading or online music streaming.
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ apply plugin: "androidx.navigation.safeargs.kotlin"
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 29
|
compileSdkVersion 29
|
||||||
buildToolsVersion = '30.0.1'
|
buildToolsVersion = '30.0.2'
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
|
@ -16,8 +16,8 @@ android {
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
|
||||||
applicationId 'io.github.muntashirakon.Music'
|
applicationId 'io.github.muntashirakon.Music'
|
||||||
versionCode 10445
|
versionCode 10503
|
||||||
versionName '3.5.11'
|
versionName '4.0.010'
|
||||||
|
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
}
|
}
|
||||||
|
@ -134,4 +134,6 @@ dependencies {
|
||||||
implementation 'me.jorgecastillo:androidcolorx:0.2.0'
|
implementation 'me.jorgecastillo:androidcolorx:0.2.0'
|
||||||
implementation 'org.jsoup:jsoup:1.11.1'
|
implementation 'org.jsoup:jsoup:1.11.1'
|
||||||
debugImplementation 'com.amitshekhar.android:debug-db:1.0.6'
|
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 java.lang.invoke.*
|
||||||
-dontwarn **$$Lambda$*
|
-dontwarn **$$Lambda$*
|
||||||
|
-dontwarn javax.annotation.**
|
||||||
|
|
||||||
# RetroFit
|
# RetroFit
|
||||||
-dontwarn retrofit.**
|
-dontwarn retrofit.**
|
||||||
-keep class retrofit.** { *; }
|
-keep class retrofit.** { *; }
|
||||||
-keepattributes Signature
|
|
||||||
-keepattributes Exceptions
|
|
||||||
-dontwarn javax.annotation.**
|
|
||||||
|
|
||||||
# Glide
|
# Glide
|
||||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||||
|
@ -41,14 +39,24 @@
|
||||||
public *;
|
public *;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# OkHttp
|
||||||
|
-keepattributes Signature
|
||||||
|
-keepattributes *Annotation*
|
||||||
|
-keep interface com.squareup.okhttp3.** { *; }
|
||||||
|
-dontwarn com.squareup.okhttp3.**
|
||||||
|
|
||||||
-dontwarn
|
#-dontwarn
|
||||||
-ignorewarnings
|
#-ignorewarnings
|
||||||
|
-dontshrink
|
||||||
|
-dontobfuscate
|
||||||
|
|
||||||
#-dontwarn android.support.v8.renderscript.*
|
-dontwarn org.jaudiotagger.**
|
||||||
#-keepclassmembers class android.support.v8.renderscript.RenderScript {
|
-keep class org.jaudiotagger.** { *; }
|
||||||
# native *** rsn*(...);
|
|
||||||
# native *** n*(...);
|
|
||||||
#}
|
|
||||||
|
|
||||||
#-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:letterSpacing">0.0125</item>
|
||||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="circleImageView" parent="">
|
||||||
|
<item name="cornerFamily">rounded</item>
|
||||||
|
<item name="cornerSize">5%</item>
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
|
@ -5,6 +5,7 @@
|
||||||
android:installLocation="auto">
|
android:installLocation="auto">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
<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.WAKE_LOCK" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
@ -116,11 +117,7 @@
|
||||||
<activity android:name=".activities.ShareInstagramStory" />
|
<activity android:name=".activities.ShareInstagramStory" />
|
||||||
<activity android:name=".activities.DriveModeActivity" />
|
<activity android:name=".activities.DriveModeActivity" />
|
||||||
<activity android:name=".activities.PermissionActivity" />
|
<activity android:name=".activities.PermissionActivity" />
|
||||||
|
<activity android:name=".activities.LockScreenActivity" />
|
||||||
<activity
|
|
||||||
android:name=".activities.LockScreenActivity"
|
|
||||||
android:noHistory="true"
|
|
||||||
android:showOnLockScreen="true" />
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".appshortcuts.AppShortcutLauncherActivity"
|
android:name=".appshortcuts.AppShortcutLauncherActivity"
|
||||||
|
|
|
@ -3,24 +3,30 @@
|
||||||
"name": "Hemanth Savarala",
|
"name": "Hemanth Savarala",
|
||||||
"summary": "Lead Developer & Designer",
|
"summary": "Lead Developer & Designer",
|
||||||
"link": "https://github.com/h4h13",
|
"link": "https://github.com/h4h13",
|
||||||
"profile_image": "https://i.imgur.com/AoVs9oj.jpg"
|
"image": "https://i.imgur.com/AoVs9oj.jpg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Lennart Glamann",
|
"name": "Lennart Glamann",
|
||||||
"summary": "Play Store banner and Images",
|
"summary": "Play Store Banner & Images",
|
||||||
"link": "https://t.me/FlixbusLennart",
|
"link": "https://t.me/FlixbusLennart",
|
||||||
"profile_image": "https://i.imgur.com/Q5Nsx1R.jpg"
|
"image": "https://i.imgur.com/Q5Nsx1R.jpg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Daksh P. Jain",
|
"name": "Daksh P. Jain",
|
||||||
"summary": "Support Representative & Moderator",
|
"summary": "Support Representative & Moderator",
|
||||||
"link": "https://daksh.eu.org",
|
"link": "https://daksh.eu.org",
|
||||||
"profile_image": "https://i.imgur.com/fnYpg65.jpg"
|
"image": "https://i.imgur.com/fnYpg65.jpg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Milind Goel",
|
"name": "Milind Goel",
|
||||||
"summary": "Support Representative & Moderator",
|
"summary": "Support Representative & Moderator",
|
||||||
"link": "https://t.me/MilindGoel15",
|
"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
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music
|
package io.github.muntashirakon.music
|
||||||
|
|
||||||
import androidx.multidex.MultiDexApplication
|
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
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music
|
package io.github.muntashirakon.music
|
||||||
|
|
||||||
import android.provider.BaseColumns
|
import android.provider.BaseColumns
|
||||||
|
@ -46,9 +45,9 @@ object Constants {
|
||||||
MediaStore.Audio.AudioColumns.ALBUM_ID, // 7
|
MediaStore.Audio.AudioColumns.ALBUM_ID, // 7
|
||||||
MediaStore.Audio.AudioColumns.ALBUM, // 8
|
MediaStore.Audio.AudioColumns.ALBUM, // 8
|
||||||
MediaStore.Audio.AudioColumns.ARTIST_ID, // 9
|
MediaStore.Audio.AudioColumns.ARTIST_ID, // 9
|
||||||
MediaStore.Audio.AudioColumns.ARTIST,// 10
|
MediaStore.Audio.AudioColumns.ARTIST, // 10
|
||||||
MediaStore.Audio.AudioColumns.COMPOSER,// 11
|
MediaStore.Audio.AudioColumns.COMPOSER, // 11
|
||||||
"album_artist"//12
|
"album_artist" // 12
|
||||||
)
|
)
|
||||||
const val NUMBER_OF_TOP_TRACKS = 99
|
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 NEW_BLUR_AMOUNT = "new_blur_amount"
|
||||||
const val TOGGLE_HEADSET = "toggle_headset"
|
const val TOGGLE_HEADSET = "toggle_headset"
|
||||||
const val GENERAL_THEME = "general_theme"
|
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 CIRCULAR_ALBUM_ART = "circular_album_art"
|
||||||
const val USER_NAME = "user_name"
|
const val USER_NAME = "user_name"
|
||||||
const val TOGGLE_FULL_SCREEN = "toggle_full_screen"
|
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 ADAPTIVE_COLOR_APP = "adaptive_color_app"
|
||||||
const val TOGGLE_SEPARATE_LINE = "toggle_separate_line"
|
const val TOGGLE_SEPARATE_LINE = "toggle_separate_line"
|
||||||
const val HOME_ARTIST_GRID_STYLE = "home_artist_grid_style"
|
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 TOGGLE_ADD_CONTROLS = "toggle_add_controls"
|
||||||
const val ALBUM_COVER_STYLE = "album_cover_style_id"
|
const val ALBUM_COVER_STYLE = "album_cover_style_id"
|
||||||
const val ALBUM_COVER_TRANSFORM = "album_cover_transform"
|
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_SORT_ORDER = "artist_sort_order"
|
||||||
const val ARTIST_ALBUM_SORT_ORDER = "artist_album_sort_order"
|
const val ARTIST_ALBUM_SORT_ORDER = "artist_album_sort_order"
|
||||||
const val ALBUM_SORT_ORDER = "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 ALBUM_SONG_SORT_ORDER = "album_song_sort_order"
|
||||||
const val ARTIST_SONG_SORT_ORDER = "artist_song_sort_order"
|
const val ARTIST_SONG_SORT_ORDER = "artist_song_sort_order"
|
||||||
const val ALBUM_GRID_SIZE = "album_grid_size"
|
const val ALBUM_GRID_SIZE = "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 START_DIRECTORY = "start_directory"
|
||||||
const val RECENTLY_PLAYED_CUTOFF = "recently_played_interval"
|
const val RECENTLY_PLAYED_CUTOFF = "recently_played_interval"
|
||||||
const val LOCK_SCREEN = "lock_screen"
|
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 ALBUM_DETAIL_SONG_SORT_ORDER = "album_detail_song_sort_order"
|
||||||
const val LYRICS_OPTIONS = "lyrics_tab_position"
|
const val LYRICS_OPTIONS = "lyrics_tab_position"
|
||||||
const val CHOOSE_EQUALIZER = "choose_equalizer"
|
const val CHOOSE_EQUALIZER = "choose_equalizer"
|
||||||
|
const val EQUALIZER = "equalizer"
|
||||||
const val TOGGLE_SHUFFLE = "toggle_shuffle"
|
const val TOGGLE_SHUFFLE = "toggle_shuffle"
|
||||||
const val SONG_GRID_STYLE = "song_grid_style"
|
const val SONG_GRID_STYLE = "song_grid_style"
|
||||||
const val PAUSE_ON_ZERO_VOLUME = "pause_on_zero_volume"
|
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
|
package io.github.muntashirakon.music
|
||||||
|
|
||||||
import androidx.annotation.IntDef
|
import androidx.annotation.IntDef
|
||||||
|
@ -25,4 +39,4 @@ const val GENRES = 6
|
||||||
const val PLAYLISTS = 7
|
const val PLAYLISTS = 7
|
||||||
const val HISTORY_PLAYLIST = 8
|
const val HISTORY_PLAYLIST = 8
|
||||||
const val LAST_ADDED_PLAYLIST = 9
|
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.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.os.LocaleList;
|
import android.os.LocaleList;
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import code.name.monkey.appthemehelper.util.VersionUtils;
|
import code.name.monkey.appthemehelper.util.VersionUtils;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public class LanguageContextWrapper extends ContextWrapper {
|
public class LanguageContextWrapper extends ContextWrapper {
|
||||||
|
|
||||||
public LanguageContextWrapper(Context base) {
|
public LanguageContextWrapper(Context base) {
|
||||||
super(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) {
|
return new LanguageContextWrapper(context);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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.artists.ArtistDetailsViewModel
|
||||||
import io.github.muntashirakon.music.fragments.genres.GenreDetailsViewModel
|
import io.github.muntashirakon.music.fragments.genres.GenreDetailsViewModel
|
||||||
import io.github.muntashirakon.music.fragments.playlists.PlaylistDetailsViewModel
|
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.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.repository.*
|
||||||
import io.github.muntashirakon.music.util.FilePathUtil
|
import io.github.muntashirakon.music.util.FilePathUtil
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
|
@ -36,15 +38,9 @@ val networkModule = module {
|
||||||
single {
|
single {
|
||||||
provideLastFmRetrofit(get())
|
provideLastFmRetrofit(get())
|
||||||
}
|
}
|
||||||
single {
|
|
||||||
provideDeezerRest(get())
|
|
||||||
}
|
|
||||||
single {
|
single {
|
||||||
provideLastFmRest(get())
|
provideLastFmRest(get())
|
||||||
}
|
}
|
||||||
single {
|
|
||||||
provideLyrics(get())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val roomModule = module {
|
private val roomModule = module {
|
||||||
|
@ -93,7 +89,6 @@ private val mainModule = module {
|
||||||
single {
|
single {
|
||||||
androidContext().contentResolver
|
androidContext().contentResolver
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
private val dataModule = module {
|
private val dataModule = module {
|
||||||
single {
|
single {
|
||||||
|
@ -109,7 +104,7 @@ private val dataModule = module {
|
||||||
get(),
|
get(),
|
||||||
get(),
|
get(),
|
||||||
get(),
|
get(),
|
||||||
get()
|
get(),
|
||||||
)
|
)
|
||||||
} bind Repository::class
|
} bind Repository::class
|
||||||
|
|
||||||
|
@ -154,6 +149,9 @@ private val dataModule = module {
|
||||||
get()
|
get()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
single {
|
||||||
|
RealLocalDataRepository(get())
|
||||||
|
} bind LocalDataRepository::class
|
||||||
}
|
}
|
||||||
|
|
||||||
private val viewModules = module {
|
private val viewModules = module {
|
||||||
|
@ -189,10 +187,6 @@ private val viewModules = module {
|
||||||
genre
|
genre
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel {
|
|
||||||
SearchViewModel(get())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val appModules = listOf(mainModule, dataModule, viewModules, networkModule, roomModule)
|
val appModules = listOf(mainModule, dataModule, viewModules, networkModule, roomModule)
|
|
@ -4,36 +4,32 @@ import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||||
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|
||||||
public class RetroBottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {
|
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;
|
||||||
}
|
}
|
||||||
|
return super.onInterceptTouchEvent(parent, child, event);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020 Hemanth Savarala.
|
* Copyright (c) 2020 Hemanth Savarla.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.activities
|
package io.github.muntashirakon.music.activities
|
||||||
|
|
||||||
import android.animation.ObjectAnimator
|
import android.animation.ObjectAnimator
|
||||||
|
@ -234,4 +234,4 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback {
|
||||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,82 +18,86 @@ import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
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.ThemeStore;
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||||
import io.github.muntashirakon.music.R;
|
import io.github.muntashirakon.music.R;
|
||||||
import io.github.muntashirakon.music.activities.base.AbsBaseActivity;
|
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 {
|
public class LicenseActivity extends AbsBaseActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
setDrawUnderStatusBar();
|
setDrawUnderStatusBar();
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_license);
|
setContentView(R.layout.activity_license);
|
||||||
setStatusbarColorAuto();
|
setStatusbarColorAuto();
|
||||||
setNavigationbarColorAuto();
|
setNavigationbarColorAuto();
|
||||||
setLightNavigationBar(true);
|
setLightNavigationBar(true);
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
ToolbarContentTintHelper.colorBackButton(toolbar);
|
ToolbarContentTintHelper.colorBackButton(toolbar);
|
||||||
toolbar.setBackgroundColor(ATHUtil.INSTANCE.resolveColor(this, R.attr.colorSurface));
|
toolbar.setBackgroundColor(ATHUtil.INSTANCE.resolveColor(this, R.attr.colorSurface));
|
||||||
WebView webView = findViewById(R.id.license);
|
WebView webView = findViewById(R.id.license);
|
||||||
try {
|
try {
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
InputStream json = getAssets().open("oldindex.html");
|
InputStream json = getAssets().open("oldindex.html");
|
||||||
BufferedReader in = new BufferedReader(new InputStreamReader(json, StandardCharsets.UTF_8));
|
BufferedReader in = new BufferedReader(new InputStreamReader(json, StandardCharsets.UTF_8));
|
||||||
String str;
|
String str;
|
||||||
while ((str = in.readLine()) != null) {
|
while ((str = in.readLine()) != null) {
|
||||||
buf.append(str);
|
buf.append(str);
|
||||||
}
|
}
|
||||||
in.close();
|
in.close();
|
||||||
|
|
||||||
// Inject color values for WebView body background and links
|
// Inject color values for WebView body background and links
|
||||||
final boolean isDark = ATHUtil.INSTANCE.isWindowBackgroundDark(this);
|
final boolean isDark = ATHUtil.INSTANCE.isWindowBackgroundDark(this);
|
||||||
final String backgroundColor = colorToCSS(ATHUtil.INSTANCE.resolveColor(this, R.attr.colorSurface,
|
final String backgroundColor =
|
||||||
Color.parseColor(isDark ? "#424242" : "#ffffff")));
|
colorToCSS(
|
||||||
final String contentColor = colorToCSS(Color.parseColor(isDark ? "#ffffff" : "#000000"));
|
ATHUtil.INSTANCE.resolveColor(
|
||||||
final String changeLog = buf.toString()
|
this, R.attr.colorSurface, Color.parseColor(isDark ? "#424242" : "#ffffff")));
|
||||||
.replace("{style-placeholder}",
|
final String contentColor = colorToCSS(Color.parseColor(isDark ? "#ffffff" : "#000000"));
|
||||||
String.format("body { background-color: %s; color: %s; }", backgroundColor, contentColor))
|
final String changeLog =
|
||||||
.replace("{link-color}", colorToCSS(ThemeStore.Companion.accentColor(this)))
|
buf.toString()
|
||||||
.replace("{link-color-active}",
|
.replace(
|
||||||
colorToCSS(ColorUtil.INSTANCE.lightenColor(ThemeStore.Companion.accentColor(this))));
|
"{style-placeholder}",
|
||||||
|
String.format(
|
||||||
webView.loadData(changeLog, "text/html", "UTF-8");
|
"body { background-color: %s; color: %s; }", backgroundColor, contentColor))
|
||||||
} catch (Throwable e) {
|
.replace("{link-color}", colorToCSS(ThemeStore.Companion.accentColor(this)))
|
||||||
webView.loadData("<h1>Unable to load</h1><p>" + e.getLocalizedMessage() + "</p>", "text/html", "UTF-8");
|
.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
|
@Override
|
||||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||||
if (item.getItemId() == android.R.id.home) {
|
if (item.getItemId() == android.R.id.home) {
|
||||||
onBackPressed();
|
onBackPressed();
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
private String colorToCSS(int color) {
|
private String colorToCSS(int color) {
|
||||||
return String.format("rgb(%d, %d, %d)", Color.red(color), Color.green(color),
|
return String.format(
|
||||||
Color.blue(color)); // on API 29, WebView doesn't load with hex colors
|
"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
|
package io.github.muntashirakon.music.activities
|
||||||
|
|
||||||
import android.app.KeyguardManager
|
import android.app.KeyguardManager
|
||||||
|
@ -9,7 +23,8 @@ import android.view.WindowManager
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import io.github.muntashirakon.music.R
|
import io.github.muntashirakon.music.R
|
||||||
import io.github.muntashirakon.music.activities.base.AbsMusicServiceActivity
|
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.RetroMusicColoredTarget
|
||||||
import io.github.muntashirakon.music.glide.SongGlideRequest
|
import io.github.muntashirakon.music.glide.SongGlideRequest
|
||||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
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.*
|
import kotlinx.android.synthetic.main.activity_lock_screen.*
|
||||||
|
|
||||||
class LockScreenActivity : AbsMusicServiceActivity() {
|
class LockScreenActivity : AbsMusicServiceActivity() {
|
||||||
private var fragment: LockScreenPlayerControlsFragment? = null
|
private var fragment: LockScreenControlsFragment? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setDrawUnderStatusBar()
|
setDrawUnderStatusBar()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
lockScreenInit()
|
||||||
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
|
|
||||||
)
|
|
||||||
}
|
|
||||||
setContentView(R.layout.activity_lock_screen)
|
setContentView(R.layout.activity_lock_screen)
|
||||||
hideStatusBar()
|
hideStatusBar()
|
||||||
setStatusbarColorAuto()
|
setStatusbarColorAuto()
|
||||||
|
@ -67,8 +73,7 @@ class LockScreenActivity : AbsMusicServiceActivity() {
|
||||||
|
|
||||||
Slidr.attach(this, config)
|
Slidr.attach(this, config)
|
||||||
|
|
||||||
fragment =
|
fragment = whichFragment<LockScreenControlsFragment>(R.id.playback_controls_fragment)
|
||||||
supportFragmentManager.findFragmentById(R.id.playback_controls_fragment) as LockScreenPlayerControlsFragment?
|
|
||||||
|
|
||||||
findViewById<View>(R.id.slide).apply {
|
findViewById<View>(R.id.slide).apply {
|
||||||
translationY = 100f
|
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() {
|
override fun onPlayingMetaChanged() {
|
||||||
super.onPlayingMetaChanged()
|
super.onPlayingMetaChanged()
|
||||||
updateSongs()
|
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
|
package io.github.muntashirakon.music.activities
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.WindowManager
|
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.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||||
import io.github.muntashirakon.music.R
|
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.model.Song
|
||||||
import io.github.muntashirakon.music.util.LyricUtil
|
import io.github.muntashirakon.music.util.LyricUtil
|
||||||
import io.github.muntashirakon.music.util.RetroUtil
|
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.*
|
import kotlinx.android.synthetic.main.activity_lyrics.*
|
||||||
|
|
||||||
class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.Callback {
|
class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.Callback {
|
||||||
|
@ -31,9 +51,20 @@ class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.
|
||||||
return baseUrl
|
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?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_lyrics)
|
setContentView(R.layout.activity_lyrics)
|
||||||
|
ViewCompat.setTransitionName(container, "lyrics")
|
||||||
setStatusbarColorAuto()
|
setStatusbarColorAuto()
|
||||||
setTaskDescriptionColorAuto()
|
setTaskDescriptionColorAuto()
|
||||||
setNavigationbarColorAuto()
|
setNavigationbarColorAuto()
|
||||||
|
@ -122,4 +153,4 @@ class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item)
|
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
|
package io.github.muntashirakon.music.activities
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
@ -8,17 +22,45 @@ import android.os.Bundle
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.lifecycle.lifecycleScope
|
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.activities.base.AbsSlidingMusicPanelActivity
|
||||||
import io.github.muntashirakon.music.extensions.findNavController
|
import io.github.muntashirakon.music.extensions.findNavController
|
||||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
||||||
import io.github.muntashirakon.music.helper.SearchQueryHelper.getSongs
|
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.model.Song
|
||||||
import io.github.muntashirakon.music.repository.PlaylistSongsLoader
|
import io.github.muntashirakon.music.repository.PlaylistSongsLoader
|
||||||
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.PreferenceUtil
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import org.koin.android.ext.android.get
|
||||||
|
|
||||||
class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeListener {
|
class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeListener {
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -28,21 +70,43 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createContentView(): View {
|
override fun createContentView(): View {
|
||||||
return wrapSlidingMusicPanel(R.layout.activity_main_content)
|
return wrapSlidingMusicPanel()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setDrawUnderStatusBar()
|
setDrawUnderStatusBar()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
if (!hasPermissions()) {
|
|
||||||
findNavController(R.id.fragment_container).navigate(R.id.permissionFragment)
|
|
||||||
}
|
|
||||||
setStatusbarColorAuto()
|
setStatusbarColorAuto()
|
||||||
setNavigationbarColorAuto()
|
setNavigationbarColorAuto()
|
||||||
setLightNavigationBar(true)
|
setLightNavigationBar(true)
|
||||||
setTaskDescriptionColorAuto()
|
setTaskDescriptionColorAuto()
|
||||||
hideStatusBar()
|
hideStatusBar()
|
||||||
updateTabs()
|
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 =
|
override fun onSupportNavigateUp(): Boolean =
|
||||||
|
@ -98,8 +162,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
|
||||||
val id = parseLongFromIntent(intent, "playlistId", "playlist")
|
val id = parseLongFromIntent(intent, "playlistId", "playlist")
|
||||||
if (id >= 0L) {
|
if (id >= 0L) {
|
||||||
val position: Int = intent.getIntExtra("position", 0)
|
val position: Int = intent.getIntExtra("position", 0)
|
||||||
val songs: List<Song> =
|
val songs: List<Song> = PlaylistSongsLoader.getPlaylistSongList(get(), id)
|
||||||
PlaylistSongsLoader.getPlaylistSongList(this@MainActivity, id)
|
|
||||||
MusicPlayerRemote.openQueue(songs, position, true)
|
MusicPlayerRemote.openQueue(songs, position, true)
|
||||||
handled = true
|
handled = true
|
||||||
}
|
}
|
||||||
|
@ -107,8 +170,9 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
|
||||||
val id = parseLongFromIntent(intent, "albumId", "album")
|
val id = parseLongFromIntent(intent, "albumId", "album")
|
||||||
if (id >= 0L) {
|
if (id >= 0L) {
|
||||||
val position: Int = intent.getIntExtra("position", 0)
|
val position: Int = intent.getIntExtra("position", 0)
|
||||||
|
val songs = libraryViewModel.albumById(id).songs
|
||||||
MusicPlayerRemote.openQueue(
|
MusicPlayerRemote.openQueue(
|
||||||
libraryViewModel.albumById(id).songs,
|
songs,
|
||||||
position,
|
position,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
@ -118,8 +182,9 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
|
||||||
val id = parseLongFromIntent(intent, "artistId", "artist")
|
val id = parseLongFromIntent(intent, "artistId", "artist")
|
||||||
if (id >= 0L) {
|
if (id >= 0L) {
|
||||||
val position: Int = intent.getIntExtra("position", 0)
|
val position: Int = intent.getIntExtra("position", 0)
|
||||||
|
val songs: List<Song> = libraryViewModel.artistById(id).songs
|
||||||
MusicPlayerRemote.openQueue(
|
MusicPlayerRemote.openQueue(
|
||||||
libraryViewModel.artistById(id).songs,
|
songs,
|
||||||
position,
|
position,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
@ -130,11 +195,11 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
|
||||||
setIntent(Intent())
|
setIntent(Intent())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseLongFromIntent(
|
private fun parseLongFromIntent(
|
||||||
intent: Intent, longKey: String,
|
intent: Intent,
|
||||||
|
longKey: String,
|
||||||
stringKey: String
|
stringKey: String
|
||||||
): Long {
|
): Long {
|
||||||
var id = intent.getLongExtra(longKey, -1)
|
var id = intent.getLongExtra(longKey, -1)
|
||||||
|
@ -150,4 +215,4 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
|
||||||
}
|
}
|
||||||
return id
|
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
|
package io.github.muntashirakon.music.activities
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
@ -13,7 +27,6 @@ import io.github.muntashirakon.music.extensions.show
|
||||||
import io.github.muntashirakon.music.util.RingtoneManager
|
import io.github.muntashirakon.music.util.RingtoneManager
|
||||||
import kotlinx.android.synthetic.main.activity_permission.*
|
import kotlinx.android.synthetic.main.activity_permission.*
|
||||||
|
|
||||||
|
|
||||||
class PermissionActivity : AbsMusicServiceActivity() {
|
class PermissionActivity : AbsMusicServiceActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -37,7 +50,7 @@ class PermissionActivity : AbsMusicServiceActivity() {
|
||||||
}
|
}
|
||||||
finish.accentBackgroundColor()
|
finish.accentBackgroundColor()
|
||||||
finish.setOnClickListener {
|
finish.setOnClickListener {
|
||||||
if (hasPermissions() && !RingtoneManager.requiresDialog(this)) {
|
if (hasPermissions()) {
|
||||||
startActivity(
|
startActivity(
|
||||||
Intent(this, MainActivity::class.java).addFlags(
|
Intent(this, MainActivity::class.java).addFlags(
|
||||||
Intent.FLAG_ACTIVITY_NEW_TASK or
|
Intent.FLAG_ACTIVITY_NEW_TASK or
|
||||||
|
@ -56,4 +69,4 @@ class PermissionActivity : AbsMusicServiceActivity() {
|
||||||
)
|
)
|
||||||
appNameText.text = appName
|
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
|
package io.github.muntashirakon.music.activities
|
||||||
|
|
||||||
import android.content.res.ColorStateList
|
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
|
package io.github.muntashirakon.music.activities
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import androidx.navigation.NavDestination
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.VersionUtils
|
import code.name.monkey.appthemehelper.util.VersionUtils
|
||||||
import com.afollestad.materialdialogs.color.ColorChooserDialog
|
import com.afollestad.materialdialogs.color.ColorChooserDialog
|
||||||
|
@ -29,10 +44,26 @@ class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback {
|
||||||
applyToolbar(toolbar)
|
applyToolbar(toolbar)
|
||||||
val navController: NavController = findNavController(R.id.contentFrame)
|
val navController: NavController = findNavController(R.id.contentFrame)
|
||||||
navController.addOnDestinationChangedListener { _, _, _ ->
|
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 {
|
override fun onSupportNavigateUp(): Boolean {
|
||||||
return findNavController(R.id.contentFrame).navigateUp() || super.onSupportNavigateUp()
|
return findNavController(R.id.contentFrame).navigateUp() || super.onSupportNavigateUp()
|
||||||
}
|
}
|
||||||
|
@ -49,7 +80,6 @@ class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onColorChooserDismissed(dialog: ColorChooserDialog) {
|
override fun onColorChooserDismissed(dialog: ColorChooserDialog) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
@ -58,4 +88,4 @@ class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback {
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item)
|
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
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.activities
|
package io.github.muntashirakon.music.activities
|
||||||
|
|
||||||
import android.content.res.ColorStateList
|
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
|
package io.github.muntashirakon.music.activities
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
@ -11,12 +25,6 @@ import android.view.MenuItem
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
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_BANNER
|
||||||
import io.github.muntashirakon.music.Constants.USER_PROFILE
|
import io.github.muntashirakon.music.Constants.USER_PROFILE
|
||||||
import io.github.muntashirakon.music.R
|
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.glide.UserProfileGlideRequest
|
||||||
import io.github.muntashirakon.music.util.ImageUtil
|
import io.github.muntashirakon.music.util.ImageUtil
|
||||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
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.android.synthetic.main.activity_user_info.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.BufferedOutputStream
|
|
||||||
import java.io.File
|
|
||||||
import java.io.FileOutputStream
|
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
class UserInfoActivity : AbsBaseActivity() {
|
class UserInfoActivity : AbsBaseActivity() {
|
||||||
|
|
||||||
|
@ -55,7 +69,7 @@ class UserInfoActivity : AbsBaseActivity() {
|
||||||
pickNewPhoto()
|
pickNewPhoto()
|
||||||
}
|
}
|
||||||
|
|
||||||
bannerSelect.setOnClickListener {
|
bannerImage.setOnClickListener {
|
||||||
selectBannerImage()
|
selectBannerImage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +128,6 @@ class UserInfoActivity : AbsBaseActivity() {
|
||||||
.start(PICK_IMAGE_REQUEST)
|
.start(PICK_IMAGE_REQUEST)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
if (resultCode == Activity.RESULT_OK && requestCode == PICK_IMAGE_REQUEST) {
|
if (resultCode == Activity.RESULT_OK && requestCode == PICK_IMAGE_REQUEST) {
|
||||||
|
@ -209,9 +222,8 @@ class UserInfoActivity : AbsBaseActivity() {
|
||||||
.into(userImage)
|
.into(userImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val PICK_IMAGE_REQUEST = 9002
|
private const val PICK_IMAGE_REQUEST = 9002
|
||||||
private const val PICK_BANNER_REQUEST = 9004
|
private const val PICK_BANNER_REQUEST = 9004
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,14 @@
|
||||||
package io.github.muntashirakon.music.activities;
|
package io.github.muntashirakon.music.activities;
|
||||||
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
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.ThemeStore;
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
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.R;
|
||||||
import io.github.muntashirakon.music.activities.base.AbsBaseActivity;
|
import io.github.muntashirakon.music.activities.base.AbsBaseActivity;
|
||||||
import io.github.muntashirakon.music.util.PreferenceUtil;
|
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 {
|
public class WhatsNewActivity extends AbsBaseActivity {
|
||||||
|
|
||||||
private static String colorToCSS(int color) {
|
private static String colorToCSS(int color) {
|
||||||
return String.format(Locale.getDefault(), "rgba(%d, %d, %d, %d)", Color.red(color), Color.green(color),
|
return String.format(
|
||||||
Color.blue(color), Color.alpha(color)); // on API 29, WebView doesn't load with hex colors
|
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) {
|
@Override
|
||||||
try {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
|
setDrawUnderStatusBar();
|
||||||
int currentVersion = pInfo.versionCode;
|
super.onCreate(savedInstanceState);
|
||||||
PreferenceUtil.INSTANCE.setLastVersion(currentVersion);
|
setContentView(R.layout.activity_whats_new);
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
setStatusbarColorAuto();
|
||||||
e.printStackTrace();
|
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);
|
||||||
@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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
package io.github.muntashirakon.music.activities.base
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
|
@ -12,8 +26,8 @@ import android.view.KeyEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import com.google.android.material.snackbar.Snackbar
|
|
||||||
import io.github.muntashirakon.music.R
|
import io.github.muntashirakon.music.R
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
|
||||||
abstract class AbsBaseActivity : AbsThemeActivity() {
|
abstract class AbsBaseActivity : AbsThemeActivity() {
|
||||||
private var hadPermissions: Boolean = false
|
private var hadPermissions: Boolean = false
|
||||||
|
@ -46,7 +60,7 @@ abstract class AbsBaseActivity : AbsThemeActivity() {
|
||||||
override fun onPostCreate(savedInstanceState: Bundle?) {
|
override fun onPostCreate(savedInstanceState: Bundle?) {
|
||||||
super.onPostCreate(savedInstanceState)
|
super.onPostCreate(savedInstanceState)
|
||||||
if (!hasPermissions()) {
|
if (!hasPermissions()) {
|
||||||
//requestPermissions()
|
// requestPermissions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +121,7 @@ abstract class AbsBaseActivity : AbsThemeActivity() {
|
||||||
this@AbsBaseActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE
|
this@AbsBaseActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
//User has deny from permission dialog
|
// User has deny from permission dialog
|
||||||
Snackbar.make(
|
Snackbar.make(
|
||||||
snackBarContainer,
|
snackBarContainer,
|
||||||
permissionDeniedMessage!!,
|
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
|
package io.github.muntashirakon.music.activities.base
|
||||||
|
|
||||||
import android.Manifest
|
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.Bundle
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import io.github.muntashirakon.music.R
|
import io.github.muntashirakon.music.R
|
||||||
import io.github.muntashirakon.music.db.toPlayCount
|
import io.github.muntashirakon.music.db.toPlayCount
|
||||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
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.repository.RealRepository
|
||||||
import io.github.muntashirakon.music.service.MusicService.*
|
import io.github.muntashirakon.music.service.MusicService.*
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
import java.util.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koin.android.ext.android.inject
|
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 val repository: RealRepository by inject()
|
||||||
private var serviceToken: MusicPlayerRemote.ServiceToken? = null
|
private var serviceToken: MusicPlayerRemote.ServiceToken? = null
|
||||||
private var musicStateReceiver: MusicStateReceiver? = null
|
private var musicStateReceiver: MusicStateReceiver? = null
|
||||||
|
@ -49,15 +68,15 @@ abstract class AbsMusicServiceActivity : AbsBaseActivity(), MusicServiceEventLis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addMusicServiceEventListener(listener: MusicServiceEventListener?) {
|
fun addMusicServiceEventListener(listenerI: IMusicServiceEventListener?) {
|
||||||
if (listener != null) {
|
if (listenerI != null) {
|
||||||
mMusicServiceEventListeners.add(listener)
|
mMusicServiceEventListeners.add(listenerI)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeMusicServiceEventListener(listener: MusicServiceEventListener?) {
|
fun removeMusicServiceEventListener(listenerI: IMusicServiceEventListener?) {
|
||||||
if (listener != null) {
|
if (listenerI != null) {
|
||||||
mMusicServiceEventListeners.remove(listener)
|
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
|
package io.github.muntashirakon.music.activities.base
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewTreeObserver
|
import android.view.ViewTreeObserver
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import androidx.annotation.LayoutRes
|
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.isVisible
|
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.ATHUtil
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||||
import io.github.muntashirakon.music.R
|
import io.github.muntashirakon.music.R
|
||||||
import io.github.muntashirakon.music.RetroBottomSheetBehavior
|
import io.github.muntashirakon.music.RetroBottomSheetBehavior
|
||||||
import io.github.muntashirakon.music.extensions.hide
|
import io.github.muntashirakon.music.extensions.*
|
||||||
import io.github.muntashirakon.music.extensions.whichFragment
|
|
||||||
import io.github.muntashirakon.music.fragments.LibraryViewModel
|
import io.github.muntashirakon.music.fragments.LibraryViewModel
|
||||||
import io.github.muntashirakon.music.fragments.MiniPlayerFragment
|
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.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.helper.MusicPlayerRemote
|
||||||
import io.github.muntashirakon.music.model.CategoryInfo
|
import io.github.muntashirakon.music.model.CategoryInfo
|
||||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||||
import io.github.muntashirakon.music.views.BottomNavigationBarTinted
|
import io.github.muntashirakon.music.views.BottomNavigationBarTinted
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetBehavior.*
|
||||||
import kotlinx.android.synthetic.main.sliding_music_panel_layout.*
|
import kotlinx.android.synthetic.main.sliding_music_panel_layout.*
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
|
||||||
|
@ -34,9 +67,10 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected val libraryViewModel by viewModel<LibraryViewModel>()
|
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 miniPlayerFragment: MiniPlayerFragment? = null
|
||||||
private var cps: NowPlayingScreen? = null
|
private var nowPlayingScreen: NowPlayingScreen? = null
|
||||||
private var navigationBarColor: Int = 0
|
private var navigationBarColor: Int = 0
|
||||||
private var taskColor: Int = 0
|
private var taskColor: Int = 0
|
||||||
private var lightStatusBar: Boolean = false
|
private var lightStatusBar: Boolean = false
|
||||||
|
@ -44,88 +78,90 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
||||||
private var paletteColor: Int = Color.WHITE
|
private var paletteColor: Int = Color.WHITE
|
||||||
protected abstract fun createContentView(): View
|
protected abstract fun createContentView(): View
|
||||||
private val panelState: Int
|
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) {
|
override fun onSlide(bottomSheet: View, slideOffset: Float) {
|
||||||
setMiniPlayerAlphaProgress(slideOffset)
|
setMiniPlayerAlphaProgress(slideOffset)
|
||||||
|
dimBackground.show()
|
||||||
|
dimBackground.alpha = slideOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||||
when (newState) {
|
when (newState) {
|
||||||
BottomSheetBehavior.STATE_EXPANDED -> {
|
STATE_EXPANDED -> {
|
||||||
onPanelExpanded()
|
onPanelExpanded()
|
||||||
}
|
}
|
||||||
BottomSheetBehavior.STATE_COLLAPSED -> {
|
STATE_COLLAPSED -> {
|
||||||
onPanelCollapsed()
|
onPanelCollapsed()
|
||||||
|
dimBackground.hide()
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
println("Do something")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getBottomSheetBehavior() = bottomSheetBehavior
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(createContentView())
|
setContentView(createContentView())
|
||||||
chooseFragmentForTheme()
|
chooseFragmentForTheme()
|
||||||
setupSlidingUpPanel()
|
setupSlidingUpPanel()
|
||||||
|
|
||||||
setupBottomSheet()
|
setupBottomSheet()
|
||||||
|
updateColor()
|
||||||
|
|
||||||
libraryViewModel.paletteColorLiveData.observe(this, Observer {
|
val themeColor = ATHUtil.resolveColor(this, android.R.attr.windowBackground, Color.GRAY)
|
||||||
this.paletteColor = it
|
dimBackground.setBackgroundColor(ColorUtil.withAlpha(themeColor, 0.5f))
|
||||||
onPaletteColorChanged()
|
dimBackground.setOnClickListener {
|
||||||
})
|
println("dimBackground")
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getBottomSheetBehavior() = behavior
|
|
||||||
|
|
||||||
private fun setupBottomSheet() {
|
private fun setupBottomSheet() {
|
||||||
behavior = BottomSheetBehavior.from(slidingPanel) as RetroBottomSheetBehavior
|
bottomSheetBehavior = from(slidingPanel) as RetroBottomSheetBehavior
|
||||||
behavior.addBottomSheetCallback(bottomSheetCallbackList)
|
bottomSheetBehavior.addBottomSheetCallback(bottomSheetCallbackList)
|
||||||
|
|
||||||
if (behavior.state == BottomSheetBehavior.STATE_EXPANDED) {
|
|
||||||
setMiniPlayerAlphaProgress(1f)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
if (cps != PreferenceUtil.nowPlayingScreen) {
|
if (nowPlayingScreen != PreferenceUtil.nowPlayingScreen) {
|
||||||
postRecreate()
|
postRecreate()
|
||||||
}
|
}
|
||||||
|
if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) {
|
||||||
|
setMiniPlayerAlphaProgress(1f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
behavior.removeBottomSheetCallback(bottomSheetCallbackList)
|
bottomSheetBehavior.removeBottomSheetCallback(bottomSheetCallbackList)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun wrapSlidingMusicPanel(@LayoutRes resId: Int): View {
|
@SuppressLint("InflateParams")
|
||||||
|
protected fun wrapSlidingMusicPanel(): View {
|
||||||
val slidingMusicPanelLayout =
|
val slidingMusicPanelLayout =
|
||||||
layoutInflater.inflate(R.layout.sliding_music_panel_layout, null)
|
layoutInflater.inflate(R.layout.sliding_music_panel_layout, null)
|
||||||
val contentContainer: ViewGroup =
|
val contentContainer: ViewGroup =
|
||||||
slidingMusicPanelLayout.findViewById(R.id.mainContentFrame)
|
slidingMusicPanelLayout.findViewById(R.id.mainContentFrame)
|
||||||
layoutInflater.inflate(resId, contentContainer)
|
layoutInflater.inflate(R.layout.activity_main_content, contentContainer)
|
||||||
return slidingMusicPanelLayout
|
return slidingMusicPanelLayout
|
||||||
}
|
}
|
||||||
|
|
||||||
fun collapsePanel() {
|
fun collapsePanel() {
|
||||||
behavior.state = BottomSheetBehavior.STATE_COLLAPSED
|
bottomSheetBehavior.state = STATE_COLLAPSED
|
||||||
setMiniPlayerAlphaProgress(0f)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun expandPanel() {
|
fun expandPanel() {
|
||||||
behavior.state = BottomSheetBehavior.STATE_EXPANDED
|
bottomSheetBehavior.state = STATE_EXPANDED
|
||||||
setMiniPlayerAlphaProgress(1f)
|
setMiniPlayerAlphaProgress(1f)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setMiniPlayerAlphaProgress(progress: Float) {
|
private fun setMiniPlayerAlphaProgress(progress: Float) {
|
||||||
if (miniPlayerFragment?.view == null) return
|
|
||||||
val alpha = 1 - progress
|
val alpha = 1 - progress
|
||||||
miniPlayerFragment?.view?.alpha = alpha
|
miniPlayerFragment?.view?.alpha = alpha
|
||||||
miniPlayerFragment?.view?.visibility = if (alpha == 0f) View.GONE else View.VISIBLE
|
miniPlayerFragment?.view?.visibility = if (alpha == 0f) View.GONE else View.VISIBLE
|
||||||
|
@ -150,11 +186,16 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
||||||
ViewTreeObserver.OnGlobalLayoutListener {
|
ViewTreeObserver.OnGlobalLayoutListener {
|
||||||
override fun onGlobalLayout() {
|
override fun onGlobalLayout() {
|
||||||
slidingPanel.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
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) {
|
when (panelState) {
|
||||||
BottomSheetBehavior.STATE_EXPANDED -> onPanelExpanded()
|
STATE_EXPANDED -> onPanelExpanded()
|
||||||
BottomSheetBehavior.STATE_COLLAPSED -> onPanelCollapsed()
|
STATE_COLLAPSED -> onPanelCollapsed()
|
||||||
else -> {
|
else -> {
|
||||||
//playerFragment!!.onHide()
|
// playerFragment!!.onHide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,35 +206,6 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
||||||
return bottomNavigationView
|
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() {
|
override fun onServiceConnected() {
|
||||||
super.onServiceConnected()
|
super.onServiceConnected()
|
||||||
if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
|
if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
|
||||||
|
@ -216,36 +228,38 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
||||||
if (!handleBackPress()) super.onBackPressed()
|
if (!handleBackPress()) super.onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun handleBackPress(): Boolean {
|
private fun handleBackPress(): Boolean {
|
||||||
if (panelState == BottomSheetBehavior.STATE_EXPANDED) {
|
if (bottomSheetBehavior.peekHeight != 0 && playerFragment!!.onBackPressed()) return true
|
||||||
|
if (panelState == STATE_EXPANDED) {
|
||||||
collapsePanel()
|
collapsePanel()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onPaletteColorChanged() {
|
private fun onPaletteColorChanged() {
|
||||||
if (panelState == BottomSheetBehavior.STATE_EXPANDED) {
|
if (panelState == STATE_EXPANDED) {
|
||||||
super.setTaskDescriptionColor(paletteColor)
|
super.setTaskDescriptionColor(paletteColor)
|
||||||
val isColorLight = ColorUtil.isColorLight(paletteColor)
|
val isColorLight = ColorUtil.isColorLight(paletteColor)
|
||||||
if (PreferenceUtil.isAdaptiveColor && (cps == Normal || cps == Flat)) {
|
if (PreferenceUtil.isAdaptiveColor && (nowPlayingScreen == Normal || nowPlayingScreen == Flat)) {
|
||||||
super.setLightNavigationBar(true)
|
super.setLightNavigationBar(true)
|
||||||
super.setLightStatusbar(isColorLight)
|
super.setLightStatusbar(isColorLight)
|
||||||
} else if (cps == Card || cps == Blur || cps == BlurCard) {
|
} else if (nowPlayingScreen == Card || nowPlayingScreen == Blur || nowPlayingScreen == BlurCard) {
|
||||||
super.setLightStatusbar(false)
|
super.setLightStatusbar(false)
|
||||||
super.setLightNavigationBar(true)
|
super.setLightNavigationBar(true)
|
||||||
super.setNavigationbarColor(Color.BLACK)
|
super.setNavigationbarColor(Color.BLACK)
|
||||||
} else if (cps == Color || cps == Tiny || cps == Gradient) {
|
} else if (nowPlayingScreen == Color || nowPlayingScreen == Tiny || nowPlayingScreen == Gradient) {
|
||||||
super.setNavigationbarColor(paletteColor)
|
super.setNavigationbarColor(paletteColor)
|
||||||
super.setLightNavigationBar(isColorLight)
|
super.setLightNavigationBar(isColorLight)
|
||||||
super.setLightStatusbar(isColorLight)
|
super.setLightStatusbar(isColorLight)
|
||||||
} else if (cps == Full) {
|
} else if (nowPlayingScreen == Full) {
|
||||||
super.setNavigationbarColor(paletteColor)
|
super.setNavigationbarColor(paletteColor)
|
||||||
super.setLightNavigationBar(isColorLight)
|
super.setLightNavigationBar(isColorLight)
|
||||||
super.setLightStatusbar(false)
|
super.setLightStatusbar(false)
|
||||||
} else if (cps == Classic) {
|
} else if (nowPlayingScreen == Classic) {
|
||||||
super.setLightStatusbar(false)
|
super.setLightStatusbar(false)
|
||||||
} else if (cps == Fit) {
|
} else if (nowPlayingScreen == Fit) {
|
||||||
super.setLightStatusbar(false)
|
super.setLightStatusbar(false)
|
||||||
} else {
|
} else {
|
||||||
super.setLightStatusbar(
|
super.setLightStatusbar(
|
||||||
|
@ -263,38 +277,32 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
||||||
|
|
||||||
override fun setLightStatusbar(enabled: Boolean) {
|
override fun setLightStatusbar(enabled: Boolean) {
|
||||||
lightStatusBar = enabled
|
lightStatusBar = enabled
|
||||||
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
if (panelState == STATE_COLLAPSED) {
|
||||||
super.setLightStatusbar(enabled)
|
super.setLightStatusbar(enabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setLightNavigationBar(enabled: Boolean) {
|
override fun setLightNavigationBar(enabled: Boolean) {
|
||||||
lightNavigationBar = enabled
|
lightNavigationBar = enabled
|
||||||
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
if (panelState == STATE_COLLAPSED) {
|
||||||
super.setLightNavigationBar(enabled)
|
super.setLightNavigationBar(enabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setNavigationbarColor(color: Int) {
|
override fun setNavigationbarColor(color: Int) {
|
||||||
navigationBarColor = color
|
navigationBarColor = color
|
||||||
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
if (panelState == STATE_COLLAPSED) {
|
||||||
super.setNavigationbarColor(color)
|
super.setNavigationbarColor(color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setTaskDescriptionColor(color: Int) {
|
override fun setTaskDescriptionColor(color: Int) {
|
||||||
taskColor = color
|
taskColor = color
|
||||||
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
if (panelState == STATE_COLLAPSED) {
|
||||||
super.setTaskDescriptionColor(color)
|
super.setTaskDescriptionColor(color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hideBottomNavigation() {
|
|
||||||
behavior.isHideable = true
|
|
||||||
behavior.peekHeight = 0
|
|
||||||
hideBottomBarVisibility(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateTabs() {
|
fun updateTabs() {
|
||||||
bottomNavigationView.menu.clear()
|
bottomNavigationView.menu.clear()
|
||||||
val currentTabs: List<CategoryInfo> = PreferenceUtil.libraryCategory
|
val currentTabs: List<CategoryInfo> = PreferenceUtil.libraryCategory
|
||||||
|
@ -308,4 +316,74 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
||||||
bottomNavigationView.hide()
|
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
|
package io.github.muntashirakon.music.activities.base
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
@ -37,7 +51,6 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
|
||||||
MaterialDialogsUtil.updateMaterialDialogsThemeSingleton(this)
|
MaterialDialogsUtil.updateMaterialDialogsThemeSingleton(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun updateTheme() {
|
private fun updateTheme() {
|
||||||
setTheme(ThemeManager.getThemeResValue(this))
|
setTheme(ThemeManager.getThemeResValue(this))
|
||||||
setDefaultNightMode(ThemeManager.getNightMode(this))
|
setDefaultNightMode(ThemeManager.getNightMode(this))
|
||||||
|
@ -204,4 +217,4 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
|
||||||
super.attachBaseContext(LanguageContextWrapper.wrap(newBase, Locale(code)))
|
super.attachBaseContext(LanguageContextWrapper.wrap(newBase, Locale(code)))
|
||||||
} else super.attachBaseContext(newBase)
|
} 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
|
package io.github.muntashirakon.music.activities.bugreport
|
||||||
|
|
||||||
import android.app.Activity
|
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.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
|
import java.io.IOException
|
||||||
import kotlinx.android.synthetic.main.activity_bug_report.*
|
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_device_info.*
|
||||||
import kotlinx.android.synthetic.main.bug_report_card_report.*
|
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.GitHubClient
|
||||||
import org.eclipse.egit.github.core.client.RequestException
|
import org.eclipse.egit.github.core.client.RequestException
|
||||||
import org.eclipse.egit.github.core.service.IssueService
|
import org.eclipse.egit.github.core.service.IssueService
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
private const val RESULT_SUCCESS = "RESULT_OK"
|
private const val RESULT_SUCCESS = "RESULT_OK"
|
||||||
private const val RESULT_BAD_CREDENTIALS = "RESULT_BAD_CREDENTIALS"
|
private const val RESULT_BAD_CREDENTIALS = "RESULT_BAD_CREDENTIALS"
|
||||||
|
@ -306,7 +320,6 @@ open class BugReportActivity : AbsThemeActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun report(
|
fun report(
|
||||||
|
|
|
@ -5,129 +5,197 @@ import android.content.Context;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
import androidx.annotation.IntRange;
|
import androidx.annotation.IntRange;
|
||||||
|
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import io.github.muntashirakon.music.util.PreferenceUtil;
|
|
||||||
|
|
||||||
public class DeviceInfo {
|
public class DeviceInfo {
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private final String[] abis = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ?
|
private final String[] abis =
|
||||||
Build.SUPPORTED_ABIS : new String[]{Build.CPU_ABI, Build.CPU_ABI2};
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
|
||||||
|
? Build.SUPPORTED_ABIS
|
||||||
|
: new String[] {Build.CPU_ABI, Build.CPU_ABI2};
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
private final String[] abis32Bits = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ?
|
private final String[] abis32Bits =
|
||||||
Build.SUPPORTED_32_BIT_ABIS : null;
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? Build.SUPPORTED_32_BIT_ABIS : null;
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
private final String[] abis64Bits = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ?
|
private final String[] abis64Bits =
|
||||||
Build.SUPPORTED_64_BIT_ABIS : null;
|
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)
|
@IntRange(from = 0)
|
||||||
private final int sdkVersion = Build.VERSION.SDK_INT;
|
private final int sdkVersion = Build.VERSION.SDK_INT;
|
||||||
|
|
||||||
private final int versionCode;
|
private final int versionCode;
|
||||||
|
|
||||||
private final String versionName;
|
private final String versionName;
|
||||||
private final String selectedLang;
|
private final String selectedLang;
|
||||||
|
|
||||||
public DeviceInfo(Context context) {
|
public DeviceInfo(Context context) {
|
||||||
PackageInfo packageInfo;
|
PackageInfo packageInfo;
|
||||||
try {
|
try {
|
||||||
packageInfo = context.getPackageManager()
|
packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
|
||||||
.getPackageInfo(context.getPackageName(), 0);
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
packageInfo = null;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
if (packageInfo != null) {
|
||||||
public String toMarkdown() {
|
versionCode = packageInfo.versionCode;
|
||||||
return "Device info:\n"
|
versionName = packageInfo.versionName;
|
||||||
+ "---\n"
|
} else {
|
||||||
+ "<table>\n"
|
versionCode = -1;
|
||||||
+ "<tr><td><b>App version</b></td><td>" + versionName + "</td></tr>\n"
|
versionName = null;
|
||||||
+ "<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";
|
|
||||||
}
|
}
|
||||||
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "App version: " + versionName + "\n"
|
return "App version: "
|
||||||
+ "App version code: " + versionCode + "\n"
|
+ versionName
|
||||||
+ "Android build version: " + buildVersion + "\n"
|
+ "\n"
|
||||||
+ "Android release version: " + releaseVersion + "\n"
|
+ "App version code: "
|
||||||
+ "Android SDK version: " + sdkVersion + "\n"
|
+ versionCode
|
||||||
+ "Android build ID: " + buildID + "\n"
|
+ "\n"
|
||||||
+ "Device brand: " + brand + "\n"
|
+ "Android build version: "
|
||||||
+ "Device manufacturer: " + manufacturer + "\n"
|
+ buildVersion
|
||||||
+ "Device name: " + device + "\n"
|
+ "\n"
|
||||||
+ "Device model: " + model + "\n"
|
+ "Android release version: "
|
||||||
+ "Device product name: " + product + "\n"
|
+ releaseVersion
|
||||||
+ "Device hardware name: " + hardware + "\n"
|
+ "\n"
|
||||||
+ "ABIs: " + Arrays.toString(abis) + "\n"
|
+ "Android SDK version: "
|
||||||
+ "ABIs (32bit): " + Arrays.toString(abis32Bits) + "\n"
|
+ sdkVersion
|
||||||
+ "ABIs (64bit): " + Arrays.toString(abis64Bits) + "\n"
|
+ "\n"
|
||||||
+ "Base theme: " + baseTheme + "\n"
|
+ "Android build ID: "
|
||||||
+ "Now playing theme: " + nowPlayingTheme + "\n"
|
+ buildID
|
||||||
+ "Adaptive: " + isAdaptive + "\n"
|
+ "\n"
|
||||||
+ "System language: " + Locale.getDefault().toLanguageTag() + "\n"
|
+ "Device brand: "
|
||||||
+ "In-App Language: " + selectedLang;
|
+ 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;
|
package io.github.muntashirakon.music.activities.bugreport.model;
|
||||||
|
|
||||||
|
|
||||||
import io.github.muntashirakon.music.activities.bugreport.model.github.ExtraInfo;
|
import io.github.muntashirakon.music.activities.bugreport.model.github.ExtraInfo;
|
||||||
|
|
||||||
public class Report {
|
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) {
|
public Report(String title, String description, DeviceInfo deviceInfo, ExtraInfo extraInfo) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.deviceInfo = deviceInfo;
|
this.deviceInfo = deviceInfo;
|
||||||
this.extraInfo = extraInfo;
|
this.extraInfo = extraInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return description + "\n\n"
|
return description
|
||||||
+ "-\n\n"
|
+ "\n\n"
|
||||||
+ deviceInfo.toMarkdown() + "\n\n"
|
+ "-\n\n"
|
||||||
+ extraInfo.toMarkdown();
|
+ deviceInfo.toMarkdown()
|
||||||
}
|
+ "\n\n"
|
||||||
|
+ extraInfo.toMarkdown();
|
||||||
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,58 +5,57 @@ import java.util.Map;
|
||||||
|
|
||||||
public class ExtraInfo {
|
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) {
|
public void put(String key, String value) {
|
||||||
extraInfo.put(key, 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) {
|
StringBuilder output = new StringBuilder();
|
||||||
extraInfo.put(key, Boolean.toString(value));
|
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) {
|
return output.toString();
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,38 +4,37 @@ import android.text.TextUtils;
|
||||||
|
|
||||||
public class GithubLogin {
|
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) {
|
public GithubLogin(String username, String password) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.apiToken = null;
|
this.apiToken = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GithubLogin(String apiToken) {
|
public GithubLogin(String apiToken) {
|
||||||
this.username = null;
|
this.username = null;
|
||||||
this.password = null;
|
this.password = null;
|
||||||
this.apiToken = apiToken;
|
this.apiToken = apiToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getApiToken() {
|
public String getApiToken() {
|
||||||
return apiToken;
|
return apiToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPassword() {
|
public String getPassword() {
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldUseApiToken() {
|
|
||||||
return TextUtils.isEmpty(username) || TextUtils.isEmpty(password);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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 {
|
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) {
|
public GithubTarget(String username, String repository) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRepository() {
|
public String getRepository() {
|
||||||
return repository;
|
return repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,57 +16,58 @@ package io.github.muntashirakon.music.activities.saf;
|
||||||
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import io.github.muntashirakon.music.R;
|
||||||
import com.heinrichreimersoftware.materialintro.app.IntroActivity;
|
import com.heinrichreimersoftware.materialintro.app.IntroActivity;
|
||||||
import com.heinrichreimersoftware.materialintro.slide.SimpleSlide;
|
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 class SAFGuideActivity extends IntroActivity {
|
||||||
|
|
||||||
public static final int REQUEST_CODE_SAF_GUIDE = 98;
|
public static final int REQUEST_CODE_SAF_GUIDE = 98;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
setButtonCtaVisible(false);
|
setButtonCtaVisible(false);
|
||||||
setButtonNextVisible(false);
|
setButtonNextVisible(false);
|
||||||
setButtonBackVisible(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()
|
addSlide(
|
||||||
.title(title)
|
new SimpleSlide.Builder()
|
||||||
.description(Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1
|
.title(title)
|
||||||
? R.string.saf_guide_slide1_description_before_o : R.string.saf_guide_slide1_description)
|
.description(
|
||||||
.image(R.drawable.saf_guide_1)
|
Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1
|
||||||
.background(R.color.md_deep_purple_300)
|
? R.string.saf_guide_slide1_description_before_o
|
||||||
.backgroundDark(R.color.md_deep_purple_400)
|
: R.string.saf_guide_slide1_description)
|
||||||
.layout(R.layout.fragment_simple_slide_large_image)
|
.image(R.drawable.saf_guide_1)
|
||||||
.build());
|
.background(R.color.md_deep_purple_300)
|
||||||
addSlide(new SimpleSlide.Builder()
|
.backgroundDark(R.color.md_deep_purple_400)
|
||||||
.title(R.string.saf_guide_slide2_title)
|
.layout(R.layout.fragment_simple_slide_large_image)
|
||||||
.description(R.string.saf_guide_slide2_description)
|
.build());
|
||||||
.image(R.drawable.saf_guide_2)
|
addSlide(
|
||||||
.background(R.color.md_deep_purple_500)
|
new SimpleSlide.Builder()
|
||||||
.backgroundDark(R.color.md_deep_purple_600)
|
.title(R.string.saf_guide_slide2_title)
|
||||||
.layout(R.layout.fragment_simple_slide_large_image)
|
.description(R.string.saf_guide_slide2_description)
|
||||||
.build());
|
.image(R.drawable.saf_guide_2)
|
||||||
addSlide(new SimpleSlide.Builder()
|
.background(R.color.md_deep_purple_500)
|
||||||
.title(R.string.saf_guide_slide3_title)
|
.backgroundDark(R.color.md_deep_purple_600)
|
||||||
.description(R.string.saf_guide_slide3_description)
|
.layout(R.layout.fragment_simple_slide_large_image)
|
||||||
.image(R.drawable.saf_guide_3)
|
.build());
|
||||||
.background(R.color.md_deep_purple_700)
|
addSlide(
|
||||||
.backgroundDark(R.color.md_deep_purple_800)
|
new SimpleSlide.Builder()
|
||||||
.layout(R.layout.fragment_simple_slide_large_image)
|
.title(R.string.saf_guide_slide3_title)
|
||||||
.build());
|
.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
|
package io.github.muntashirakon.music.activities.tageditor
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.SearchManager
|
import android.app.SearchManager
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.res.ColorStateList
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
@ -16,18 +28,19 @@ import android.view.animation.OvershootInterpolator
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
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 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
|
||||||
import io.github.muntashirakon.music.R.drawable
|
import io.github.muntashirakon.music.R.drawable
|
||||||
import io.github.muntashirakon.music.activities.base.AbsBaseActivity
|
import io.github.muntashirakon.music.activities.base.AbsBaseActivity
|
||||||
import io.github.muntashirakon.music.activities.saf.SAFGuideActivity
|
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.repository.Repository
|
||||||
import io.github.muntashirakon.music.util.RetroUtil
|
import io.github.muntashirakon.music.util.RetroUtil
|
||||||
import io.github.muntashirakon.music.util.SAFUtil
|
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 kotlinx.android.synthetic.main.activity_album_tag_editor.*
|
||||||
import org.jaudiotagger.audio.AudioFile
|
import org.jaudiotagger.audio.AudioFile
|
||||||
import org.jaudiotagger.audio.AudioFileIO
|
import org.jaudiotagger.audio.AudioFileIO
|
||||||
|
@ -49,6 +62,8 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
private val currentSongPath: String? = null
|
private val currentSongPath: String? = null
|
||||||
private var savedTags: Map<FieldKey, String>? = null
|
private var savedTags: Map<FieldKey, String>? = null
|
||||||
private var savedArtworkInfo: ArtworkInfo? = null
|
private var savedArtworkInfo: ArtworkInfo? = null
|
||||||
|
protected abstract val contentViewLayout: Int
|
||||||
|
protected abstract fun loadImageFromFile(selectedFile: Uri?)
|
||||||
|
|
||||||
protected val show: AlertDialog
|
protected val show: AlertDialog
|
||||||
get() =
|
get() =
|
||||||
|
@ -62,7 +77,6 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.show()
|
.show()
|
||||||
protected abstract val contentViewLayout: Int
|
|
||||||
|
|
||||||
internal val albumArtist: String?
|
internal val albumArtist: String?
|
||||||
get() {
|
get() {
|
||||||
|
@ -182,6 +196,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
getIntentExtras()
|
getIntentExtras()
|
||||||
|
|
||||||
songPaths = getSongPaths()
|
songPaths = getSongPaths()
|
||||||
|
println(songPaths?.size)
|
||||||
if (songPaths!!.isEmpty()) {
|
if (songPaths!!.isEmpty()) {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
@ -198,9 +213,9 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
private fun setUpImageView() {
|
private fun setUpImageView() {
|
||||||
loadCurrentImage()
|
loadCurrentImage()
|
||||||
items = listOf(
|
items = listOf(
|
||||||
getString(io.github.muntashirakon.music.R.string.pick_from_local_storage),
|
getString(R.string.pick_from_local_storage),
|
||||||
getString(io.github.muntashirakon.music.R.string.web_search),
|
getString(R.string.web_search),
|
||||||
getString(io.github.muntashirakon.music.R.string.remove_cover)
|
getString(R.string.remove_cover)
|
||||||
)
|
)
|
||||||
editorImage?.setOnClickListener { show }
|
editorImage?.setOnClickListener { show }
|
||||||
}
|
}
|
||||||
|
@ -211,7 +226,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
startActivityForResult(
|
startActivityForResult(
|
||||||
Intent.createChooser(
|
Intent.createChooser(
|
||||||
intent,
|
intent,
|
||||||
getString(io.github.muntashirakon.music.R.string.pick_from_local_storage)
|
getString(R.string.pick_from_local_storage)
|
||||||
), REQUEST_CODE_SELECT_IMAGE
|
), REQUEST_CODE_SELECT_IMAGE
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -223,20 +238,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
protected abstract fun deleteImage()
|
protected abstract fun deleteImage()
|
||||||
|
|
||||||
private fun setUpFab() {
|
private fun setUpFab() {
|
||||||
saveFab.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
|
saveFab.accentColor()
|
||||||
ColorStateList.valueOf(
|
|
||||||
MaterialValueHelper.getPrimaryTextColor(
|
|
||||||
this,
|
|
||||||
ColorUtil.isColorLight(
|
|
||||||
ThemeStore.accentColor(
|
|
||||||
this
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
).apply {
|
|
||||||
saveFab.setTextColor(this)
|
|
||||||
saveFab.iconTint = this
|
|
||||||
}
|
|
||||||
saveFab.apply {
|
saveFab.apply {
|
||||||
scaleX = 0f
|
scaleX = 0f
|
||||||
scaleY = 0f
|
scaleY = 0f
|
||||||
|
@ -324,35 +326,25 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun writeValuesToFiles(
|
protected fun writeValuesToFiles(
|
||||||
fieldKeyValueMap: Map<FieldKey, String>, artworkInfo: ArtworkInfo?
|
fieldKeyValueMap: Map<FieldKey, String>,
|
||||||
|
artworkInfo: ArtworkInfo?
|
||||||
) {
|
) {
|
||||||
RetroUtil.hideSoftKeyboard(this)
|
RetroUtil.hideSoftKeyboard(this)
|
||||||
|
|
||||||
hideFab()
|
hideFab()
|
||||||
|
println(fieldKeyValueMap)
|
||||||
savedSongPaths = songPaths
|
WriteTagsAsyncTask(this).execute(
|
||||||
savedTags = fieldKeyValueMap
|
LoadingInfo(
|
||||||
savedArtworkInfo = artworkInfo
|
songPaths,
|
||||||
|
fieldKeyValueMap,
|
||||||
if (!SAFUtil.isSAFRequired(savedSongPaths)) {
|
artworkInfo
|
||||||
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
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun writeTags(paths: List<String>?) {
|
private fun writeTags(paths: List<String>?) {
|
||||||
WriteTagsAsyncTask(this).execute(
|
WriteTagsAsyncTask(this).execute(
|
||||||
WriteTagsAsyncTask.LoadingInfo(
|
LoadingInfo(
|
||||||
paths,
|
paths,
|
||||||
savedTags,
|
savedTags,
|
||||||
savedArtworkInfo
|
savedArtworkInfo
|
||||||
|
@ -360,6 +352,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
|
||||||
super.onActivityResult(requestCode, resultCode, intent)
|
super.onActivityResult(requestCode, resultCode, intent)
|
||||||
when (requestCode) {
|
when (requestCode) {
|
||||||
|
@ -385,7 +378,6 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun loadImageFromFile(selectedFile: Uri?)
|
|
||||||
|
|
||||||
private fun getAudioFile(path: String): AudioFile {
|
private fun getAudioFile(path: String): AudioFile {
|
||||||
return try {
|
return try {
|
||||||
|
@ -396,7 +388,6 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ArtworkInfo constructor(val albumId: Long, val artwork: Bitmap?)
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
@ -405,5 +396,4 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
private val TAG = AbsTagEditorActivity::class.java.simpleName
|
private val TAG = AbsTagEditorActivity::class.java.simpleName
|
||||||
private const val REQUEST_CODE_SELECT_IMAGE = 1000
|
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
|
package io.github.muntashirakon.music.activities.tageditor
|
||||||
|
|
||||||
import android.app.Activity
|
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.extensions.appHandleColor
|
||||||
import io.github.muntashirakon.music.glide.palette.BitmapPaletteTranscoder
|
import io.github.muntashirakon.music.glide.palette.BitmapPaletteTranscoder
|
||||||
import io.github.muntashirakon.music.glide.palette.BitmapPaletteWrapper
|
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.model.Song
|
||||||
import io.github.muntashirakon.music.util.ImageUtil
|
import io.github.muntashirakon.music.util.ImageUtil
|
||||||
import io.github.muntashirakon.music.util.RetroColorUtil.generatePalette
|
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.load.engine.DiskCacheStrategy
|
||||||
import com.bumptech.glide.request.animation.GlideAnimation
|
import com.bumptech.glide.request.animation.GlideAnimation
|
||||||
import com.bumptech.glide.request.target.SimpleTarget
|
import com.bumptech.glide.request.target.SimpleTarget
|
||||||
|
import java.util.*
|
||||||
import kotlinx.android.synthetic.main.activity_album_tag_editor.*
|
import kotlinx.android.synthetic.main.activity_album_tag_editor.*
|
||||||
import org.jaudiotagger.tag.FieldKey
|
import org.jaudiotagger.tag.FieldKey
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
|
|
||||||
|
@ -155,7 +170,7 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
override fun save() {
|
override fun save() {
|
||||||
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
||||||
fieldKeyValueMap[FieldKey.ALBUM] = albumText.text.toString()
|
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.ARTIST] = albumArtistText.text.toString()
|
||||||
fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = albumArtistText.text.toString()
|
fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = albumArtistText.text.toString()
|
||||||
fieldKeyValueMap[FieldKey.GENRE] = genreTitle.text.toString()
|
fieldKeyValueMap[FieldKey.GENRE] = genreTitle.text.toString()
|
||||||
|
@ -163,8 +178,11 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
|
|
||||||
writeValuesToFiles(
|
writeValuesToFiles(
|
||||||
fieldKeyValueMap,
|
fieldKeyValueMap,
|
||||||
if (deleteAlbumArt) ArtworkInfo(id, null)
|
when {
|
||||||
else if (albumArtBitmap == null) null else ArtworkInfo(id, albumArtBitmap!!)
|
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
|
package io.github.muntashirakon.music.activities.tageditor
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
@ -88,11 +102,7 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
writeValuesToFiles(fieldKeyValueMap, null)
|
writeValuesToFiles(fieldKeyValueMap, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSongPaths(): List<String> {
|
override fun getSongPaths(): List<String> = listOf(songRepository.song(id).data)
|
||||||
val paths = ArrayList<String>(1)
|
|
||||||
paths.add(songRepository.song(id).data)
|
|
||||||
return paths
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun loadImageFromFile(selectedFile: Uri?) {
|
override fun loadImageFromFile(selectedFile: Uri?) {
|
||||||
}
|
}
|
||||||
|
@ -111,5 +121,3 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
val TAG: String = SongTagEditorActivity::class.java.simpleName
|
val TAG: String = SongTagEditorActivity::class.java.simpleName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,67 +5,54 @@ import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.media.MediaScannerConnection;
|
import android.media.MediaScannerConnection;
|
||||||
import android.net.Uri;
|
import android.util.Log;
|
||||||
import android.os.Build;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
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.AudioFile;
|
||||||
import org.jaudiotagger.audio.AudioFileIO;
|
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.FieldKey;
|
||||||
import org.jaudiotagger.tag.Tag;
|
import org.jaudiotagger.tag.Tag;
|
||||||
|
import org.jaudiotagger.tag.TagException;
|
||||||
import org.jaudiotagger.tag.images.Artwork;
|
import org.jaudiotagger.tag.images.Artwork;
|
||||||
import org.jaudiotagger.tag.images.ArtworkFactory;
|
import org.jaudiotagger.tag.images.ArtworkFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.ref.WeakReference;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import io.github.muntashirakon.music.R;
|
import io.github.muntashirakon.music.R;
|
||||||
import io.github.muntashirakon.music.misc.DialogAsyncTask;
|
import io.github.muntashirakon.music.misc.DialogAsyncTask;
|
||||||
import io.github.muntashirakon.music.misc.UpdateToastMediaScannerCompletionListener;
|
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.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(Context context) {
|
||||||
|
super(context);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String[] doInBackground(LoadingInfo... params) {
|
protected List<String> doInBackground(LoadingInfo... params) {
|
||||||
try {
|
try {
|
||||||
LoadingInfo info = params[0];
|
LoadingInfo info = params[0];
|
||||||
|
|
||||||
Artwork artwork = null;
|
Artwork artwork = null;
|
||||||
File albumArtFile = null;
|
File albumArtFile = null;
|
||||||
if (info.artworkInfo != null && info.artworkInfo.getArtwork() != null) {
|
if (info.getArtworkInfo() != null && info.getArtworkInfo().getArtwork() != null) {
|
||||||
try {
|
try {
|
||||||
albumArtFile = MusicUtil.INSTANCE.createAlbumArtFile().getCanonicalFile();
|
albumArtFile = MusicUtil.INSTANCE.createAlbumArtFile().getCanonicalFile();
|
||||||
info.artworkInfo.getArtwork()
|
info.getArtworkInfo().getArtwork().compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
|
||||||
.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
|
|
||||||
artwork = ArtworkFactory.createArtworkFromFile(albumArtFile);
|
artwork = ArtworkFactory.createArtworkFromFile(albumArtFile);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -75,21 +62,14 @@ public class WriteTagsAsyncTask extends DialogAsyncTask<WriteTagsAsyncTask.Loadi
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
boolean wroteArtwork = false;
|
boolean wroteArtwork = false;
|
||||||
boolean deletedArtwork = false;
|
boolean deletedArtwork = false;
|
||||||
for (String filePath : info.filePaths) {
|
for (String filePath : info.getFilePaths()) {
|
||||||
publishProgress(++counter, info.filePaths.size());
|
publishProgress(++counter, info.getFilePaths().size());
|
||||||
try {
|
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));
|
AudioFile audioFile = AudioFileIO.read(new File(filePath));
|
||||||
Tag tag = audioFile.getTagOrCreateAndSetDefault();
|
Tag tag = audioFile.getTagOrCreateAndSetDefault();
|
||||||
|
|
||||||
if (info.fieldKeyValueMap != null) {
|
if (info.getFieldKeyValueMap() != null) {
|
||||||
for (Map.Entry<FieldKey, String> entry : info.fieldKeyValueMap.entrySet()) {
|
for (Map.Entry<FieldKey, String> entry : info.getFieldKeyValueMap().entrySet()) {
|
||||||
try {
|
try {
|
||||||
tag.setField(entry.getKey(), entry.getValue());
|
tag.setField(entry.getKey(), entry.getValue());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -98,8 +78,8 @@ public class WriteTagsAsyncTask extends DialogAsyncTask<WriteTagsAsyncTask.Loadi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.artworkInfo != null) {
|
if (info.getArtworkInfo() != null) {
|
||||||
if (info.artworkInfo.getArtwork() == null) {
|
if (info.getArtworkInfo().getArtwork() == null) {
|
||||||
tag.deleteArtworkField();
|
tag.deleteArtworkField();
|
||||||
deletedArtwork = true;
|
deletedArtwork = true;
|
||||||
} else if (artwork != null) {
|
} else if (artwork != null) {
|
||||||
|
@ -109,10 +89,8 @@ public class WriteTagsAsyncTask extends DialogAsyncTask<WriteTagsAsyncTask.Loadi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Activity activity = this.activity.get();
|
audioFile.commit();
|
||||||
SAFUtil.write(activity, audioFile, safUri);
|
} catch (@NonNull CannotReadException | IOException | CannotWriteException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
|
||||||
|
|
||||||
} catch (@NonNull Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,24 +98,13 @@ public class WriteTagsAsyncTask extends DialogAsyncTask<WriteTagsAsyncTask.Loadi
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
if (wroteArtwork) {
|
if (wroteArtwork) {
|
||||||
MusicUtil.INSTANCE.insertAlbumArt(context, info.artworkInfo.getAlbumId(), albumArtFile.getPath());
|
MusicUtil.INSTANCE.insertAlbumArt(context, info.getArtworkInfo().getAlbumId(), albumArtFile.getPath());
|
||||||
} else if (deletedArtwork) {
|
} else if (deletedArtwork) {
|
||||||
MusicUtil.INSTANCE.deleteAlbumArt(context, info.artworkInfo.getAlbumId());
|
MusicUtil.INSTANCE.deleteAlbumArt(context, info.getArtworkInfo().getAlbumId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<String> paths = info.filePaths;
|
return info.getFilePaths();
|
||||||
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()]);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
|
@ -145,48 +112,40 @@ public class WriteTagsAsyncTask extends DialogAsyncTask<WriteTagsAsyncTask.Loadi
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCancelled(String[] toBeScanned) {
|
protected void onPostExecute(List<String> toBeScanned) {
|
||||||
super.onCancelled(toBeScanned);
|
|
||||||
scan(toBeScanned);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(String[] toBeScanned) {
|
|
||||||
super.onPostExecute(toBeScanned);
|
super.onPostExecute(toBeScanned);
|
||||||
scan(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
|
@Override
|
||||||
protected void onProgressUpdate(@NonNull Dialog dialog, Integer... values) {
|
protected void onProgressUpdate(@NonNull Dialog dialog, Integer... values) {
|
||||||
super.onProgressUpdate(dialog, values);
|
super.onProgressUpdate(dialog, values);
|
||||||
//((MaterialDialog) dialog).setMaxProgress(values[1]);
|
((MaterialDialog) dialog).setMaxProgress(values[1]);
|
||||||
//((MaterialDialog) dialog).setProgress(values[0]);
|
((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.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.google.android.material.checkbox.MaterialCheckBox;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import code.name.monkey.appthemehelper.ThemeStore;
|
import code.name.monkey.appthemehelper.ThemeStore;
|
||||||
import io.github.muntashirakon.music.R;
|
import io.github.muntashirakon.music.R;
|
||||||
import io.github.muntashirakon.music.model.CategoryInfo;
|
import io.github.muntashirakon.music.model.CategoryInfo;
|
||||||
import io.github.muntashirakon.music.util.SwipeAndDragHelper;
|
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>
|
public class CategoryInfoAdapter extends RecyclerView.Adapter<CategoryInfoAdapter.ViewHolder>
|
||||||
implements SwipeAndDragHelper.ActionCompletionContract {
|
implements SwipeAndDragHelper.ActionCompletionContract {
|
||||||
|
|
||||||
private List<CategoryInfo> categoryInfos;
|
private List<CategoryInfo> categoryInfos;
|
||||||
private ItemTouchHelper touchHelper;
|
private ItemTouchHelper touchHelper;
|
||||||
|
|
||||||
public CategoryInfoAdapter() {
|
public CategoryInfoAdapter() {
|
||||||
SwipeAndDragHelper swipeAndDragHelper = new SwipeAndDragHelper(this);
|
SwipeAndDragHelper swipeAndDragHelper = new SwipeAndDragHelper(this);
|
||||||
touchHelper = new ItemTouchHelper(swipeAndDragHelper);
|
touchHelper = new ItemTouchHelper(swipeAndDragHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void attachToRecyclerView(RecyclerView recyclerView) {
|
public void attachToRecyclerView(RecyclerView recyclerView) {
|
||||||
touchHelper.attachToRecyclerView(recyclerView);
|
touchHelper.attachToRecyclerView(recyclerView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public List<CategoryInfo> getCategoryInfos() {
|
public List<CategoryInfo> getCategoryInfos() {
|
||||||
return categoryInfos;
|
return categoryInfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCategoryInfos(@NonNull List<CategoryInfo> categoryInfos) {
|
public void setCategoryInfos(@NonNull List<CategoryInfo> categoryInfos) {
|
||||||
this.categoryInfos = categoryInfos;
|
this.categoryInfos = categoryInfos;
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return categoryInfos.size();
|
return categoryInfos.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull CategoryInfoAdapter.ViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull CategoryInfoAdapter.ViewHolder holder, int position) {
|
||||||
CategoryInfo categoryInfo = categoryInfos.get(position);
|
CategoryInfo categoryInfo = categoryInfos.get(position);
|
||||||
|
|
||||||
holder.checkBox.setChecked(categoryInfo.isVisible());
|
holder.checkBox.setChecked(categoryInfo.isVisible());
|
||||||
holder.title.setText(holder.title.getResources().getString(categoryInfo.getCategory().getStringRes()));
|
holder.title.setText(
|
||||||
|
holder.title.getResources().getString(categoryInfo.getCategory().getStringRes()));
|
||||||
|
|
||||||
holder.itemView.setOnClickListener(v -> {
|
holder.itemView.setOnClickListener(
|
||||||
if (!(categoryInfo.isVisible() && isLastCheckedCategory(categoryInfo))) {
|
v -> {
|
||||||
categoryInfo.setVisible(!categoryInfo.isVisible());
|
if (!(categoryInfo.isVisible() && isLastCheckedCategory(categoryInfo))) {
|
||||||
holder.checkBox.setChecked(categoryInfo.isVisible());
|
categoryInfo.setVisible(!categoryInfo.isVisible());
|
||||||
} else {
|
holder.checkBox.setChecked(categoryInfo.isVisible());
|
||||||
Toast.makeText(holder.itemView.getContext(), R.string.you_have_to_select_at_least_one_category,
|
} else {
|
||||||
Toast.LENGTH_SHORT).show();
|
Toast.makeText(
|
||||||
}
|
holder.itemView.getContext(),
|
||||||
|
R.string.you_have_to_select_at_least_one_category,
|
||||||
|
Toast.LENGTH_SHORT)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
holder.dragView.setOnTouchListener((view, event) -> {
|
holder.dragView.setOnTouchListener(
|
||||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
(view, event) -> {
|
||||||
touchHelper.startDrag(holder);
|
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
||||||
}
|
touchHelper.startDrag(holder);
|
||||||
return false;
|
}
|
||||||
}
|
return false;
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NonNull
|
@NonNull
|
||||||
public CategoryInfoAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
public CategoryInfoAdapter.ViewHolder onCreateViewHolder(
|
||||||
View view = LayoutInflater.from(parent.getContext())
|
@NonNull ViewGroup parent, int viewType) {
|
||||||
.inflate(R.layout.preference_dialog_library_categories_listitem, parent, false);
|
View view =
|
||||||
return new ViewHolder(view);
|
LayoutInflater.from(parent.getContext())
|
||||||
}
|
.inflate(R.layout.preference_dialog_library_categories_listitem, parent, false);
|
||||||
|
return new ViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewMoved(int oldPosition, int newPosition) {
|
public void onViewMoved(int oldPosition, int newPosition) {
|
||||||
CategoryInfo categoryInfo = categoryInfos.get(oldPosition);
|
CategoryInfo categoryInfo = categoryInfos.get(oldPosition);
|
||||||
categoryInfos.remove(oldPosition);
|
categoryInfos.remove(oldPosition);
|
||||||
categoryInfos.add(newPosition, categoryInfo);
|
categoryInfos.add(newPosition, categoryInfo);
|
||||||
notifyItemMoved(oldPosition, newPosition);
|
notifyItemMoved(oldPosition, newPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isLastCheckedCategory(CategoryInfo categoryInfo) {
|
private boolean isLastCheckedCategory(CategoryInfo categoryInfo) {
|
||||||
if (categoryInfo.isVisible()) {
|
if (categoryInfo.isVisible()) {
|
||||||
for (CategoryInfo c : categoryInfos) {
|
for (CategoryInfo c : categoryInfos) {
|
||||||
if (c != categoryInfo && c.isVisible()) {
|
if (c != categoryInfo && c.isVisible()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
private MaterialCheckBox checkBox;
|
private MaterialCheckBox checkBox;
|
||||||
private View dragView;
|
private View dragView;
|
||||||
private TextView title;
|
private TextView title;
|
||||||
|
|
||||||
ViewHolder(View view) {
|
ViewHolder(View view) {
|
||||||
super(view);
|
super(view);
|
||||||
checkBox = view.findViewById(R.id.checkbox);
|
checkBox = view.findViewById(R.id.checkbox);
|
||||||
checkBox.setButtonTintList(
|
checkBox.setButtonTintList(
|
||||||
ColorStateList.valueOf(ThemeStore.Companion.accentColor(checkBox.getContext())));
|
ColorStateList.valueOf(ThemeStore.Companion.accentColor(checkBox.getContext())));
|
||||||
title = view.findViewById(R.id.title);
|
title = view.findViewById(R.id.title);
|
||||||
dragView = view.findViewById(R.id.drag_view);
|
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
|
package io.github.muntashirakon.music.adapter
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
@ -59,6 +73,11 @@ class ContributorAdapter(
|
||||||
return contributors.size
|
return contributors.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun swapData(it: List<Contributor>) {
|
||||||
|
contributors = it
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
val title: TextView = itemView.findViewById(R.id.title)
|
val title: TextView = itemView.findViewById(R.id.title)
|
||||||
val text: TextView = itemView.findViewById(R.id.text)
|
val text: TextView = itemView.findViewById(R.id.text)
|
||||||
|
@ -68,7 +87,7 @@ class ContributorAdapter(
|
||||||
title.text = contributor.name
|
title.text = contributor.name
|
||||||
text.text = contributor.summary
|
text.text = contributor.summary
|
||||||
Glide.with(image.context)
|
Glide.with(image.context)
|
||||||
.load(contributor.profileImage)
|
.load(contributor.image)
|
||||||
.error(R.drawable.ic_account)
|
.error(R.drawable.ic_account)
|
||||||
.placeholder(R.drawable.ic_account)
|
.placeholder(R.drawable.ic_account)
|
||||||
.dontAnimate()
|
.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
|
package io.github.muntashirakon.music.adapter
|
||||||
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -23,14 +36,12 @@ class GenreAdapter(
|
||||||
var dataSet: List<Genre>,
|
var dataSet: List<Genre>,
|
||||||
private val mItemLayoutRes: Int
|
private val mItemLayoutRes: Int
|
||||||
) : RecyclerView.Adapter<GenreAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<GenreAdapter.ViewHolder>() {
|
||||||
val colors = listOf<Int>(Color.RED, Color.BLUE)
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
return ViewHolder(LayoutInflater.from(activity).inflate(mItemLayoutRes, parent, false))
|
return ViewHolder(LayoutInflater.from(activity).inflate(mItemLayoutRes, parent, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val genre = dataSet[position]
|
val genre = dataSet[position]
|
||||||
|
|
||||||
holder.title?.text = genre.name
|
holder.title?.text = genre.name
|
||||||
holder.text?.text = String.format(
|
holder.text?.text = String.format(
|
||||||
Locale.getDefault(),
|
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
|
package io.github.muntashirakon.music.adapter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -15,23 +29,23 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
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.*
|
||||||
import io.github.muntashirakon.music.adapter.album.AlbumAdapter
|
import io.github.muntashirakon.music.adapter.album.AlbumAdapter
|
||||||
import io.github.muntashirakon.music.adapter.artist.ArtistAdapter
|
import io.github.muntashirakon.music.adapter.artist.ArtistAdapter
|
||||||
import io.github.muntashirakon.music.adapter.song.SongAdapter
|
import io.github.muntashirakon.music.adapter.song.SongAdapter
|
||||||
import io.github.muntashirakon.music.extensions.hide
|
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.glide.SongGlideRequest
|
||||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
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.model.*
|
||||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.google.android.material.card.MaterialCardView
|
||||||
|
|
||||||
class HomeAdapter(
|
class HomeAdapter(
|
||||||
private val activity: AppCompatActivity
|
private val activity: AppCompatActivity
|
||||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), ArtistClickListener, AlbumClickListener {
|
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), IArtistClickListener, IAlbumClickListener {
|
||||||
|
|
||||||
private var list = listOf<Home>()
|
private var list = listOf<Home>()
|
||||||
|
|
||||||
|
@ -121,7 +135,6 @@ class HomeAdapter(
|
||||||
viewHolder.bind(home)
|
viewHolder.bind(home)
|
||||||
}
|
}
|
||||||
PLAYLISTS -> {
|
PLAYLISTS -> {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,7 +194,6 @@ class HomeAdapter(
|
||||||
.asBitmap()
|
.asBitmap()
|
||||||
.build()
|
.build()
|
||||||
.into(itemView.findViewById(id))
|
.into(itemView.findViewById(id))
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,21 +237,22 @@ class HomeAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun artistsAdapter(artists: List<Artist>) =
|
fun artistsAdapter(artists: List<Artist>) =
|
||||||
ArtistAdapter(activity, artists, PreferenceUtil.homeGridStyle, null, this)
|
ArtistAdapter(activity, artists, PreferenceUtil.homeArtistGridStyle, null, this)
|
||||||
|
|
||||||
fun albumAdapter(albums: List<Album>) =
|
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 gridLayoutManager() = GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
|
||||||
|
|
||||||
fun linearLayoutManager() = LinearLayoutManager(activity, LinearLayoutManager.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(
|
activity.findNavController(R.id.fragment_container).navigate(
|
||||||
R.id.artistDetailsFragment,
|
R.id.artistDetailsFragment,
|
||||||
bundleOf(EXTRA_ARTIST_ID to artistId),
|
bundleOf(EXTRA_ARTIST_ID to artistId),
|
||||||
null,
|
null,
|
||||||
FragmentNavigatorExtras(
|
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),
|
bundleOf(EXTRA_ALBUM_ID to albumId),
|
||||||
null,
|
null,
|
||||||
FragmentNavigatorExtras(
|
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
|
package io.github.muntashirakon.music.adapter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
|
import androidx.core.view.isInvisible
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import com.bumptech.glide.Glide
|
|
||||||
import io.github.muntashirakon.music.*
|
import io.github.muntashirakon.music.*
|
||||||
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
|
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.AlbumGlideRequest
|
||||||
import io.github.muntashirakon.music.glide.ArtistGlideRequest
|
import io.github.muntashirakon.music.glide.ArtistGlideRequest
|
||||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
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.model.smartplaylist.AbsSmartPlaylist
|
||||||
import io.github.muntashirakon.music.repository.PlaylistSongsLoader
|
import io.github.muntashirakon.music.repository.PlaylistSongsLoader
|
||||||
import io.github.muntashirakon.music.util.MusicUtil
|
import io.github.muntashirakon.music.util.MusicUtil
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class SearchAdapter(
|
class SearchAdapter(
|
||||||
private val activity: FragmentActivity,
|
private val activity: FragmentActivity,
|
||||||
private var dataSet: List<Any>
|
private var dataSet: List<Any>
|
||||||
) : RecyclerView.Adapter<SearchAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<SearchAdapter.ViewHolder>() {
|
||||||
|
|
||||||
fun swapDataSet(dataSet: MutableList<Any>) {
|
fun swapDataSet(dataSet: List<Any>) {
|
||||||
this.dataSet = dataSet
|
this.dataSet = dataSet
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
@ -34,7 +52,7 @@ class SearchAdapter(
|
||||||
if (dataSet[position] is Album) return ALBUM
|
if (dataSet[position] is Album) return ALBUM
|
||||||
if (dataSet[position] is Artist) return ARTIST
|
if (dataSet[position] is Artist) return ARTIST
|
||||||
if (dataSet[position] is Genre) return GENRE
|
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
|
return if (dataSet[position] is Song) SONG else HEADER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,42 +74,52 @@ class SearchAdapter(
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
when (getItemViewType(position)) {
|
when (getItemViewType(position)) {
|
||||||
ALBUM -> {
|
ALBUM -> {
|
||||||
val album = dataSet.get(position) as Album
|
holder.imageTextContainer?.isVisible = true
|
||||||
|
val album = dataSet[position] as Album
|
||||||
holder.title?.text = album.title
|
holder.title?.text = album.title
|
||||||
holder.text?.text = album.artistName
|
holder.text?.text = album.artistName
|
||||||
AlbumGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
AlbumGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||||
.checkIgnoreMediaStore().build().into(holder.image)
|
.checkIgnoreMediaStore().build().into(holder.image)
|
||||||
}
|
}
|
||||||
ARTIST -> {
|
ARTIST -> {
|
||||||
val artist = dataSet.get(position) as Artist
|
holder.imageTextContainer?.isVisible = true
|
||||||
|
val artist = dataSet[position] as Artist
|
||||||
holder.title?.text = artist.name
|
holder.title?.text = artist.name
|
||||||
holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
|
holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
|
||||||
ArtistGlideRequest.Builder.from(Glide.with(activity), artist).build()
|
ArtistGlideRequest.Builder.from(Glide.with(activity), artist).build()
|
||||||
.into(holder.image)
|
.into(holder.image)
|
||||||
}
|
}
|
||||||
SONG -> {
|
SONG -> {
|
||||||
val song = dataSet.get(position) as Song
|
val song = dataSet[position] as Song
|
||||||
holder.title?.text = song.title
|
holder.title?.text = song.title
|
||||||
holder.text?.text = song.albumName
|
holder.text?.text = song.albumName
|
||||||
}
|
}
|
||||||
GENRE -> {
|
GENRE -> {
|
||||||
val genre = dataSet.get(position) as Genre
|
val genre = dataSet[position] as Genre
|
||||||
holder.title?.text = genre.name
|
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 -> {
|
PLAYLIST -> {
|
||||||
val playlist = dataSet.get(position) as Playlist
|
val playlist = dataSet[position] as PlaylistWithSongs
|
||||||
holder.title?.text = playlist.name
|
holder.title?.text = playlist.playlistEntity.playlistName
|
||||||
holder.text?.text = MusicUtil.getPlaylistInfoString(activity, getSongs(playlist))
|
holder.text?.text = MusicUtil.playlistInfoString(activity, playlist.songs)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
holder.title?.text = dataSet.get(position).toString()
|
holder.title?.text = dataSet[position].toString()
|
||||||
holder.title?.setTextColor(ThemeStore.accentColor(activity))
|
holder.title?.setTextColor(ThemeStore.accentColor(activity))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSongs(playlist: Playlist): java.util.ArrayList<Song> {
|
private fun getSongs(playlist: Playlist): List<Song> {
|
||||||
val songs = java.util.ArrayList<Song>()
|
val songs = mutableListOf<Song>()
|
||||||
if (playlist is AbsSmartPlaylist) {
|
if (playlist is AbsSmartPlaylist) {
|
||||||
songs.addAll(playlist.getSongs())
|
songs.addAll(playlist.getSongs())
|
||||||
} else {
|
} else {
|
||||||
|
@ -107,7 +135,7 @@ class SearchAdapter(
|
||||||
inner class ViewHolder(itemView: View, itemViewType: Int) : MediaEntryViewHolder(itemView) {
|
inner class ViewHolder(itemView: View, itemViewType: Int) : MediaEntryViewHolder(itemView) {
|
||||||
init {
|
init {
|
||||||
itemView.setOnLongClickListener(null)
|
itemView.setOnLongClickListener(null)
|
||||||
|
imageTextContainer?.isInvisible = true
|
||||||
if (itemViewType == SONG) {
|
if (itemViewType == SONG) {
|
||||||
menu?.visibility = View.VISIBLE
|
menu?.visibility = View.VISIBLE
|
||||||
menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
|
menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
|
||||||
|
@ -151,12 +179,12 @@ class SearchAdapter(
|
||||||
}
|
}
|
||||||
PLAYLIST -> {
|
PLAYLIST -> {
|
||||||
activity.findNavController(R.id.fragment_container).navigate(
|
activity.findNavController(R.id.fragment_container).navigate(
|
||||||
R.id.artistDetailsFragment,
|
R.id.playlistDetailsFragment,
|
||||||
bundleOf(EXTRA_PLAYLIST to (item as Playlist))
|
bundleOf(EXTRA_PLAYLIST to (item as PlaylistWithSongs))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
SONG -> {
|
SONG -> {
|
||||||
val playList = ArrayList<Song>()
|
val playList = mutableListOf<Song>()
|
||||||
playList.add(item as Song)
|
playList.add(item as Song)
|
||||||
MusicPlayerRemote.openQueue(playList, 0, true)
|
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");
|
* Licensed under the GNU General Public License v3
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* 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
|
package io.github.muntashirakon.music.adapter
|
||||||
|
|
||||||
|
@ -22,31 +21,31 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
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.R
|
||||||
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
||||||
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
|
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
|
||||||
import io.github.muntashirakon.music.glide.audiocover.AudioFileCover
|
import io.github.muntashirakon.music.glide.audiocover.AudioFileCover
|
||||||
import io.github.muntashirakon.music.interfaces.CabHolder
|
import io.github.muntashirakon.music.interfaces.ICabHolder
|
||||||
import io.github.muntashirakon.music.interfaces.Callbacks
|
import io.github.muntashirakon.music.interfaces.ICallbacks
|
||||||
import io.github.muntashirakon.music.util.MusicUtil
|
import io.github.muntashirakon.music.util.MusicUtil
|
||||||
import io.github.muntashirakon.music.util.RetroUtil
|
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.io.File
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
import kotlin.math.log10
|
import kotlin.math.log10
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||||
|
|
||||||
class SongFileAdapter(
|
class SongFileAdapter(
|
||||||
private val activity: AppCompatActivity,
|
private val activity: AppCompatActivity,
|
||||||
private var dataSet: List<File>,
|
private var dataSet: List<File>,
|
||||||
private val itemLayoutRes: Int,
|
private val itemLayoutRes: Int,
|
||||||
private val callbacks: Callbacks?,
|
private val ICallbacks: ICallbacks?,
|
||||||
cabHolder: CabHolder?
|
ICabHolder: ICabHolder?
|
||||||
) : AbsMultiSelectAdapter<SongFileAdapter.ViewHolder, File>(
|
) : AbsMultiSelectAdapter<SongFileAdapter.ViewHolder, File>(
|
||||||
activity, cabHolder, R.menu.menu_media_selection
|
activity, ICabHolder, R.menu.menu_media_selection
|
||||||
), PopupTextProvider {
|
), PopupTextProvider {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -136,8 +135,8 @@ class SongFileAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMultipleItemAction(menuItem: MenuItem, selection: List<File>) {
|
override fun onMultipleItemAction(menuItem: MenuItem, selection: List<File>) {
|
||||||
if (callbacks == null) return
|
if (ICallbacks == null) return
|
||||||
callbacks.onMultipleItemAction(menuItem, selection as ArrayList<File>)
|
ICallbacks.onMultipleItemAction(menuItem, selection as ArrayList<File>)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPopupText(position: Int): String {
|
override fun getPopupText(position: Int): String {
|
||||||
|
@ -148,15 +147,14 @@ class SongFileAdapter(
|
||||||
return MusicUtil.getSectionName(dataSet[position].name)
|
return MusicUtil.getSectionName(dataSet[position].name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (menu != null && callbacks != null) {
|
if (menu != null && ICallbacks != null) {
|
||||||
menu?.setOnClickListener { v ->
|
menu?.setOnClickListener { v ->
|
||||||
val position = layoutPosition
|
val position = layoutPosition
|
||||||
if (isPositionInRange(position)) {
|
if (isPositionInRange(position)) {
|
||||||
callbacks.onFileMenuClicked(dataSet[position], v)
|
ICallbacks.onFileMenuClicked(dataSet[position], v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,7 +169,7 @@ class SongFileAdapter(
|
||||||
if (isInQuickSelectMode) {
|
if (isInQuickSelectMode) {
|
||||||
toggleChecked(position)
|
toggleChecked(position)
|
||||||
} else {
|
} 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]
|
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
|
package io.github.muntashirakon.music.adapter
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
@ -49,4 +63,4 @@ class TranslatorsAdapter(
|
||||||
image.hide()
|
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
|
package io.github.muntashirakon.music.adapter.album
|
||||||
|
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
|
@ -6,7 +20,23 @@ import android.view.LayoutInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.fragment.app.FragmentActivity
|
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 com.bumptech.glide.Glide
|
||||||
import io.github.muntashirakon.music.R
|
import io.github.muntashirakon.music.R
|
||||||
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
||||||
|
@ -29,11 +59,11 @@ open class AlbumAdapter(
|
||||||
protected val activity: FragmentActivity,
|
protected val activity: FragmentActivity,
|
||||||
var dataSet: List<Album>,
|
var dataSet: List<Album>,
|
||||||
protected var itemLayoutRes: Int,
|
protected var itemLayoutRes: Int,
|
||||||
cabHolder: CabHolder?,
|
ICabHolder: ICabHolder?,
|
||||||
private val albumClickListener: AlbumClickListener?
|
private val albumClickListener: IAlbumClickListener?
|
||||||
) : AbsMultiSelectAdapter<AlbumAdapter.ViewHolder, Album>(
|
) : AbsMultiSelectAdapter<AlbumAdapter.ViewHolder, Album>(
|
||||||
activity,
|
activity,
|
||||||
cabHolder,
|
ICabHolder,
|
||||||
R.menu.menu_media_selection
|
R.menu.menu_media_selection
|
||||||
), PopupTextProvider {
|
), PopupTextProvider {
|
||||||
|
|
||||||
|
@ -75,7 +105,7 @@ open class AlbumAdapter(
|
||||||
holder.title?.text = getAlbumTitle(album)
|
holder.title?.text = getAlbumTitle(album)
|
||||||
holder.text?.text = getAlbumText(album)
|
holder.text?.text = getAlbumText(album)
|
||||||
holder.playSongs?.setOnClickListener {
|
holder.playSongs?.setOnClickListener {
|
||||||
album.songs?.let { songs ->
|
album.songs.let { songs ->
|
||||||
MusicPlayerRemote.openQueue(
|
MusicPlayerRemote.openQueue(
|
||||||
songs,
|
songs,
|
||||||
0,
|
0,
|
||||||
|
@ -116,7 +146,7 @@ open class AlbumAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemId(position: Int): Long {
|
override fun getItemId(position: Int): Long {
|
||||||
return dataSet[position].id.toLong()
|
return dataSet[position].id
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIdentifier(position: Int): Album? {
|
override fun getIdentifier(position: Int): Album? {
|
||||||
|
@ -128,7 +158,8 @@ open class AlbumAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMultipleItemAction(
|
override fun onMultipleItemAction(
|
||||||
menuItem: MenuItem, selection: List<Album>
|
menuItem: MenuItem,
|
||||||
|
selection: List<Album>
|
||||||
) {
|
) {
|
||||||
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
|
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
|
||||||
}
|
}
|
||||||
|
@ -161,7 +192,7 @@ open class AlbumAdapter(
|
||||||
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setImageTransitionName(activity.getString(R.string.transition_album_art))
|
setImageTransitionName("Album")
|
||||||
menu?.visibility = View.GONE
|
menu?.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +201,7 @@ open class AlbumAdapter(
|
||||||
if (isInQuickSelectMode) {
|
if (isInQuickSelectMode) {
|
||||||
toggleChecked(layoutPosition)
|
toggleChecked(layoutPosition)
|
||||||
} else {
|
} else {
|
||||||
|
ViewCompat.setTransitionName(itemView, "album")
|
||||||
albumClickListener?.onAlbumClick(dataSet[layoutPosition].id, itemView)
|
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
|
package io.github.muntashirakon.music.adapter.album
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
@ -5,6 +19,7 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
@ -88,9 +103,9 @@ class AlbumCoverPagerAdapter(
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
val view = inflater.inflate(getLayoutWithPlayerTheme(), container, false)
|
val view = inflater.inflate(getLayoutWithPlayerTheme(), container, false)
|
||||||
|
ViewCompat.setTransitionName(view, "lyrics")
|
||||||
albumCover = view.findViewById(R.id.player_image)
|
albumCover = view.findViewById(R.id.player_image)
|
||||||
albumCover.setOnClickListener {
|
view.setOnClickListener {
|
||||||
//LyricsDialog().show(childFragmentManager, "LyricsDialog")
|
|
||||||
showLyricsDialog()
|
showLyricsDialog()
|
||||||
}
|
}
|
||||||
return view
|
return view
|
||||||
|
@ -98,14 +113,14 @@ class AlbumCoverPagerAdapter(
|
||||||
|
|
||||||
private fun showLyricsDialog() {
|
private fun showLyricsDialog() {
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
val data: String = MusicUtil.getLyrics(song) ?: "No lyrics found"
|
val data: String? = MusicUtil.getLyrics(song)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
MaterialAlertDialogBuilder(
|
MaterialAlertDialogBuilder(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
R.style.ThemeOverlay_MaterialComponents_Dialog_Alert
|
R.style.ThemeOverlay_MaterialComponents_Dialog_Alert
|
||||||
).apply {
|
).apply {
|
||||||
setTitle(song.title)
|
setTitle(song.title)
|
||||||
setMessage(data)
|
setMessage(if (data.isNullOrEmpty()) "No lyrics found" else data)
|
||||||
setNegativeButton(R.string.synced_lyrics) { _, _ ->
|
setNegativeButton(R.string.synced_lyrics) { _, _ ->
|
||||||
NavigationUtil.goToLyrics(requireActivity())
|
NavigationUtil.goToLyrics(requireActivity())
|
||||||
}
|
}
|
||||||
|
@ -197,4 +212,3 @@ class AlbumCoverPagerAdapter(
|
||||||
val TAG: String = AlbumCoverPagerAdapter::class.java.simpleName
|
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
|
package io.github.muntashirakon.music.adapter.album
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.FragmentActivity
|
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.AlbumGlideRequest
|
||||||
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
|
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
|
||||||
import io.github.muntashirakon.music.helper.HorizontalAdapterHelper
|
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.model.Album
|
||||||
import io.github.muntashirakon.music.util.MusicUtil
|
import io.github.muntashirakon.music.util.MusicUtil
|
||||||
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
|
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
|
||||||
|
@ -16,10 +30,10 @@ import com.bumptech.glide.Glide
|
||||||
class HorizontalAlbumAdapter(
|
class HorizontalAlbumAdapter(
|
||||||
activity: FragmentActivity,
|
activity: FragmentActivity,
|
||||||
dataSet: List<Album>,
|
dataSet: List<Album>,
|
||||||
cabHolder: CabHolder?,
|
ICabHolder: ICabHolder?,
|
||||||
albumClickListener: AlbumClickListener
|
albumClickListener: IAlbumClickListener
|
||||||
) : AlbumAdapter(
|
) : AlbumAdapter(
|
||||||
activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, cabHolder, albumClickListener
|
activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, ICabHolder, albumClickListener
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun createViewHolder(view: View, viewType: Int): ViewHolder {
|
override fun createViewHolder(view: View, viewType: Int): ViewHolder {
|
||||||
|
@ -29,8 +43,8 @@ class HorizontalAlbumAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setColors(color: MediaNotificationProcessor, holder: ViewHolder) {
|
override fun setColors(color: MediaNotificationProcessor, holder: ViewHolder) {
|
||||||
//holder.title?.setTextColor(ATHUtil.resolveColor(activity, android.R.attr.textColorPrimary))
|
// holder.title?.setTextColor(ATHUtil.resolveColor(activity, android.R.attr.textColorPrimary))
|
||||||
//holder.text?.setTextColor(ATHUtil.resolveColor(activity, android.R.attr.textColorSecondary))
|
// holder.text?.setTextColor(ATHUtil.resolveColor(activity, android.R.attr.textColorSecondary))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadAlbumCover(album: Album, holder: ViewHolder) {
|
override fun loadAlbumCover(album: Album, holder: ViewHolder) {
|
||||||
|
@ -51,7 +65,7 @@ class HorizontalAlbumAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
return HorizontalAdapterHelper.getItemViewtype(position, itemCount)
|
return HorizontalAdapterHelper.getItemViewType(position, itemCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
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
|
package io.github.muntashirakon.music.adapter.artist
|
||||||
|
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
|
@ -8,31 +22,31 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import com.bumptech.glide.Glide
|
|
||||||
import io.github.muntashirakon.music.R
|
import io.github.muntashirakon.music.R
|
||||||
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
||||||
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
|
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
|
||||||
import io.github.muntashirakon.music.extensions.hide
|
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.ArtistGlideRequest
|
||||||
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
|
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
|
||||||
import io.github.muntashirakon.music.helper.menu.SongsMenuHelper
|
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.Artist
|
||||||
import io.github.muntashirakon.music.model.Song
|
import io.github.muntashirakon.music.model.Song
|
||||||
import io.github.muntashirakon.music.util.MusicUtil
|
import io.github.muntashirakon.music.util.MusicUtil
|
||||||
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
|
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
|
||||||
import me.zhanghai.android.fastscroll.PopupTextProvider
|
import com.bumptech.glide.Glide
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||||
|
|
||||||
class ArtistAdapter(
|
class ArtistAdapter(
|
||||||
val activity: FragmentActivity,
|
val activity: FragmentActivity,
|
||||||
var dataSet: List<Artist>,
|
var dataSet: List<Artist>,
|
||||||
var itemLayoutRes: Int,
|
var itemLayoutRes: Int,
|
||||||
cabHolder: CabHolder?,
|
val ICabHolder: ICabHolder?,
|
||||||
private val artistClickListener: ArtistClickListener
|
val IArtistClickListener: IArtistClickListener
|
||||||
) : AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist>(
|
) : AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist>(
|
||||||
activity, cabHolder, R.menu.menu_media_selection
|
activity, ICabHolder, R.menu.menu_media_selection
|
||||||
), PopupTextProvider {
|
), PopupTextProvider {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -45,7 +59,7 @@ class ArtistAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemId(position: Int): Long {
|
override fun getItemId(position: Int): Long {
|
||||||
return dataSet[position].id.toLong()
|
return dataSet[position].id
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
@ -107,7 +121,8 @@ class ArtistAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMultipleItemAction(
|
override fun onMultipleItemAction(
|
||||||
menuItem: MenuItem, selection: List<Artist>
|
menuItem: MenuItem,
|
||||||
|
selection: List<Artist>
|
||||||
) {
|
) {
|
||||||
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
|
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
|
||||||
}
|
}
|
||||||
|
@ -140,11 +155,8 @@ class ArtistAdapter(
|
||||||
toggleChecked(layoutPosition)
|
toggleChecked(layoutPosition)
|
||||||
} else {
|
} else {
|
||||||
image?.let {
|
image?.let {
|
||||||
ViewCompat.setTransitionName(
|
ViewCompat.setTransitionName(itemView, "album")
|
||||||
it,
|
IArtistClickListener.onArtist(dataSet[layoutPosition].id, itemView)
|
||||||
activity.getString(R.string.transition_artist_image)
|
|
||||||
)
|
|
||||||
artistClickListener.onArtist(dataSet[layoutPosition].id, it)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,132 +3,127 @@ package io.github.muntashirakon.music.adapter.base;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
import androidx.annotation.MenuRes;
|
import androidx.annotation.MenuRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import io.github.muntashirakon.music.R;
|
||||||
|
import io.github.muntashirakon.music.interfaces.ICabHolder;
|
||||||
import com.afollestad.materialcab.MaterialCab;
|
import com.afollestad.materialcab.MaterialCab;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import io.github.muntashirakon.music.R;
|
public abstract class AbsMultiSelectAdapter<V extends RecyclerView.ViewHolder, I>
|
||||||
import io.github.muntashirakon.music.interfaces.CabHolder;
|
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>
|
public AbsMultiSelectAdapter(
|
||||||
implements MaterialCab.Callback {
|
@NonNull Context context, @Nullable ICabHolder ICabHolder, @MenuRes int menuRes) {
|
||||||
|
this.ICabHolder = ICabHolder;
|
||||||
|
checked = new ArrayList<>();
|
||||||
|
this.menuRes = menuRes;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Override
|
||||||
private final CabHolder cabHolder;
|
public boolean onCabCreated(MaterialCab materialCab, Menu menu) {
|
||||||
private final Context context;
|
return true;
|
||||||
private MaterialCab cab;
|
}
|
||||||
private List<I> checked;
|
|
||||||
private int menuRes;
|
|
||||||
|
|
||||||
public AbsMultiSelectAdapter(@NonNull Context context, @Nullable CabHolder cabHolder, @MenuRes int menuRes) {
|
@Override
|
||||||
this.cabHolder = cabHolder;
|
public boolean onCabFinished(MaterialCab materialCab) {
|
||||||
checked = new ArrayList<>();
|
clearChecked();
|
||||||
this.menuRes = menuRes;
|
return true;
|
||||||
this.context = context;
|
}
|
||||||
|
|
||||||
|
@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
|
protected void checkAll() {
|
||||||
public boolean onCabCreated(MaterialCab materialCab, Menu menu) {
|
if (ICabHolder != null) {
|
||||||
return true;
|
checked.clear();
|
||||||
}
|
for (int i = 0; i < getItemCount(); i++) {
|
||||||
|
I identifier = getIdentifier(i);
|
||||||
@Override
|
if (identifier != null) {
|
||||||
public boolean onCabFinished(MaterialCab materialCab) {
|
checked.add(identifier);
|
||||||
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;
|
}
|
||||||
|
notifyDataSetChanged();
|
||||||
|
updateCab();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void checkAll() {
|
@Nullable
|
||||||
if (cabHolder != null) {
|
protected abstract I getIdentifier(int position);
|
||||||
checked.clear();
|
|
||||||
for (int i = 0; i < getItemCount(); i++) {
|
|
||||||
I identifier = getIdentifier(i);
|
|
||||||
if (identifier != null) {
|
|
||||||
checked.add(identifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
notifyDataSetChanged();
|
|
||||||
updateCab();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
protected String getName(I object) {
|
||||||
protected abstract I getIdentifier(int position);
|
return object.toString();
|
||||||
|
}
|
||||||
|
|
||||||
protected String getName(I object) {
|
protected boolean isChecked(I identifier) {
|
||||||
return object.toString();
|
return checked.contains(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isChecked(I identifier) {
|
protected boolean isInQuickSelectMode() {
|
||||||
return checked.contains(identifier);
|
return cab != null && cab.isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isInQuickSelectMode() {
|
protected abstract void onMultipleItemAction(MenuItem menuItem, List<I> selection);
|
||||||
return cab != null && cab.isActive();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void onMultipleItemAction(MenuItem menuItem, List<I> selection);
|
protected void setMultiSelectMenuRes(@MenuRes int menuRes) {
|
||||||
|
this.menuRes = menuRes;
|
||||||
|
}
|
||||||
|
|
||||||
protected void setMultiSelectMenuRes(@MenuRes int menuRes) {
|
protected boolean toggleChecked(final int position) {
|
||||||
this.menuRes = menuRes;
|
if (ICabHolder != null) {
|
||||||
}
|
I identifier = getIdentifier(position);
|
||||||
|
if (identifier == null) {
|
||||||
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;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearChecked() {
|
if (!checked.remove(identifier)) {
|
||||||
checked.clear();
|
checked.add(identifier);
|
||||||
notifyDataSetChanged();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void updateCab() {
|
notifyItemChanged(position);
|
||||||
if (cabHolder != null) {
|
updateCab();
|
||||||
if (cab == null || !cab.isActive()) {
|
return true;
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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.graphics.Color;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import io.github.muntashirakon.music.R;
|
||||||
import com.google.android.material.card.MaterialCardView;
|
import com.google.android.material.card.MaterialCardView;
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractDraggableSwipeableItemViewHolder;
|
import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractDraggableSwipeableItemViewHolder;
|
||||||
|
|
||||||
import io.github.muntashirakon.music.R;
|
|
||||||
|
|
||||||
public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHolder
|
public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHolder
|
||||||
implements View.OnLongClickListener, View.OnClickListener {
|
implements View.OnLongClickListener, View.OnClickListener {
|
||||||
|
|
||||||
@Nullable
|
@Nullable public View dragView;
|
||||||
public View dragView;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public View dummyContainer;
|
||||||
public View dummyContainer;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public ImageView image;
|
||||||
public ImageView image;
|
|
||||||
@Nullable
|
|
||||||
public ImageView artistImage;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public ImageView artistImage;
|
||||||
public ImageView playerImage;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public ImageView playerImage;
|
||||||
public ViewGroup imageContainer;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public MaterialCardView imageContainerCard;
|
||||||
public MaterialCardView imageContainerCard;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public TextView imageText;
|
||||||
public TextView imageText;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public MaterialCardView imageTextContainer;
|
||||||
public MaterialCardView imageTextContainer;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public View mask;
|
||||||
public View mask;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public View menu;
|
||||||
public View menu;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public View paletteColorContainer;
|
||||||
public View paletteColorContainer;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public ImageButton playSongs;
|
||||||
public ImageButton playSongs;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public RecyclerView recyclerView;
|
||||||
public RecyclerView recyclerView;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public TextView text;
|
||||||
public TextView text;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public TextView text2;
|
||||||
public TextView time;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable public TextView time;
|
||||||
public TextView title;
|
|
||||||
|
|
||||||
public MediaEntryViewHolder(@NonNull View itemView) {
|
@Nullable public TextView title;
|
||||||
super(itemView);
|
|
||||||
title = itemView.findViewById(R.id.title);
|
|
||||||
text = itemView.findViewById(R.id.text);
|
|
||||||
|
|
||||||
image = itemView.findViewById(R.id.image);
|
public MediaEntryViewHolder(@NonNull View itemView) {
|
||||||
artistImage = itemView.findViewById(R.id.artistImage);
|
super(itemView);
|
||||||
playerImage = itemView.findViewById(R.id.player_image);
|
title = itemView.findViewById(R.id.title);
|
||||||
time = itemView.findViewById(R.id.time);
|
text = itemView.findViewById(R.id.text);
|
||||||
|
text2 = itemView.findViewById(R.id.text2);
|
||||||
|
|
||||||
imageText = itemView.findViewById(R.id.imageText);
|
image = itemView.findViewById(R.id.image);
|
||||||
imageContainer = itemView.findViewById(R.id.imageContainer);
|
artistImage = itemView.findViewById(R.id.artistImage);
|
||||||
imageTextContainer = itemView.findViewById(R.id.imageTextContainer);
|
playerImage = itemView.findViewById(R.id.player_image);
|
||||||
imageContainerCard = itemView.findViewById(R.id.imageContainerCard);
|
time = itemView.findViewById(R.id.time);
|
||||||
|
|
||||||
menu = itemView.findViewById(R.id.menu);
|
imageText = itemView.findViewById(R.id.imageText);
|
||||||
dragView = itemView.findViewById(R.id.drag_view);
|
imageTextContainer = itemView.findViewById(R.id.imageTextContainer);
|
||||||
paletteColorContainer = itemView.findViewById(R.id.paletteColorContainer);
|
imageContainerCard = itemView.findViewById(R.id.imageContainerCard);
|
||||||
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) {
|
menu = itemView.findViewById(R.id.menu);
|
||||||
imageContainerCard.setCardBackgroundColor(Color.TRANSPARENT);
|
dragView = itemView.findViewById(R.id.drag_view);
|
||||||
}
|
paletteColorContainer = itemView.findViewById(R.id.paletteColorContainer);
|
||||||
itemView.setOnClickListener(this);
|
recyclerView = itemView.findViewById(R.id.recycler_view);
|
||||||
itemView.setOnLongClickListener(this);
|
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
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View getSwipeableContainerView() {
|
public View getSwipeableContainerView() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {}
|
||||||
|
|
||||||
}
|
@Override
|
||||||
|
public boolean onLongClick(View v) {
|
||||||
@Override
|
return false;
|
||||||
public boolean onLongClick(View v) {
|
}
|
||||||
return false;
|
|
||||||
}
|
public void setImageTransitionName(@NonNull String transitionName) {
|
||||||
|
itemView.setTransitionName(transitionName);
|
||||||
public void setImageTransitionName(@NonNull String transitionName) {
|
/* if (imageContainerCard != null) {
|
||||||
itemView.setTransitionName(transitionName);
|
imageContainerCard.setTransitionName(transitionName);
|
||||||
/* if (imageContainerCard != null) {
|
|
||||||
imageContainerCard.setTransitionName(transitionName);
|
|
||||||
}
|
|
||||||
if (image != null) {
|
|
||||||
image.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
|
package io.github.muntashirakon.music.adapter.playlist
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -49,4 +63,4 @@ class LegacyPlaylistAdapter(
|
||||||
interface PlaylistClickListener {
|
interface PlaylistClickListener {
|
||||||
fun onPlaylistClick(playlist: Playlist)
|
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
|
package io.github.muntashirakon.music.adapter.playlist
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.AsyncTask
|
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.fragment.app.FragmentActivity
|
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.ATHUtil
|
||||||
import code.name.monkey.appthemehelper.util.TintHelper
|
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.R
|
||||||
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
||||||
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
|
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.extensions.show
|
||||||
import io.github.muntashirakon.music.helper.menu.PlaylistMenuHelper
|
import io.github.muntashirakon.music.helper.menu.PlaylistMenuHelper
|
||||||
import io.github.muntashirakon.music.helper.menu.SongsMenuHelper
|
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.Playlist
|
import io.github.muntashirakon.music.interfaces.IPlaylistClickListener
|
||||||
import io.github.muntashirakon.music.model.Song
|
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.AutoGeneratedPlaylistBitmap
|
||||||
import io.github.muntashirakon.music.util.MusicUtil
|
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(
|
class PlaylistAdapter(
|
||||||
private val activity: FragmentActivity,
|
private val activity: FragmentActivity,
|
||||||
var dataSet: List<PlaylistWithSongs>,
|
private var dataSet: List<PlaylistWithSongs>,
|
||||||
private var itemLayoutRes: Int,
|
private var itemLayoutRes: Int,
|
||||||
cabHolder: CabHolder?
|
ICabHolder: ICabHolder?,
|
||||||
|
private val listener: IPlaylistClickListener
|
||||||
) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, PlaylistWithSongs>(
|
) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, PlaylistWithSongs>(
|
||||||
activity,
|
activity,
|
||||||
cabHolder,
|
ICabHolder,
|
||||||
R.menu.menu_playlists_selection
|
R.menu.menu_playlists_selection
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@ -56,7 +70,7 @@ class PlaylistAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemId(position: Int): Long {
|
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 {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
@ -88,7 +102,7 @@ class PlaylistAdapter(
|
||||||
} else {
|
} else {
|
||||||
holder.menu?.show()
|
holder.menu?.show()
|
||||||
}
|
}
|
||||||
//PlaylistBitmapLoader(this, holder, playlist).execute()
|
//playlistBitmapLoader(activity, holder, playlist)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getIconRes(): Drawable = TintHelper.createTintedDrawable(
|
private fun getIconRes(): Drawable = TintHelper.createTintedDrawable(
|
||||||
|
@ -158,10 +172,8 @@ class PlaylistAdapter(
|
||||||
if (isInQuickSelectMode) {
|
if (isInQuickSelectMode) {
|
||||||
toggleChecked(layoutPosition)
|
toggleChecked(layoutPosition)
|
||||||
} else {
|
} else {
|
||||||
activity.findNavController(R.id.fragment_container).navigate(
|
ViewCompat.setTransitionName(itemView, "playlist")
|
||||||
R.id.playlistDetailsFragment,
|
listener.onPlaylistClick(dataSet[layoutPosition], itemView)
|
||||||
bundleOf(EXTRA_PLAYLIST to dataSet[layoutPosition])
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,28 +183,35 @@ class PlaylistAdapter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PlaylistBitmapLoader(
|
private fun playlistBitmapLoader(
|
||||||
private var adapter: PlaylistAdapter,
|
activity: FragmentActivity,
|
||||||
private var viewHolder: ViewHolder,
|
viewHolder: ViewHolder,
|
||||||
private var playlist: Playlist
|
playlist: PlaylistWithSongs
|
||||||
) : AsyncTask<Void, Void, Bitmap>() {
|
) {
|
||||||
|
|
||||||
override fun doInBackground(vararg params: Void?): Bitmap {
|
activity.lifecycleScope.launch(IO) {
|
||||||
val songs = PlaylistSongsLoader.getPlaylistSongList(adapter.activity, playlist)
|
val songs = playlist.songs.toSongs()
|
||||||
return AutoGeneratedPlaylistBitmap.getBitmap(adapter.activity, songs, false, false)
|
val bitmap = AutoGeneratedPlaylistBitmap.getBitmap(activity, songs, false, false)
|
||||||
|
withContext(Main) { viewHolder.image?.setImageBitmap(bitmap) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPostExecute(result: Bitmap?) {
|
/*
|
||||||
super.onPostExecute(result)
|
override fun doInBackground(vararg params: Void?): Bitmap {
|
||||||
viewHolder.image?.setImageBitmap(result)
|
val songs = playlist.songs.toSongs()
|
||||||
val color = RetroColorUtil.getColor(
|
return AutoGeneratedPlaylistBitmap.getBitmap(activity, songs, false, false)
|
||||||
RetroColorUtil.generatePalette(
|
}
|
||||||
result
|
|
||||||
),
|
override fun onPostExecute(result: Bitmap?) {
|
||||||
ATHUtil.resolveColor(adapter.activity, R.attr.colorSurface)
|
super.onPostExecute(result)
|
||||||
)
|
viewHolder.image?.setImageBitmap(result)
|
||||||
viewHolder.paletteColorContainer?.setBackgroundColor(color)
|
val color = RetroColorUtil.getColor(
|
||||||
}
|
RetroColorUtil.generatePalette(
|
||||||
|
result
|
||||||
|
),
|
||||||
|
ATHUtil.resolveColor(activity, R.attr.colorSurface)
|
||||||
|
)
|
||||||
|
viewHolder.paletteColorContainer?.setBackgroundColor(color)
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
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
|
package io.github.muntashirakon.music.adapter.song
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.annotation.LayoutRes
|
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.R
|
||||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
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 io.github.muntashirakon.music.model.Song
|
||||||
|
|
||||||
abstract class AbsOffsetSongAdapter(
|
abstract class AbsOffsetSongAdapter(
|
||||||
activity: AppCompatActivity,
|
activity: FragmentActivity,
|
||||||
dataSet: MutableList<Song>,
|
dataSet: MutableList<Song>,
|
||||||
@LayoutRes itemLayoutRes: Int,
|
@LayoutRes itemLayoutRes: Int,
|
||||||
cabHolder: CabHolder?
|
ICabHolder: ICabHolder?
|
||||||
) : SongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {
|
) : SongAdapter(activity, dataSet, itemLayoutRes, ICabHolder) {
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongAdapter.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongAdapter.ViewHolder {
|
||||||
if (viewType == OFFSET_ITEM) {
|
if (viewType == OFFSET_ITEM) {
|
||||||
|
@ -76,4 +90,4 @@ abstract class AbsOffsetSongAdapter(
|
||||||
const val OFFSET_ITEM = 0
|
const val OFFSET_ITEM = 0
|
||||||
const val SONG = 1
|
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
|
package io.github.muntashirakon.music.adapter.song
|
||||||
|
|
||||||
import android.view.MenuItem
|
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.toSongEntity
|
||||||
import io.github.muntashirakon.music.db.toSongs
|
import io.github.muntashirakon.music.db.toSongs
|
||||||
import io.github.muntashirakon.music.dialogs.RemoveSongFromPlaylistDialog
|
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.PlaylistSong
|
||||||
import io.github.muntashirakon.music.model.Song
|
import io.github.muntashirakon.music.model.Song
|
||||||
import io.github.muntashirakon.music.util.ViewUtil
|
import io.github.muntashirakon.music.util.ViewUtil
|
||||||
|
@ -23,13 +37,13 @@ class OrderablePlaylistSongAdapter(
|
||||||
activity: FragmentActivity,
|
activity: FragmentActivity,
|
||||||
dataSet: ArrayList<Song>,
|
dataSet: ArrayList<Song>,
|
||||||
itemLayoutRes: Int,
|
itemLayoutRes: Int,
|
||||||
cabHolder: CabHolder?,
|
ICabHolder: ICabHolder?,
|
||||||
private val onMoveItemListener: OnMoveItemListener?
|
private val onMoveItemListener: OnMoveItemListener?
|
||||||
) : SongAdapter(
|
) : SongAdapter(
|
||||||
activity,
|
activity,
|
||||||
dataSet,
|
dataSet,
|
||||||
itemLayoutRes,
|
itemLayoutRes,
|
||||||
cabHolder
|
ICabHolder
|
||||||
), DraggableItemAdapter<OrderablePlaylistSongAdapter.ViewHolder> {
|
), DraggableItemAdapter<OrderablePlaylistSongAdapter.ViewHolder> {
|
||||||
|
|
||||||
init {
|
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
|
package io.github.muntashirakon.music.adapter.song
|
||||||
|
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
@ -5,6 +19,8 @@ import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import io.github.muntashirakon.music.R
|
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
|
||||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote.isPlaying
|
import io.github.muntashirakon.music.helper.MusicPlayerRemote.isPlaying
|
||||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote.playNextSong
|
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.model.Song
|
||||||
import io.github.muntashirakon.music.util.MusicUtil
|
import io.github.muntashirakon.music.util.MusicUtil
|
||||||
import io.github.muntashirakon.music.util.ViewUtil
|
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.DraggableItemAdapter
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange
|
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags
|
import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags
|
||||||
|
@ -41,8 +59,8 @@ class PlayingQueueAdapter(
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
|
||||||
super.onBindViewHolder(holder, position)
|
super.onBindViewHolder(holder, position)
|
||||||
holder.imageText?.text = (position - current).toString()
|
val song = dataSet[position]
|
||||||
holder.time?.text = MusicUtil.getReadableDurationString(dataSet[position].duration)
|
holder.time?.text = MusicUtil.getReadableDurationString(song.duration)
|
||||||
if (holder.itemViewType == HISTORY || holder.itemViewType == CURRENT) {
|
if (holder.itemViewType == HISTORY || holder.itemViewType == CURRENT) {
|
||||||
setAlpha(holder, 0.5f)
|
setAlpha(holder, 0.5f)
|
||||||
}
|
}
|
||||||
|
@ -58,7 +76,17 @@ class PlayingQueueAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadAlbumCover(song: Song, holder: SongAdapter.ViewHolder) {
|
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) {
|
fun swapDataSet(dataSet: List<Song>, position: Int) {
|
||||||
|
@ -76,7 +104,6 @@ class PlayingQueueAdapter(
|
||||||
holder.image?.alpha = alpha
|
holder.image?.alpha = alpha
|
||||||
holder.title?.alpha = alpha
|
holder.title?.alpha = alpha
|
||||||
holder.text?.alpha = alpha
|
holder.text?.alpha = alpha
|
||||||
holder.imageText?.alpha = alpha
|
|
||||||
holder.paletteColorContainer?.alpha = alpha
|
holder.paletteColorContainer?.alpha = alpha
|
||||||
holder.dragView?.alpha = alpha
|
holder.dragView?.alpha = alpha
|
||||||
holder.menu?.alpha = alpha
|
holder.menu?.alpha = alpha
|
||||||
|
@ -129,7 +156,6 @@ class PlayingQueueAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
imageText?.visibility = View.VISIBLE
|
|
||||||
dragView?.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 {
|
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
|
SwipeableItemConstants.REACTION_CAN_NOT_SWIPE_BOTH_H
|
||||||
} else {
|
} else {
|
||||||
SwipeableItemConstants.REACTION_CAN_SWIPE_BOTH_H
|
SwipeableItemConstants.REACTION_CAN_SWIPE_BOTH_H
|
||||||
|
@ -196,17 +222,17 @@ class PlayingQueueAdapter(
|
||||||
private val isPlaying: Boolean = MusicPlayerRemote.isPlaying
|
private val isPlaying: Boolean = MusicPlayerRemote.isPlaying
|
||||||
private val songProgressMillis = 0
|
private val songProgressMillis = 0
|
||||||
override fun onPerformAction() {
|
override fun onPerformAction() {
|
||||||
//currentlyShownSnackbar = null
|
// currentlyShownSnackbar = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSlideAnimationEnd() {
|
override fun onSlideAnimationEnd() {
|
||||||
//initializeSnackBar(adapter, position, activity, isPlaying)
|
// initializeSnackBar(adapter, position, activity, isPlaying)
|
||||||
songToRemove = adapter.dataSet[position]
|
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!!)) {
|
if (isPlaying(songToRemove!!)) {
|
||||||
playNextSong()
|
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!!)
|
adapter.setSongToRemove(songToRemove!!)
|
||||||
removeFromQueue(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
|
package io.github.muntashirakon.music.adapter.song
|
||||||
|
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
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 io.github.muntashirakon.music.R
|
import io.github.muntashirakon.music.R
|
||||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
import com.google.android.material.button.MaterialButton
|
||||||
import io.github.muntashirakon.music.interfaces.CabHolder
|
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
|
import io.github.muntashirakon.music.model.Song
|
||||||
|
|
||||||
open class PlaylistSongAdapter(
|
open class PlaylistSongAdapter(
|
||||||
activity: AppCompatActivity,
|
private val playlist: PlaylistEntity,
|
||||||
|
activity: FragmentActivity,
|
||||||
dataSet: MutableList<Song>,
|
dataSet: MutableList<Song>,
|
||||||
itemLayoutRes: Int,
|
itemLayoutRes: Int,
|
||||||
cabHolder: CabHolder?
|
ICabHolder: ICabHolder?
|
||||||
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {
|
) : SongAdapter(activity, dataSet, itemLayoutRes, ICabHolder) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.setMultiSelectMenuRes(R.menu.menu_cannot_delete_single_songs_playlist_songs_selection)
|
this.setMultiSelectMenuRes(R.menu.menu_cannot_delete_single_songs_playlist_songs_selection)
|
||||||
|
@ -27,45 +41,23 @@ open class PlaylistSongAdapter(
|
||||||
return ViewHolder(view)
|
return ViewHolder(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
|
open inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) {
|
||||||
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)
|
|
||||||
|
|
||||||
override var songMenuRes: Int
|
override var songMenuRes: Int
|
||||||
get() = R.menu.menu_item_cannot_delete_single_songs_playlist_song
|
get() = R.menu.menu_item_playlist_song
|
||||||
set(value) {
|
set(value) {
|
||||||
super.songMenuRes = value
|
super.songMenuRes = value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSongMenuItemClick(item: MenuItem): Boolean {
|
override fun onSongMenuItemClick(item: MenuItem): Boolean {
|
||||||
if (item.itemId == R.id.action_go_to_album) {
|
when (item.itemId) {
|
||||||
activity.findNavController(R.id.fragment_container)
|
R.id.action_remove_from_playlist -> {
|
||||||
.navigate(
|
RemoveSongFromPlaylistDialog.create(song.toSongEntity(playlist.playListId))
|
||||||
R.id.albumDetailsFragment,
|
.show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST")
|
||||||
bundleOf(EXTRA_ALBUM_ID to song.albumId)
|
return true
|
||||||
)
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return super.onSongMenuItemClick(item)
|
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
|
package io.github.muntashirakon.music.adapter.song
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import io.github.muntashirakon.music.R
|
import io.github.muntashirakon.music.R
|
||||||
import io.github.muntashirakon.music.helper.MusicPlayerRemote
|
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 io.github.muntashirakon.music.model.Song
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
|
|
||||||
|
@ -12,8 +26,8 @@ class ShuffleButtonSongAdapter(
|
||||||
activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
dataSet: MutableList<Song>,
|
dataSet: MutableList<Song>,
|
||||||
itemLayoutRes: Int,
|
itemLayoutRes: Int,
|
||||||
cabHolder: CabHolder?
|
ICabHolder: ICabHolder?
|
||||||
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {
|
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, ICabHolder) {
|
||||||
|
|
||||||
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
||||||
return ViewHolder(view)
|
return ViewHolder(view)
|
||||||
|
@ -49,4 +63,4 @@ class ShuffleButtonSongAdapter(
|
||||||
super.onClick(v)
|
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
|
package io.github.muntashirakon.music.adapter.song
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.FragmentActivity
|
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.model.Song
|
||||||
import io.github.muntashirakon.music.util.MusicUtil
|
import io.github.muntashirakon.music.util.MusicUtil
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -12,8 +26,8 @@ class SimpleSongAdapter(
|
||||||
context: FragmentActivity,
|
context: FragmentActivity,
|
||||||
songs: ArrayList<Song>,
|
songs: ArrayList<Song>,
|
||||||
layoutRes: Int,
|
layoutRes: Int,
|
||||||
cabHolder: CabHolder?
|
ICabHolder: ICabHolder?
|
||||||
) : SongAdapter(context, songs, layoutRes, cabHolder) {
|
) : SongAdapter(context, songs, layoutRes, ICabHolder) {
|
||||||
|
|
||||||
override fun swapDataSet(dataSet: List<Song>) {
|
override fun swapDataSet(dataSet: List<Song>) {
|
||||||
this.dataSet = dataSet.toMutableList()
|
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
|
package io.github.muntashirakon.music.adapter.song
|
||||||
|
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
|
@ -7,10 +21,9 @@ import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.navigation.findNavController
|
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.EXTRA_ALBUM_ID
|
||||||
import io.github.muntashirakon.music.R
|
import io.github.muntashirakon.music.R
|
||||||
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
|
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.SortOrder
|
||||||
import io.github.muntashirakon.music.helper.menu.SongMenuHelper
|
import io.github.muntashirakon.music.helper.menu.SongMenuHelper
|
||||||
import io.github.muntashirakon.music.helper.menu.SongsMenuHelper
|
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.model.Song
|
||||||
import io.github.muntashirakon.music.util.MusicUtil
|
import io.github.muntashirakon.music.util.MusicUtil
|
||||||
import io.github.muntashirakon.music.util.PreferenceUtil
|
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||||
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
|
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
|
||||||
|
import com.afollestad.materialcab.MaterialCab
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
import me.zhanghai.android.fastscroll.PopupTextProvider
|
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,11 +53,11 @@ open class SongAdapter(
|
||||||
protected val activity: FragmentActivity,
|
protected val activity: FragmentActivity,
|
||||||
var dataSet: MutableList<Song>,
|
var dataSet: MutableList<Song>,
|
||||||
protected var itemLayoutRes: Int,
|
protected var itemLayoutRes: Int,
|
||||||
cabHolder: CabHolder?,
|
ICabHolder: ICabHolder?,
|
||||||
showSectionName: Boolean = true
|
showSectionName: Boolean = true
|
||||||
) : AbsMultiSelectAdapter<SongAdapter.ViewHolder, Song>(
|
) : AbsMultiSelectAdapter<SongAdapter.ViewHolder, Song>(
|
||||||
activity,
|
activity,
|
||||||
cabHolder,
|
ICabHolder,
|
||||||
R.menu.menu_media_selection
|
R.menu.menu_media_selection
|
||||||
), MaterialCab.Callback, PopupTextProvider {
|
), MaterialCab.Callback, PopupTextProvider {
|
||||||
|
|
||||||
|
@ -59,7 +74,7 @@ open class SongAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemId(position: Int): Long {
|
override fun getItemId(position: Int): Long {
|
||||||
return dataSet[position].id.toLong()
|
return dataSet[position].id
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
@ -87,6 +102,7 @@ open class SongAdapter(
|
||||||
}
|
}
|
||||||
holder.title?.text = getSongTitle(song)
|
holder.title?.text = getSongTitle(song)
|
||||||
holder.text?.text = getSongText(song)
|
holder.text?.text = getSongText(song)
|
||||||
|
holder.text2?.text = getSongText(song)
|
||||||
loadAlbumCover(song, holder)
|
loadAlbumCover(song, holder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,6 +137,10 @@ open class SongAdapter(
|
||||||
return song.artistName
|
return song.artistName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getSongText2(song: Song): String? {
|
||||||
|
return song.albumName
|
||||||
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return dataSet.size
|
return dataSet.size
|
||||||
}
|
}
|
||||||
|
@ -157,7 +177,6 @@ open class SongAdapter(
|
||||||
get() = dataSet[layoutPosition]
|
get() = dataSet[layoutPosition]
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setImageTransitionName(activity.getString(R.string.transition_album_art))
|
|
||||||
menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
|
menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
|
||||||
override val song: Song
|
override val song: Song
|
||||||
get() = this@ViewHolder.song
|
get() = this@ViewHolder.song
|
||||||
|
@ -172,7 +191,7 @@ open class SongAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun onSongMenuItemClick(item: MenuItem): Boolean {
|
protected open fun onSongMenuItemClick(item: MenuItem): Boolean {
|
||||||
if (image != null && image!!.visibility == View.VISIBLE) {
|
if (image != null && image!!.isVisible) {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_go_to_album -> {
|
R.id.action_go_to_album -> {
|
||||||
activity.findNavController(R.id.fragment_container)
|
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
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.appshortcuts
|
package io.github.muntashirakon.music.appshortcuts
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
@ -60,7 +60,10 @@ object AppShortcutIconGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateThemedIcon(
|
private fun generateThemedIcon(
|
||||||
context: Context, iconId: Int, foregroundColor: Int, backgroundColor: Int
|
context: Context,
|
||||||
|
iconId: Int,
|
||||||
|
foregroundColor: Int,
|
||||||
|
backgroundColor: Int
|
||||||
): Icon {
|
): Icon {
|
||||||
// Get and tint foreground and background drawables
|
// Get and tint foreground and background drawables
|
||||||
val vectorDrawable = RetroUtil.getTintedVectorDrawable(context, iconId, foregroundColor)
|
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
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.appshortcuts
|
package io.github.muntashirakon.music.appshortcuts
|
||||||
|
|
||||||
import android.app.Activity
|
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.LastAddedShortcutType
|
||||||
import io.github.muntashirakon.music.appshortcuts.shortcuttype.ShuffleAllShortcutType
|
import io.github.muntashirakon.music.appshortcuts.shortcuttype.ShuffleAllShortcutType
|
||||||
import io.github.muntashirakon.music.appshortcuts.shortcuttype.TopTracksShortcutType
|
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.Playlist
|
||||||
import io.github.muntashirakon.music.model.smartplaylist.LastAddedPlaylist
|
import io.github.muntashirakon.music.model.smartplaylist.LastAddedPlaylist
|
||||||
import io.github.muntashirakon.music.model.smartplaylist.ShuffleAllPlaylist
|
import io.github.muntashirakon.music.model.smartplaylist.ShuffleAllPlaylist
|
||||||
|
@ -31,16 +32,7 @@ class AppShortcutLauncherActivity : Activity() {
|
||||||
|
|
||||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
when (extraNotNull(KEY_SHORTCUT_TYPE, SHORTCUT_TYPE_NONE).value) {
|
||||||
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) {
|
|
||||||
SHORTCUT_TYPE_SHUFFLE_ALL -> {
|
SHORTCUT_TYPE_SHUFFLE_ALL -> {
|
||||||
startServiceWithPlaylist(
|
startServiceWithPlaylist(
|
||||||
SHUFFLE_MODE_SHUFFLE, ShuffleAllPlaylist()
|
SHUFFLE_MODE_SHUFFLE, ShuffleAllPlaylist()
|
||||||
|
@ -78,9 +70,9 @@ class AppShortcutLauncherActivity : Activity() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val KEY_SHORTCUT_TYPE = "io.github.muntashirakon.Music.appshortcuts.ShortcutType"
|
const val KEY_SHORTCUT_TYPE = "io.github.muntashirakon.Music.appshortcuts.ShortcutType"
|
||||||
const val SHORTCUT_TYPE_SHUFFLE_ALL = 0
|
const val SHORTCUT_TYPE_SHUFFLE_ALL = 0L
|
||||||
const val SHORTCUT_TYPE_TOP_TRACKS = 1
|
const val SHORTCUT_TYPE_TOP_TRACKS = 1L
|
||||||
const val SHORTCUT_TYPE_LAST_ADDED = 2
|
const val SHORTCUT_TYPE_LAST_ADDED = 2L
|
||||||
const val SHORTCUT_TYPE_NONE = 4
|
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
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.appshortcuts
|
package io.github.muntashirakon.music.appshortcuts
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
import android.annotation.TargetApi
|
||||||
|
@ -32,16 +32,16 @@ class DynamicShortcutManager(private val context: Context) {
|
||||||
this.context.getSystemService(ShortcutManager::class.java)
|
this.context.getSystemService(ShortcutManager::class.java)
|
||||||
|
|
||||||
private val defaultShortcuts: List<ShortcutInfo>
|
private val defaultShortcuts: List<ShortcutInfo>
|
||||||
get() = Arrays.asList(
|
get() = listOf(
|
||||||
ShuffleAllShortcutType(context).shortcutInfo,
|
ShuffleAllShortcutType(context).shortcutInfo,
|
||||||
TopTracksShortcutType(context).shortcutInfo,
|
TopTracksShortcutType(context).shortcutInfo,
|
||||||
LastAddedShortcutType(context).shortcutInfo
|
LastAddedShortcutType(context).shortcutInfo
|
||||||
)
|
)
|
||||||
|
|
||||||
fun initDynamicShortcuts() {
|
fun initDynamicShortcuts() {
|
||||||
//if (shortcutManager.dynamicShortcuts.size == 0) {
|
// if (shortcutManager.dynamicShortcuts.size == 0) {
|
||||||
shortcutManager.dynamicShortcuts = defaultShortcuts
|
shortcutManager.dynamicShortcuts = defaultShortcuts
|
||||||
//}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateDynamicShortcuts() {
|
fun updateDynamicShortcuts() {
|
||||||
|
@ -58,8 +58,12 @@ class DynamicShortcutManager(private val context: Context) {
|
||||||
icon: Icon,
|
icon: Icon,
|
||||||
intent: Intent
|
intent: Intent
|
||||||
): ShortcutInfo {
|
): ShortcutInfo {
|
||||||
return ShortcutInfo.Builder(context, id).setShortLabel(shortLabel)
|
return ShortcutInfo.Builder(context, id)
|
||||||
.setLongLabel(longLabel).setIcon(icon).setIntent(intent).build()
|
.setShortLabel(shortLabel)
|
||||||
|
.setLongLabel(longLabel)
|
||||||
|
.setIcon(icon)
|
||||||
|
.setIntent(intent)
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reportShortcutUsed(context: Context, shortcutId: String) {
|
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
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.appshortcuts.shortcuttype
|
package io.github.muntashirakon.music.appshortcuts.shortcuttype
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
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.)
|
* @param shortcutType Describes the type of shortcut to create (ShuffleAll, TopTracks, custom playlist, etc.)
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
internal fun getPlaySongsIntent(shortcutType: Int): Intent {
|
internal fun getPlaySongsIntent(shortcutType: Long): Intent {
|
||||||
val intent = Intent(context, AppShortcutLauncherActivity::class.java)
|
val intent = Intent(context, AppShortcutLauncherActivity::class.java)
|
||||||
intent.action = Intent.ACTION_VIEW
|
intent.action = Intent.ACTION_VIEW
|
||||||
val b = Bundle()
|
val b = Bundle()
|
||||||
b.putInt(AppShortcutLauncherActivity.KEY_SHORTCUT_TYPE, shortcutType)
|
b.putLong(AppShortcutLauncherActivity.KEY_SHORTCUT_TYPE, shortcutType)
|
||||||
intent.putExtras(b)
|
intent.putExtras(b)
|
||||||
return intent
|
return intent
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 Hemanth Savarala.
|
* Copyright (c) 2020 Hemanth Savarla.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.appshortcuts.shortcuttype
|
package io.github.muntashirakon.music.appshortcuts.shortcuttype
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
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
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.appshortcuts.shortcuttype
|
package io.github.muntashirakon.music.appshortcuts.shortcuttype
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
import android.annotation.TargetApi
|
||||||
|
@ -26,20 +26,16 @@ import io.github.muntashirakon.music.appshortcuts.AppShortcutLauncherActivity
|
||||||
class ShuffleAllShortcutType(context: Context) : BaseShortcutType(context) {
|
class ShuffleAllShortcutType(context: Context) : BaseShortcutType(context) {
|
||||||
|
|
||||||
override val shortcutInfo: ShortcutInfo
|
override val shortcutInfo: ShortcutInfo
|
||||||
get() = ShortcutInfo.Builder(
|
get() = ShortcutInfo.Builder(context, id)
|
||||||
context, id
|
.setShortLabel(context.getString(R.string.app_shortcut_shuffle_all_short))
|
||||||
).setShortLabel(context.getString(R.string.app_shortcut_shuffle_all_short)).setLongLabel(
|
.setLongLabel(context.getString(R.string.app_shortcut_shuffle_all_long))
|
||||||
context.getString(R.string.app_shortcut_shuffle_all_long)
|
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_shuffle_all))
|
||||||
).setIcon(
|
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_SHUFFLE_ALL))
|
||||||
AppShortcutIconGenerator.generateThemedIcon(
|
|
||||||
context, R.drawable.ic_app_shortcut_shuffle_all
|
|
||||||
)
|
|
||||||
).setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_SHUFFLE_ALL))
|
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
val id: String
|
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
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.appshortcuts.shortcuttype
|
package io.github.muntashirakon.music.appshortcuts.shortcuttype
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
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
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.appwidgets
|
package io.github.muntashirakon.music.appwidgets
|
||||||
|
|
||||||
import android.app.PendingIntent
|
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.glide.SongGlideRequest
|
||||||
import io.github.muntashirakon.music.service.MusicService
|
import io.github.muntashirakon.music.service.MusicService
|
||||||
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 io.github.muntashirakon.music.util.RetroUtil
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.request.animation.GlideAnimation
|
import com.bumptech.glide.request.animation.GlideAnimation
|
||||||
|
@ -193,8 +194,11 @@ class AppWidgetBig : BaseAppWidget() {
|
||||||
* Link up various button actions using [PendingIntent].
|
* Link up various button actions using [PendingIntent].
|
||||||
*/
|
*/
|
||||||
private fun linkButtons(context: Context, views: RemoteViews) {
|
private fun linkButtons(context: Context, views: RemoteViews) {
|
||||||
val action =
|
val action = Intent(context, MainActivity::class.java)
|
||||||
Intent(context, MainActivity::class.java).putExtra(MainActivity.EXPAND_PANEL, true)
|
.putExtra(
|
||||||
|
MainActivity.EXPAND_PANEL,
|
||||||
|
PreferenceUtil.isExpandPanel
|
||||||
|
)
|
||||||
var pendingIntent: PendingIntent
|
var pendingIntent: PendingIntent
|
||||||
|
|
||||||
val serviceName = ComponentName(context, MusicService::class.java)
|
val serviceName = ComponentName(context, MusicService::class.java)
|
||||||
|
@ -229,6 +233,5 @@ class AppWidgetBig : BaseAppWidget() {
|
||||||
}
|
}
|
||||||
return mInstance!!
|
return mInstance!!
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 Hemanth Savarala.
|
* Copyright (c) 2020 Hemanth Savarla.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.appwidgets
|
package io.github.muntashirakon.music.appwidgets
|
||||||
|
|
||||||
import android.app.PendingIntent
|
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.service.MusicService.*
|
import io.github.muntashirakon.music.service.MusicService.*
|
||||||
import io.github.muntashirakon.music.util.ImageUtil
|
import io.github.muntashirakon.music.util.ImageUtil
|
||||||
|
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||||
import io.github.muntashirakon.music.util.RetroUtil
|
import io.github.muntashirakon.music.util.RetroUtil
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.request.animation.GlideAnimation
|
import com.bumptech.glide.request.animation.GlideAnimation
|
||||||
|
@ -217,7 +218,11 @@ class AppWidgetCard : BaseAppWidget() {
|
||||||
* Link up various button actions using [PendingIntent].
|
* Link up various button actions using [PendingIntent].
|
||||||
*/
|
*/
|
||||||
private fun linkButtons(context: Context, views: RemoteViews) {
|
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
|
var pendingIntent: PendingIntent
|
||||||
|
|
||||||
val serviceName = ComponentName(context, MusicService::class.java)
|
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
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.appwidgets
|
package io.github.muntashirakon.music.appwidgets
|
||||||
|
|
||||||
import android.app.PendingIntent
|
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.service.MusicService.*
|
import io.github.muntashirakon.music.service.MusicService.*
|
||||||
import io.github.muntashirakon.music.util.ImageUtil
|
import io.github.muntashirakon.music.util.ImageUtil
|
||||||
|
import io.github.muntashirakon.music.util.PreferenceUtil
|
||||||
import io.github.muntashirakon.music.util.RetroUtil
|
import io.github.muntashirakon.music.util.RetroUtil
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.request.animation.GlideAnimation
|
import com.bumptech.glide.request.animation.GlideAnimation
|
||||||
|
@ -49,7 +50,6 @@ class AppWidgetClassic : BaseAppWidget() {
|
||||||
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
|
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
|
||||||
val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_classic)
|
val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_classic)
|
||||||
|
|
||||||
|
|
||||||
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
|
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
|
||||||
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
|
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
|
||||||
appWidgetView.setImageViewBitmap(
|
appWidgetView.setImageViewBitmap(
|
||||||
|
@ -208,7 +208,11 @@ class AppWidgetClassic : BaseAppWidget() {
|
||||||
* Link up various button actions using [PendingIntent].
|
* Link up various button actions using [PendingIntent].
|
||||||
*/
|
*/
|
||||||
private fun linkButtons(context: Context, views: RemoteViews) {
|
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
|
var pendingIntent: PendingIntent
|
||||||
|
|
||||||
val serviceName = ComponentName(context, MusicService::class.java)
|
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
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.appwidgets
|
package io.github.muntashirakon.music.appwidgets
|
||||||
|
|
||||||
import android.app.PendingIntent
|
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.glide.palette.BitmapPaletteWrapper
|
||||||
import io.github.muntashirakon.music.service.MusicService
|
import io.github.muntashirakon.music.service.MusicService
|
||||||
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 io.github.muntashirakon.music.util.RetroUtil
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.request.animation.GlideAnimation
|
import com.bumptech.glide.request.animation.GlideAnimation
|
||||||
|
@ -192,7 +193,11 @@ class AppWidgetSmall : BaseAppWidget() {
|
||||||
* Link up various button actions using [PendingIntent].
|
* Link up various button actions using [PendingIntent].
|
||||||
*/
|
*/
|
||||||
private fun linkButtons(context: Context, views: RemoteViews) {
|
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
|
var pendingIntent: PendingIntent
|
||||||
|
|
||||||
val serviceName = ComponentName(context, MusicService::class.java)
|
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
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.appwidgets
|
package io.github.muntashirakon.music.appwidgets
|
||||||
|
|
||||||
import android.app.PendingIntent
|
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.appwidgets.base.BaseAppWidget
|
||||||
import io.github.muntashirakon.music.service.MusicService
|
import io.github.muntashirakon.music.service.MusicService
|
||||||
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 io.github.muntashirakon.music.util.RetroUtil
|
||||||
|
|
||||||
class AppWidgetText : BaseAppWidget() {
|
class AppWidgetText : BaseAppWidget() {
|
||||||
|
@ -77,7 +78,11 @@ class AppWidgetText : BaseAppWidget() {
|
||||||
* Link up various button actions using [PendingIntent].
|
* Link up various button actions using [PendingIntent].
|
||||||
*/
|
*/
|
||||||
private fun linkButtons(context: Context, views: RemoteViews) {
|
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
|
var pendingIntent: PendingIntent
|
||||||
|
|
||||||
val serviceName = ComponentName(context, MusicService::class.java)
|
val serviceName = ComponentName(context, MusicService::class.java)
|
||||||
|
@ -153,10 +158,7 @@ class AppWidgetText : BaseAppWidget() {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pushUpdate(service.applicationContext, appWidgetIds, appWidgetView)
|
pushUpdate(service.applicationContext, appWidgetIds, appWidgetView)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 Hemanth Savarala.
|
* Copyright (c) 2020 Hemanth Savarla.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.appwidgets
|
package io.github.muntashirakon.music.appwidgets
|
||||||
|
|
||||||
import android.appwidget.AppWidgetManager
|
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
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.appwidgets.base
|
package io.github.muntashirakon.music.appwidgets.base
|
||||||
|
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
|
@ -40,7 +40,9 @@ abstract class BaseAppWidget : AppWidgetProvider() {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
override fun onUpdate(
|
override fun onUpdate(
|
||||||
context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray
|
context: Context,
|
||||||
|
appWidgetManager: AppWidgetManager,
|
||||||
|
appWidgetIds: IntArray
|
||||||
) {
|
) {
|
||||||
defaultAppWidget(context, appWidgetIds)
|
defaultAppWidget(context, appWidgetIds)
|
||||||
val updateIntent = Intent(APP_WIDGET_UPDATE)
|
val updateIntent = Intent(APP_WIDGET_UPDATE)
|
||||||
|
@ -62,7 +64,9 @@ abstract class BaseAppWidget : AppWidgetProvider() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun pushUpdate(
|
protected fun pushUpdate(
|
||||||
context: Context, appWidgetIds: IntArray?, views: RemoteViews
|
context: Context,
|
||||||
|
appWidgetIds: IntArray?,
|
||||||
|
views: RemoteViews
|
||||||
) {
|
) {
|
||||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||||
if (appWidgetIds != null) {
|
if (appWidgetIds != null) {
|
||||||
|
@ -86,7 +90,9 @@ abstract class BaseAppWidget : AppWidgetProvider() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun buildPendingIntent(
|
protected fun buildPendingIntent(
|
||||||
context: Context, action: String, serviceName: ComponentName
|
context: Context,
|
||||||
|
action: String,
|
||||||
|
serviceName: ComponentName
|
||||||
): PendingIntent {
|
): PendingIntent {
|
||||||
val intent = Intent(action)
|
val intent = Intent(action)
|
||||||
intent.component = serviceName
|
intent.component = serviceName
|
||||||
|
@ -169,7 +175,11 @@ abstract class BaseAppWidget : AppWidgetProvider() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun composeRoundedRectPath(
|
protected fun composeRoundedRectPath(
|
||||||
rect: RectF, tl: Float, tr: Float, bl: Float, br: Float
|
rect: RectF,
|
||||||
|
tl: Float,
|
||||||
|
tr: Float,
|
||||||
|
bl: Float,
|
||||||
|
br: Float
|
||||||
): Path {
|
): Path {
|
||||||
val path = Path()
|
val path = Path()
|
||||||
path.moveTo(rect.left + tl, rect.top)
|
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
|
package io.github.muntashirakon.music.db
|
||||||
|
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
|
@ -18,4 +32,4 @@ interface BlackListStoreDao {
|
||||||
|
|
||||||
@Query("SELECT * FROM BlackListStoreEntity")
|
@Query("SELECT * FROM BlackListStoreEntity")
|
||||||
fun blackListPaths(): List<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
|
package io.github.muntashirakon.music.db
|
||||||
|
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
|
@ -7,4 +21,4 @@ import androidx.room.PrimaryKey
|
||||||
class BlackListStoreEntity(
|
class BlackListStoreEntity(
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
val path: String
|
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
|
package io.github.muntashirakon.music.db
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
|
@ -23,4 +37,4 @@ interface HistoryDao {
|
||||||
|
|
||||||
@Query("SELECT * FROM HistoryEntity ORDER BY time_played DESC LIMIT $HISTORY_LIMIT")
|
@Query("SELECT * FROM HistoryEntity ORDER BY time_played DESC LIMIT $HISTORY_LIMIT")
|
||||||
fun observableHistorySongs(): LiveData<List<HistoryEntity>>
|
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
|
package io.github.muntashirakon.music.db
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
|
@ -29,4 +43,4 @@ class HistoryEntity(
|
||||||
val albumArtist: String?,
|
val albumArtist: String?,
|
||||||
@ColumnInfo(name = "time_played")
|
@ColumnInfo(name = "time_played")
|
||||||
val timePlayed: Long
|
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
|
package io.github.muntashirakon.music.db
|
||||||
|
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
|
@ -15,4 +29,4 @@ interface LyricsDao {
|
||||||
|
|
||||||
@Update
|
@Update
|
||||||
fun updateLyrics(lyricsEntity: LyricsEntity)
|
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
|
package io.github.muntashirakon.music.db
|
||||||
|
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
|
@ -7,4 +21,4 @@ import androidx.room.PrimaryKey
|
||||||
class LyricsEntity(
|
class LyricsEntity(
|
||||||
@PrimaryKey val songId: Int,
|
@PrimaryKey val songId: Int,
|
||||||
val lyrics: String
|
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
|
package io.github.muntashirakon.music.db
|
||||||
|
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
|
@ -24,4 +38,4 @@ interface PlayCountDao {
|
||||||
|
|
||||||
@Query("UPDATE PlayCountEntity SET play_count = play_count + 1 WHERE id = :id")
|
@Query("UPDATE PlayCountEntity SET play_count = play_count + 1 WHERE id = :id")
|
||||||
fun updateQuantity(id: Long)
|
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
|
package io.github.muntashirakon.music.db
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
|
@ -31,4 +45,4 @@ class PlayCountEntity(
|
||||||
val timePlayed: Long,
|
val timePlayed: Long,
|
||||||
@ColumnInfo(name = "play_count")
|
@ColumnInfo(name = "play_count")
|
||||||
var playCount: Int
|
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
|
package io.github.muntashirakon.music.db
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.room.*
|
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
|
@Dao
|
||||||
interface PlaylistDao {
|
interface PlaylistDao {
|
||||||
|
@ -48,12 +59,9 @@ interface PlaylistDao {
|
||||||
@Delete
|
@Delete
|
||||||
suspend fun deletePlaylistSongs(songs: List<SongEntity>)
|
suspend fun deletePlaylistSongs(songs: List<SongEntity>)
|
||||||
|
|
||||||
|
|
||||||
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id= :playlistId")
|
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id= :playlistId")
|
||||||
fun favoritesSongsLiveData(playlistId: Long): LiveData<List<SongEntity>>
|
fun favoritesSongsLiveData(playlistId: Long): LiveData<List<SongEntity>>
|
||||||
|
|
||||||
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id= :playlistId")
|
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id= :playlistId")
|
||||||
fun favoritesSongs(playlistId: Long): List<SongEntity>
|
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
|
package io.github.muntashirakon.music.db
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
@ -14,4 +28,4 @@ class PlaylistEntity(
|
||||||
val playListId: Long = 0,
|
val playListId: Long = 0,
|
||||||
@ColumnInfo(name = "playlist_name")
|
@ColumnInfo(name = "playlist_name")
|
||||||
val playlistName: String
|
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
|
package io.github.muntashirakon.music.db
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
@ -14,4 +28,3 @@ data class PlaylistWithSongs(
|
||||||
)
|
)
|
||||||
val songs: List<SongEntity>
|
val songs: List<SongEntity>
|
||||||
) : 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
|
package io.github.muntashirakon.music.db
|
||||||
|
|
||||||
import androidx.room.Database
|
import androidx.room.Database
|
||||||
|
@ -14,4 +28,4 @@ abstract class RetroDatabase : RoomDatabase() {
|
||||||
abstract fun playCountDao(): PlayCountDao
|
abstract fun playCountDao(): PlayCountDao
|
||||||
abstract fun historyDao(): HistoryDao
|
abstract fun historyDao(): HistoryDao
|
||||||
abstract fun lyricsDao(): LyricsDao
|
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
|
package io.github.muntashirakon.music.db
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
@ -36,4 +50,3 @@ class SongEntity(
|
||||||
@ColumnInfo(name = "album_artist")
|
@ColumnInfo(name = "album_artist")
|
||||||
val albumArtist: String?
|
val albumArtist: String?
|
||||||
) : Parcelable
|
) : 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
|
package io.github.muntashirakon.music.db
|
||||||
|
|
||||||
import io.github.muntashirakon.music.model.Song
|
import io.github.muntashirakon.music.model.Song
|
||||||
|
|
||||||
|
fun List<HistoryEntity>.fromHistoryToSongs(): List<Song> {
|
||||||
|
return map {
|
||||||
|
it.toSong()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun List<SongEntity>.toSongs(): List<Song> {
|
fun List<SongEntity>.toSongs(): List<Song> {
|
||||||
return map {
|
return map {
|
||||||
it.toSong()
|
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
|
package io.github.muntashirakon.music.dialogs
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
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.EXTRA_SONG
|
||||||
import io.github.muntashirakon.music.R
|
import io.github.muntashirakon.music.R
|
||||||
import io.github.muntashirakon.music.db.PlaylistEntity
|
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.db.toSongsEntity
|
||||||
import io.github.muntashirakon.music.extensions.colorButtons
|
import io.github.muntashirakon.music.extensions.colorButtons
|
||||||
import io.github.muntashirakon.music.extensions.extraNotNull
|
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 {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
val playlistEntities: List<PlaylistEntity> =
|
val playlistEntities = extraNotNull<List<PlaylistEntity>>(EXTRA_PLAYLISTS).value
|
||||||
extraNotNull<List<PlaylistEntity>>(EXTRA_PLAYLISTS).value
|
val songs = extraNotNull<List<Song>>(EXTRA_SONG).value
|
||||||
val songs: List<Song> = extraNotNull<List<Song>>(EXTRA_SONG).value
|
val playlistNames = mutableListOf<String>()
|
||||||
val playlistNames: MutableList<String> = mutableListOf()
|
|
||||||
playlistNames.add(requireContext().resources.getString(R.string.action_new_playlist))
|
playlistNames.add(requireContext().resources.getString(R.string.action_new_playlist))
|
||||||
for (entity: PlaylistEntity in playlistEntities) {
|
for (entity: PlaylistEntity in playlistEntities) {
|
||||||
playlistNames.add(entity.playlistName)
|
playlistNames.add(entity.playlistName)
|
||||||
}
|
}
|
||||||
return materialDialog(R.string.add_playlist_title)
|
return materialDialog(R.string.add_playlist_title)
|
||||||
.setItems(playlistNames.toTypedArray()) { _, which ->
|
.setAdapter(
|
||||||
|
playlistAdapter(playlistNames)
|
||||||
|
) { dialog, which ->
|
||||||
if (which == 0) {
|
if (which == 0) {
|
||||||
CreatePlaylistDialog.create(songs)
|
showCreateDialog(songs)
|
||||||
.show(requireActivity().supportFragmentManager, "Dialog")
|
|
||||||
} else {
|
} else {
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
val songEntities: List<SongEntity> =
|
val songEntities = songs.toSongsEntity(playlistEntities[which - 1])
|
||||||
songs.toSongsEntity(playlistEntities[which - 1])
|
|
||||||
libraryViewModel.insertSongs(songEntities)
|
libraryViewModel.insertSongs(songEntities)
|
||||||
libraryViewModel.forceReload(Playlists)
|
libraryViewModel.forceReload(Playlists)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
.create().colorButtons()
|
.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.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
import code.name.monkey.retromusic.R;
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
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();
|
public static BlacklistFolderChooserDialog create() {
|
||||||
private File parentFolder;
|
return new BlacklistFolderChooserDialog();
|
||||||
private File[] parentContents;
|
}
|
||||||
private boolean canGoUp = false;
|
|
||||||
private FolderCallback callback;
|
|
||||||
|
|
||||||
public static BlacklistFolderChooserDialog create() {
|
private String[] getContentsArray() {
|
||||||
return new BlacklistFolderChooserDialog();
|
if (parentContents == null) {
|
||||||
|
if (canGoUp) {
|
||||||
|
return new String[] {".."};
|
||||||
|
}
|
||||||
|
return new String[] {};
|
||||||
}
|
}
|
||||||
|
String[] results = new String[parentContents.length + (canGoUp ? 1 : 0)];
|
||||||
private String[] getContentsArray() {
|
if (canGoUp) {
|
||||||
if (parentContents == null) {
|
results[0] = "..";
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < parentContents.length; i++) {
|
||||||
private File[] listFiles() {
|
results[canGoUp ? i + 1 : i] = parentContents[i].getName();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
private File[] listFiles() {
|
||||||
@Override
|
File[] contents = parentFolder.listFiles();
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
List<File> results = new ArrayList<>();
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
if (contents != null) {
|
||||||
&& ActivityCompat.checkSelfPermission(
|
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)
|
requireActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
!= PackageManager.PERMISSION_GRANTED) {
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
return new MaterialDialog.Builder(requireActivity())
|
return new MaterialDialog.Builder(requireActivity())
|
||||||
.title(R.string.md_error_label)
|
.title(R.string.md_error_label)
|
||||||
.content(R.string.md_storage_perm_error)
|
.content(R.string.md_storage_perm_error)
|
||||||
.positiveText(android.R.string.ok)
|
.positiveText(android.R.string.ok)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
savedInstanceState = new Bundle();
|
savedInstanceState = new Bundle();
|
||||||
}
|
}
|
||||||
if (!savedInstanceState.containsKey("current_path")) {
|
if (!savedInstanceState.containsKey("current_path")) {
|
||||||
savedInstanceState.putString("current_path", initialPath);
|
savedInstanceState.putString("current_path", initialPath);
|
||||||
}
|
}
|
||||||
parentFolder = new File(savedInstanceState.getString("current_path", File.pathSeparator));
|
parentFolder = new File(savedInstanceState.getString("current_path", File.pathSeparator));
|
||||||
checkIfCanGoUp();
|
checkIfCanGoUp();
|
||||||
parentContents = listFiles();
|
parentContents = listFiles();
|
||||||
MaterialDialog.Builder builder = new MaterialDialog.Builder(requireContext())
|
MaterialDialog.Builder builder =
|
||||||
.title(parentFolder.getAbsolutePath())
|
new MaterialDialog.Builder(requireContext())
|
||||||
.items((CharSequence[]) getContentsArray())
|
.title(parentFolder.getAbsolutePath())
|
||||||
.itemsCallback(this)
|
.items((CharSequence[]) getContentsArray())
|
||||||
.autoDismiss(false)
|
.itemsCallback(this)
|
||||||
.onPositive((dialog, which) -> {
|
.autoDismiss(false)
|
||||||
callback.onFolderSelection(BlacklistFolderChooserDialog.this, parentFolder);
|
.onPositive(
|
||||||
dismiss();
|
(dialog, which) -> {
|
||||||
|
callback.onFolderSelection(BlacklistFolderChooserDialog.this, parentFolder);
|
||||||
|
dismiss();
|
||||||
})
|
})
|
||||||
.onNegative((materialDialog, dialogAction) -> dismiss())
|
.onNegative((materialDialog, dialogAction) -> dismiss())
|
||||||
.positiveText(R.string.add_action)
|
.positiveText(R.string.add_action)
|
||||||
.negativeText(android.R.string.cancel);
|
.negativeText(android.R.string.cancel);
|
||||||
return builder.build();
|
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
|
@Override
|
||||||
public void onSelection(MaterialDialog materialDialog, View view, int i, CharSequence s) {
|
public int compare(File lhs, File rhs) {
|
||||||
if (canGoUp && i == 0) {
|
return lhs.getName().compareTo(rhs.getName());
|
||||||
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 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
|
package io.github.muntashirakon.music.dialogs
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
|
@ -26,7 +40,7 @@ import kotlinx.coroutines.launch
|
||||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||||
|
|
||||||
class CreatePlaylistDialog : DialogFragment() {
|
class CreatePlaylistDialog : DialogFragment() {
|
||||||
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
|
private val io.github.muntashirakon.music by sharedViewModel<LibraryViewModel>()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun create(song: Song): CreatePlaylistDialog {
|
fun create(song: Song): CreatePlaylistDialog {
|
||||||
|
@ -54,17 +68,8 @@ class CreatePlaylistDialog : DialogFragment() {
|
||||||
) { _, _ ->
|
) { _, _ ->
|
||||||
val playlistName = playlistView.text.toString()
|
val playlistName = playlistView.text.toString()
|
||||||
if (!TextUtils.isEmpty(playlistName)) {
|
if (!TextUtils.isEmpty(playlistName)) {
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
io.github.muntashirakon.music.addToPlaylist(playlistName, songs)
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
playlistContainer.error = "Playlist is can't be empty"
|
playlistContainer.error = "Playlist is can't be empty"
|
||||||
}
|
}
|
||||||
|
@ -72,4 +77,4 @@ class CreatePlaylistDialog : DialogFragment() {
|
||||||
.create()
|
.create()
|
||||||
.colorButtons()
|
.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
|
package io.github.muntashirakon.music.dialogs
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
|
@ -65,5 +79,4 @@ class DeletePlaylistDialog : DialogFragment() {
|
||||||
.create()
|
.create()
|
||||||
.colorButtons()
|
.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
|
package io.github.muntashirakon.music.dialogs
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
|
@ -67,4 +81,4 @@ class DeleteSongsDialog : DialogFragment() {
|
||||||
.create()
|
.create()
|
||||||
.colorButtons()
|
.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
|
package io.github.muntashirakon.music.dialogs
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
|
@ -21,4 +35,4 @@ class ImportPlaylistDialog : DialogFragment() {
|
||||||
.create()
|
.create()
|
||||||
.colorButtons()
|
.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
|
package io.github.muntashirakon.music.dialogs
|
||||||
|
|
||||||
import android.app.Dialog
|
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.extraNotNull
|
||||||
import io.github.muntashirakon.music.extensions.materialDialog
|
import io.github.muntashirakon.music.extensions.materialDialog
|
||||||
import io.github.muntashirakon.music.fragments.LibraryViewModel
|
import io.github.muntashirakon.music.fragments.LibraryViewModel
|
||||||
import io.github.muntashirakon.music.fragments.ReloadType.Playlists
|
|
||||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||||
|
|
||||||
class RemoveSongFromPlaylistDialog : DialogFragment() {
|
class RemoveSongFromPlaylistDialog : DialogFragment() {
|
||||||
|
@ -60,10 +73,9 @@ class RemoveSongFromPlaylistDialog : DialogFragment() {
|
||||||
.setMessage(pair.second)
|
.setMessage(pair.second)
|
||||||
.setPositiveButton(R.string.remove_action) { _, _ ->
|
.setPositiveButton(R.string.remove_action) { _, _ ->
|
||||||
libraryViewModel.deleteSongsInPlaylist(songs)
|
libraryViewModel.deleteSongsInPlaylist(songs)
|
||||||
libraryViewModel.forceReload(Playlists)
|
|
||||||
}
|
}
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
.create()
|
.create()
|
||||||
.colorButtons()
|
.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
|
package io.github.muntashirakon.music.dialogs
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
|
@ -54,4 +68,4 @@ class RenamePlaylistDialog : DialogFragment() {
|
||||||
.create()
|
.create()
|
||||||
.colorButtons()
|
.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
|
package io.github.muntashirakon.music.dialogs
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
|
import android.media.MediaScannerConnection
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
|
@ -18,7 +33,6 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
|
||||||
class SavePlaylistDialog : DialogFragment() {
|
class SavePlaylistDialog : DialogFragment() {
|
||||||
companion object {
|
companion object {
|
||||||
fun create(playlistWithSongs: PlaylistWithSongs): SavePlaylistDialog {
|
fun create(playlistWithSongs: PlaylistWithSongs): SavePlaylistDialog {
|
||||||
|
@ -33,9 +47,14 @@ class SavePlaylistDialog : DialogFragment() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
val playlistWithSongs: PlaylistWithSongs =
|
val playlistWithSongs = extraNotNull<PlaylistWithSongs>(EXTRA_PLAYLIST).value
|
||||||
extraNotNull<PlaylistWithSongs>(EXTRA_PLAYLIST).value
|
val file = PlaylistsUtil.savePlaylistWithSongs(playlistWithSongs)
|
||||||
val file = PlaylistsUtil.savePlaylistWithSongs(requireContext(), playlistWithSongs)
|
MediaScannerConnection.scanFile(
|
||||||
|
requireActivity(),
|
||||||
|
arrayOf<String>(file.path),
|
||||||
|
null
|
||||||
|
) { _, _ ->
|
||||||
|
}
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
|
@ -52,4 +71,4 @@ class SavePlaylistDialog : DialogFragment() {
|
||||||
.setView(R.layout.loading)
|
.setView(R.layout.loading)
|
||||||
.create().colorButtons()
|
.create().colorButtons()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 Hemanth Savarala.
|
* Copyright (c) 2020 Hemanth Savarla.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3
|
* Licensed under the GNU General Public License v3
|
||||||
*
|
*
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
* This is free software: you can redistribute it and/or modify it
|
||||||
* the terms of the GNU General Public License as published by
|
* 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.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.muntashirakon.music.dialogs
|
package io.github.muntashirakon.music.dialogs
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
@ -130,7 +130,6 @@ class SleepTimerDialog : DialogFragment() {
|
||||||
}
|
}
|
||||||
.create()
|
.create()
|
||||||
.colorButtons()
|
.colorButtons()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateTimeDisplayTime() {
|
private fun updateTimeDisplayTime() {
|
||||||
|
@ -173,4 +172,4 @@ class SleepTimerDialog : DialogFragment() {
|
||||||
updateCancelButton()
|
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