diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 000000000..58639a31a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,42 @@
+---
+name: Bug report
+about: Create a report to help us improve. Please write in English only.
+title: ''
+labels: bug
+assignees: ''
+
+---
+
+**Have you read the [FAQ](https://www.github.com/h4h13/RetroMusicPlayer/tree/dev/FAQ.md)?**
+[Yes/No]
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**How To Reproduce**
+Steps to reproduce the behavior:
+1.
+2.
+3.
+4.
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Crash log**
+If the app is crashing, add a crash log
+
+ Click to view logs
+PASTE YOUR LOGS HERE.
+
+
+**Device info:**
+ - Device: [e.g. OnePlus 7]
+ - Android version: [e.g. Android 9]
+ - App version [e.g. 3.5.300_0517]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 000000000..e2d9f3239
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project. Please write in English only.
+title: ''
+labels: enhancement
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..810f53156
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,76 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and expression,
+level of experience, education, socio-economic status, nationality, personal
+appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at retromusicapp@gmail.com. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see
+https://www.contributor-covenant.org/faq
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..9c190e380
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,35 @@
+# Contributing
+
+## Using the issue tracker
+The [issue tracker](https://github.com/h4h13/RetroMusicPlayer/issues) is the preferred channel for bug reports, feature requests and submitting pull requests, but please follow these rules:
+
+* Please **do not** derail or troll issues. Keep the discussion on topic and respect the opinions of others.
+
+* Please **do not** post comments consisting solely of "+1" or "👍". Use [GitHub's "reactions" feature](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments) instead.
+
+* Please **do not** write [enhancement]/[bug]/[feature request] or similar stuff in the title of issues, as there are labels for that purpose that will be added by devs or collaborators.
+
+## Bug reports
+A bug is a _demonstrable problem_. Good bug reports are extremely helpful, so thanks!
+
+Guidelines for bug reports:
+
+* Use the GitHub issue search, check if the issue has already been reported both in the open issues and in the closed ones, if there are some missing details, add them in issue comments, without creating a new one
+* Check if the issue has been fixed — try to reproduce it using the latest available build
+* Isolate the problem — ideally create a reproducible scenario and a live example
+* Do not report multiple bugs in a single ticket, otherwise it will be confusing.
+
+A good bug report shouldn't leave others needing to chase you up for more information. Please try to be as detailed as possible in your report.
+
+
+## Feature requests
+Feature requests are welcome, please make sure to be as detailed as possible and use screenshots, videos, GIFs, to demonstrate it better, if possible.
+
+
+## Pull requests
+**Please ask first** before embarking on any significant pull request (e.g. implementing features, refactoring code), otherwise you risk spending a lot of time working on something that developers might not want to merge into the project. To avoid that, you can join the official [Telegram group](https://t.me/retromusicapp) or open an issue.
+
+## License
+By contributing your code, you agree to license your contribution under the [GNU General Public License](https://github.com/h4h13/RetroMusicPlayer/blob/dev/LICENSE.md).
+
+Please note we have a code of conduct, please follow it in all your interactions with the project.
diff --git a/FAQ.md b/FAQ.md
index 2ac44e716..efa40c7ac 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -31,8 +31,9 @@ A ".lrc" is like a text file which contains the time stamped lyrics for example,
##### STEP 3:
Now you have to rename the file you created in this way: - .lrc or for better matching copy the and the from the tag editor and then rename the file.
##### STEP 4:
-You have to copy or move this file into a location on the SD Card: whatever_sdcard/RetroMusic/lyrics/ and paste it there.
-Finally you will be able to see the lyrics working.
+Now paste the LRC files to the following path : /sdcard/Retromusic/lyrics/
+Here sdcard is your internal storage.
+
> If you want to skip to particular time stamp, simply scroll to the time stamp from where you want to start from and a 'Play' icon will appear left to the particular stamp. Tap on play button to play from there.
diff --git a/README.md b/README.md
index 9aff14f0f..5eb1de1a4 100644
--- a/README.md
+++ b/README.md
@@ -29,50 +29,50 @@ Material Design music player for Android music lovers
| Classic | Adaptive | Blur | Tiny | Peak |
### 🧭 Navigation never made easier
-Self-explanatory interface without overloaded menus
+Self-explanatory interface without overloaded menus.
### 🎨 Colorful
-You can choose between three different main themes: Clearly white, Kind
-dark and Just black for AMOLED displays. Select your favorite accent
+You can choose between three different main themes: Clearly White, Kinda
+Dark and Just Black for AMOLED displays. Select your favorite accent
color from a color palette.
### 🏠 Home
-Where you can have your recently/ top played Artists, Albums and
-Favorite Songs. No other music player has this feature
+Where you can have your recently/top played artists, albums and
+favorite songs. No other music player has this feature.
### 📦 Included Features
-- Base 3 themes (Clearly white, Kinda dark and Just Black)
+- Base 3 themes (Clearly White, Kinda Dark and Just Black)
- Choose from 10+ now playing themes
-- Drive Mode
+- Driving Mode
- Headset/Bluetooth support
-- Music Duration Filter
+- Music duration filter
- Folder support - Play song by folder
- Gapless playback
- Volume controls
-- More than 10 Now playing themes
- Carousel effect for an album cover
-- Home screen Widgets
-- Lock Screen Playback Controls
-- Lyrics Screen(download and sync with music)
+- Home screen widgets
+- Lock screen playback controls
+- Lyrics screen (download and sync with music)
- Sleep Timer
-- Home screen Widgets
-- Easy Drag to Sort Playlist & Play Queue
+- Easy drag to sort playlist & play queue
- Tag editor
-- Create, Edit, Import playlists
+- Create, edit and import playlists
- Playing queue with reorder
- User profile
- 30 Languages support
-- Browse and play your music by Songs, Albums, Artists, Playlists,
- Genre
-- Smart Auto Playlists - Recently played/Top Played/History Fully
- playlist support & Build your own playlist on the go
+- Browse and play your music by songs, albums, artists, playlists and
+ genre
+- Smart Auto Playlists - Recently played, most played and history
+- Build your own playlist on the go
-We are trying our best to bring you the best user experience. Until now
-it is a beta version - bug fixes (if any) and more features are on the
-way. for FAQ's https://goo.gl/DR2mE2
+We are trying our best to bring you the best user experience. The app is regulary being updated for bug fixes and new features.
### 🗂️ License
Metro is released under the GNU General Public License v3.0
(GPLv3), which can be found here: [License](LICENSE.md)
+
+
+>Please note: Retro Music player is an offline music player app. It
+>doesn't support music downloading or online music streaming.
diff --git a/app/build.gradle b/app/build.gradle
index 851e95dfc..6b4cc101a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -80,17 +80,18 @@ dependencies {
implementation "androidx.gridlayout:gridlayout:1.0.0"
implementation "androidx.cardview:cardview:1.0.0"
implementation "androidx.viewpager2:viewpager2:1.1.0-alpha01"
- implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.preference:preference-ktx:1.1.1'
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.fragment:fragment-ktx:1.2.5'
implementation 'androidx.palette:palette-ktx:1.0.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta8'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.0-rc1'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
- implementation 'com.google.android.material:material:1.3.0-alpha01'
+ implementation 'com.google.android.material:material:1.3.0-alpha02'
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
def retrofit_version = '2.9.0'
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
@@ -144,5 +145,4 @@ dependencies {
def nav_version = "2.3.0"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
-
}
\ No newline at end of file
diff --git a/app/release/output.json b/app/release/output.json
deleted file mode 100644
index 758f3ea4a..000000000
--- a/app/release/output.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "version": 1,
- "artifactType": {
- "type": "APK",
- "kind": "Directory"
- },
- "applicationId": "code.name.monkey.retromusic",
- "variantName": "release",
- "elements": [
- {
- "type": "SINGLE",
- "filters": [],
- "properties": [],
- "versionCode": 10438,
- "versionName": "10438",
- "enabled": true,
- "outputFile": "app-release.apk"
- }
- ]
-}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 30cf2312c..d90e768d1 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -20,12 +20,12 @@
-
-
-
-
+
-
-
-
+
diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png
index 991844b5e..f9c45db6b 100644
Binary files a/app/src/main/ic_launcher-playstore.png and b/app/src/main/ic_launcher-playstore.png differ
diff --git a/app/src/main/java/io/github/muntashirakon/music/Constants.kt b/app/src/main/java/io/github/muntashirakon/music/Constants.kt
index fd01d4335..85c8c327b 100644
--- a/app/src/main/java/io/github/muntashirakon/music/Constants.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/Constants.kt
@@ -47,13 +47,17 @@ object Constants {
MediaStore.Audio.AudioColumns.ALBUM, // 8
MediaStore.Audio.AudioColumns.ARTIST_ID, // 9
MediaStore.Audio.AudioColumns.ARTIST,// 10
- MediaStore.Audio.AudioColumns.COMPOSER// 11
+ MediaStore.Audio.AudioColumns.COMPOSER,// 11
+ "album_artist"//12
)
const val NUMBER_OF_TOP_TRACKS = 99
}
+const val EXTRA_GENRE = "extra_genre"
+const val EXTRA_PLAYLIST = "extra_playlist"
+const val EXTRA_ALBUM_ID = "extra_album_id"
+const val EXTRA_ARTIST_ID = "extra_artist_id"
const val EXTRA_SONG = "extra_songs"
-const val EXTRA_PLAYLIST = "extra_list"
const val LIBRARY_CATEGORIES = "library_categories"
const val EXTRA_SONG_INFO = "extra_song_info"
const val DESATURATED_COLOR = "desaturated_color"
diff --git a/app/src/main/java/io/github/muntashirakon/music/HomeSection.kt b/app/src/main/java/io/github/muntashirakon/music/HomeSection.kt
new file mode 100644
index 000000000..237e5bca6
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/HomeSection.kt
@@ -0,0 +1,25 @@
+package io.github.muntashirakon.music
+
+import androidx.annotation.IntDef
+
+@IntDef(
+ RECENT_ALBUMS,
+ TOP_ALBUMS,
+ RECENT_ARTISTS,
+ TOP_ARTISTS,
+ SUGGESTIONS,
+ FAVOURITES,
+ GENRES,
+ PLAYLISTS
+)
+@Retention(AnnotationRetention.SOURCE)
+annotation class HomeSection
+
+const val RECENT_ALBUMS = 3
+const val TOP_ALBUMS = 1
+const val RECENT_ARTISTS = 2
+const val TOP_ARTISTS = 0
+const val SUGGESTIONS = 5
+const val FAVOURITES = 4
+const val GENRES = 6
+const val PLAYLISTS = 7
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/MainModule.kt b/app/src/main/java/io/github/muntashirakon/music/MainModule.kt
index 303776da1..af439dcb6 100644
--- a/app/src/main/java/io/github/muntashirakon/music/MainModule.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/MainModule.kt
@@ -1,24 +1,70 @@
package io.github.muntashirakon.music
-import io.github.muntashirakon.music.activities.albums.AlbumDetailsViewModel
-import io.github.muntashirakon.music.activities.artists.ArtistDetailsViewModel
-import io.github.muntashirakon.music.activities.genre.GenreDetailsViewModel
-import io.github.muntashirakon.music.activities.playlist.PlaylistDetailsViewModel
-import io.github.muntashirakon.music.activities.search.SearchViewModel
import io.github.muntashirakon.music.fragments.LibraryViewModel
+import io.github.muntashirakon.music.fragments.albums.AlbumDetailsViewModel
+import io.github.muntashirakon.music.fragments.artists.ArtistDetailsViewModel
+import io.github.muntashirakon.music.fragments.genres.GenreDetailsViewModel
+import io.github.muntashirakon.music.fragments.playlists.PlaylistDetailsViewModel
+import io.github.muntashirakon.music.fragments.search.SearchViewModel
import io.github.muntashirakon.music.model.Genre
import io.github.muntashirakon.music.model.Playlist
import io.github.muntashirakon.music.network.networkModule
-import io.github.muntashirakon.music.providers.RepositoryImpl
-import org.eclipse.egit.github.core.Repository
+import io.github.muntashirakon.music.repository.*
+import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.bind
import org.koin.dsl.module
private val dataModule = module {
single {
- RepositoryImpl(get(), get())
+ RealRepository(get(), get(), get(), get(), get(), get(), get(), get(), get(), get())
} bind Repository::class
+
+ single {
+ RealSongRepository(get())
+ } bind SongRepository::class
+
+ single {
+ RealGenreRepository(get(), get())
+ } bind GenreRepository::class
+
+ single {
+ RealAlbumRepository(get())
+ } bind AlbumRepository::class
+
+ single {
+ RealArtistRepository(get(), get())
+ } bind ArtistRepository::class
+
+ single {
+ RealPlaylistRepository(get())
+ } bind PlaylistRepository::class
+
+ single {
+ RealTopPlayedRepository(get(), get(), get(), get())
+ } bind TopPlayedRepository::class
+
+ single {
+ RealLastAddedRepository(
+ get(),
+ get(),
+ get()
+ )
+ } bind LastAddedRepository::class
+
+ single {
+ RealSearchRepository(
+ get(),
+ get(),
+ get(),
+ get(),
+ get()
+ )
+ }
+
+ single {
+ androidContext().contentResolver
+ }
}
private val viewModules = module {
@@ -28,19 +74,31 @@ private val viewModules = module {
}
viewModel { (albumId: Int) ->
- AlbumDetailsViewModel(get(), albumId)
+ AlbumDetailsViewModel(
+ get(),
+ albumId
+ )
}
viewModel { (artistId: Int) ->
- ArtistDetailsViewModel(get(), artistId)
+ ArtistDetailsViewModel(
+ get(),
+ artistId
+ )
}
viewModel { (playlist: Playlist) ->
- PlaylistDetailsViewModel(get(), playlist)
+ PlaylistDetailsViewModel(
+ get(),
+ playlist
+ )
}
viewModel { (genre: Genre) ->
- GenreDetailsViewModel(get(), genre)
+ GenreDetailsViewModel(
+ get(),
+ genre
+ )
}
viewModel {
diff --git a/app/src/main/java/io/github/muntashirakon/music/Result.kt b/app/src/main/java/io/github/muntashirakon/music/Result.kt
new file mode 100644
index 000000000..e99868a98
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/Result.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2020 Fatih Giris. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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
+
+/**
+ * Generic class that holds the network state
+ */
+sealed class Result {
+ data class Success(val data: T) : Result()
+ object Loading : Result()
+ object Error : Result()
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/LyricsActivity.kt b/app/src/main/java/io/github/muntashirakon/music/activities/LyricsActivity.kt
index 70df03e08..4ca69a924 100644
--- a/app/src/main/java/io/github/muntashirakon/music/activities/LyricsActivity.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/activities/LyricsActivity.kt
@@ -20,7 +20,6 @@ import kotlinx.android.synthetic.main.activity_lyrics.*
class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.Callback {
private lateinit var updateHelper: MusicProgressViewUpdateHelper
-
private lateinit var song: Song
private val googleSearchLrcUrl: String
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/MainActivity.kt b/app/src/main/java/io/github/muntashirakon/music/activities/MainActivity.kt
index 4c15facbe..665823529 100644
--- a/app/src/main/java/io/github/muntashirakon/music/activities/MainActivity.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/activities/MainActivity.kt
@@ -1,83 +1,44 @@
package io.github.muntashirakon.music.activities
-import android.app.ActivityOptions
-import android.content.*
+import android.content.Intent
+import android.content.SharedPreferences
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
-import android.view.Menu
-import android.view.MenuItem
-import android.view.SubMenu
import android.view.View
-import androidx.core.app.ActivityCompat
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.commit
-import code.name.monkey.appthemehelper.util.ATHUtil.resolveColor
-import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
-import io.github.muntashirakon.music.R
+import androidx.lifecycle.lifecycleScope
+import io.github.muntashirakon.music.*
import io.github.muntashirakon.music.activities.base.AbsSlidingMusicPanelActivity
-import io.github.muntashirakon.music.dialogs.CreatePlaylistDialog.Companion.create
+import io.github.muntashirakon.music.extensions.findNavController
import io.github.muntashirakon.music.fragments.LibraryViewModel
-import io.github.muntashirakon.music.fragments.albums.AlbumsFragment
-import io.github.muntashirakon.music.fragments.artists.ArtistsFragment
-import io.github.muntashirakon.music.fragments.base.AbsRecyclerViewCustomGridSizeFragment
-import io.github.muntashirakon.music.fragments.folder.FoldersFragment
-import io.github.muntashirakon.music.fragments.genres.GenresFragment
-import io.github.muntashirakon.music.fragments.home.BannerHomeFragment
-import io.github.muntashirakon.music.fragments.playlists.PlaylistsFragment
-import io.github.muntashirakon.music.fragments.queue.PlayingQueueFragment
-import io.github.muntashirakon.music.fragments.songs.SongsFragment
-import io.github.muntashirakon.music.helper.MusicPlayerRemote.isPlaying
import io.github.muntashirakon.music.helper.MusicPlayerRemote.openAndShuffleQueue
import io.github.muntashirakon.music.helper.MusicPlayerRemote.openQueue
import io.github.muntashirakon.music.helper.MusicPlayerRemote.playFromUri
import io.github.muntashirakon.music.helper.MusicPlayerRemote.shuffleMode
import io.github.muntashirakon.music.helper.SearchQueryHelper.getSongs
-import io.github.muntashirakon.music.helper.SortOrder.*
-import io.github.muntashirakon.music.interfaces.CabHolder
-import io.github.muntashirakon.music.interfaces.MainActivityFragmentCallbacks
-import io.github.muntashirakon.music.loaders.AlbumLoader.getAlbum
-import io.github.muntashirakon.music.loaders.ArtistLoader.getArtist
-import io.github.muntashirakon.music.loaders.PlaylistSongsLoader.getPlaylistSongList
import io.github.muntashirakon.music.model.Song
+import io.github.muntashirakon.music.repository.PlaylistSongsLoader.getPlaylistSongList
+import io.github.muntashirakon.music.repository.Repository
import io.github.muntashirakon.music.service.MusicService
import io.github.muntashirakon.music.util.AppRater.appLaunched
-import io.github.muntashirakon.music.util.NavigationUtil
import io.github.muntashirakon.music.util.PreferenceUtil
-import io.github.muntashirakon.music.util.RetroColorUtil
-import io.github.muntashirakon.music.util.RetroUtil
-import com.afollestad.materialcab.MaterialCab
-import com.google.android.material.appbar.AppBarLayout
-import io.github.muntashirakon.music.*
-import kotlinx.android.synthetic.main.activity_main_content.*
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import java.util.*
-class MainActivity : AbsSlidingMusicPanelActivity(),
- SharedPreferences.OnSharedPreferenceChangeListener, CabHolder {
+class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeListener {
companion object {
const val TAG = "MainActivity"
const val EXPAND_PANEL = "expand_panel"
+ const val APP_UPDATE_REQUEST_CODE = 9002
}
- private val libraryViewModel: LibraryViewModel by inject()
- private var cab: MaterialCab? = null
- private val intentFilter = IntentFilter(Intent.ACTION_SCREEN_OFF)
- private lateinit var currentFragment: MainActivityFragmentCallbacks
+ private val repository by inject()
+ private val libraryViewModel by inject()
+
private var blockRequestPermissions = false
- private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- val action = intent.action
- if (action != null && action == Intent.ACTION_SCREEN_OFF) {
- if (PreferenceUtil.isLockScreen && isPlaying) {
- val activity = Intent(context, LockScreenActivity::class.java)
- activity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- activity.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
- ActivityCompat.startActivity(context, activity, null)
- }
- }
- }
- }
override fun createContentView(): View {
return wrapSlidingMusicPanel(R.layout.activity_main_content)
@@ -91,29 +52,16 @@ class MainActivity : AbsSlidingMusicPanelActivity(),
setLightNavigationBar(true)
setTaskDescriptionColorAuto()
hideStatusBar()
- setBottomBarVisibility(View.VISIBLE)
-
- addMusicServiceEventListener(libraryViewModel)
- if (savedInstanceState == null) {
- selectedFragment(PreferenceUtil.lastPage)
- } else {
- restoreCurrentFragment()
- }
-
appLaunched(this)
- setupToolbar()
+ addMusicServiceEventListener(libraryViewModel)
updateTabs()
- getBottomNavigationView().selectedItemId = PreferenceUtil.lastPage
- getBottomNavigationView().setOnNavigationItemSelectedListener {
- PreferenceUtil.lastPage = it.itemId
- selectedFragment(it.itemId)
- true
- }
}
+ override fun onSupportNavigateUp(): Boolean =
+ findNavController(R.id.fragment_container).navigateUp()
+
override fun onResume() {
super.onResume()
- registerReceiver(broadcastReceiver, intentFilter)
PreferenceUtil.registerOnSharedPreferenceChangedListener(this)
if (intent.hasExtra(EXPAND_PANEL) &&
intent.getBooleanExtra(EXPAND_PANEL, false) &&
@@ -126,389 +74,9 @@ class MainActivity : AbsSlidingMusicPanelActivity(),
override fun onDestroy() {
super.onDestroy()
- unregisterReceiver(broadcastReceiver)
PreferenceUtil.unregisterOnSharedPreferenceChangedListener(this)
}
- override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
- ToolbarContentTintHelper.handleOnPrepareOptionsMenu(this, toolbar)
- return super.onPrepareOptionsMenu(menu)
- }
-
- override fun onCreateOptionsMenu(menu: Menu?): Boolean {
- menuInflater.inflate(R.menu.menu_main, menu)
- menu ?: return super.onCreateOptionsMenu(menu)
- if (isPlaylistPage()) {
- menu.add(0, R.id.action_new_playlist, 1, R.string.new_playlist_title)
- .setIcon(R.drawable.ic_playlist_add)
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
- }
- if (isHomePage()) {
- menu.add(0, R.id.action_mic, 1, getString(R.string.action_search))
- .setIcon(R.drawable.ic_mic)
- .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM)
- }
- if (isFolderPage()) {
- menu.add(0, R.id.action_scan, 0, R.string.scan_media)
- .setIcon(R.drawable.ic_scanner)
- .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM)
- menu.add(0, R.id.action_go_to_start_directory, 1, R.string.action_go_to_start_directory)
- .setIcon(R.drawable.ic_bookmark_music)
- .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM)
- }
- val fragment: Fragment? = getCurrentFragment()
- if (fragment != null && fragment is AbsRecyclerViewCustomGridSizeFragment<*, *>) {
- val gridSizeItem: MenuItem = menu.findItem(R.id.action_grid_size)
- if (RetroUtil.isLandscape()) {
- gridSizeItem.setTitle(R.string.action_grid_size_land)
- }
- setUpGridSizeMenu(fragment, gridSizeItem.subMenu)
- setupLayoutMenu(fragment, menu.findItem(R.id.action_layout_type).subMenu)
- setUpSortOrderMenu(fragment, menu.findItem(R.id.action_sort_order).subMenu)
- } else {
- menu.removeItem(R.id.action_layout_type)
- menu.removeItem(R.id.action_grid_size)
- menu.removeItem(R.id.action_sort_order)
- }
- menu.add(0, R.id.action_settings, 6, getString(R.string.action_settings))
- .setIcon(R.drawable.ic_settings)
- .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM)
- menu.add(0, R.id.action_search, 0, getString(R.string.action_search))
- .setIcon(R.drawable.ic_search)
- .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS)
- ToolbarContentTintHelper.handleOnCreateOptionsMenu(
- this,
- toolbar,
- menu,
- getToolbarBackgroundColor(toolbar)
- )
- return super.onCreateOptionsMenu(menu)
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- val fragment = getCurrentFragment()
- if (fragment is AbsRecyclerViewCustomGridSizeFragment<*, *>) {
- if (handleGridSizeMenuItem(fragment, item)) {
- return true
- }
- if (handleLayoutResType(fragment, item)) {
- return true
- }
- if (handleSortOrderMenuItem(fragment, item)) {
- return true
- }
- }
- when (item.itemId) {
- R.id.action_search -> NavigationUtil.goToSearch(this)
- R.id.action_new_playlist -> {
- create().show(supportFragmentManager, "CREATE_PLAYLIST")
- return true
- }
- R.id.action_mic -> {
- val options = ActivityOptions.makeSceneTransitionAnimation(
- this, toolbar,
- getString(R.string.transition_toolbar)
- )
- NavigationUtil.goToSearch(this, true, options)
- return true
- }
- R.id.action_settings -> {
- NavigationUtil.goToSettings(this)
- return true
- }
- }
- return super.onOptionsItemSelected(item)
- }
-
- private fun handleSortOrderMenuItem(
- fragment: AbsRecyclerViewCustomGridSizeFragment<*, *>,
- item: MenuItem
- ): Boolean {
- var sortOrder: String? = null
- when (fragment) {
- is AlbumsFragment -> {
- when (item.itemId) {
- R.id.action_album_sort_order_asc -> sortOrder = AlbumSortOrder.ALBUM_A_Z
- R.id.action_album_sort_order_desc -> sortOrder = AlbumSortOrder.ALBUM_Z_A
- R.id.action_album_sort_order_artist -> sortOrder = AlbumSortOrder.ALBUM_ARTIST
- R.id.action_album_sort_order_year -> sortOrder = AlbumSortOrder.ALBUM_YEAR
- }
- }
- is ArtistsFragment -> {
- when (item.itemId) {
- R.id.action_artist_sort_order_asc -> sortOrder = ArtistSortOrder.ARTIST_A_Z
- R.id.action_artist_sort_order_desc -> sortOrder = ArtistSortOrder.ARTIST_Z_A
- }
- }
- is SongsFragment -> {
- when (item.itemId) {
- R.id.action_song_sort_order_asc -> sortOrder = SongSortOrder.SONG_A_Z
- R.id.action_song_sort_order_desc -> sortOrder = SongSortOrder.SONG_Z_A
- R.id.action_song_sort_order_artist -> sortOrder = SongSortOrder.SONG_ARTIST
- R.id.action_song_sort_order_album -> sortOrder = SongSortOrder.SONG_ALBUM
- R.id.action_song_sort_order_year -> sortOrder = SongSortOrder.SONG_YEAR
- R.id.action_song_sort_order_date -> sortOrder = SongSortOrder.SONG_DATE
- R.id.action_song_sort_order_composer -> sortOrder = SongSortOrder.COMPOSER
- R.id.action_song_sort_order_date_modified ->
- sortOrder = SongSortOrder.SONG_DATE_MODIFIED
- }
- }
- }
-
- if (sortOrder != null) {
- item.isChecked = true
- fragment.setAndSaveSortOrder(sortOrder)
- return true
- }
-
- return false
- }
-
- private fun handleLayoutResType(
- fragment: AbsRecyclerViewCustomGridSizeFragment<*, *>,
- item: MenuItem
- ): Boolean {
- var layoutRes = -1
- when (item.itemId) {
- R.id.action_layout_normal -> layoutRes = R.layout.item_grid
- R.id.action_layout_card -> layoutRes = R.layout.item_card
- R.id.action_layout_colored_card -> layoutRes = R.layout.item_card_color
- R.id.action_layout_circular -> layoutRes = R.layout.item_grid_circle
- R.id.action_layout_image -> layoutRes = R.layout.image
- R.id.action_layout_gradient_image -> layoutRes = R.layout.item_image_gradient
- }
- if (layoutRes != -1) {
- item.isChecked = true
- fragment.setAndSaveLayoutRes(layoutRes)
- return true
- }
- return false
- }
-
- private fun handleGridSizeMenuItem(
- fragment: AbsRecyclerViewCustomGridSizeFragment<*, *>,
- item: MenuItem
- ): Boolean {
- var gridSize = 0
- when (item.itemId) {
- R.id.action_grid_size_1 -> gridSize = 1
- R.id.action_grid_size_2 -> gridSize = 2
- R.id.action_grid_size_3 -> gridSize = 3
- R.id.action_grid_size_4 -> gridSize = 4
- R.id.action_grid_size_5 -> gridSize = 5
- R.id.action_grid_size_6 -> gridSize = 6
- R.id.action_grid_size_7 -> gridSize = 7
- R.id.action_grid_size_8 -> gridSize = 8
- }
- if (gridSize > 0) {
- item.isChecked = true
- fragment.setAndSaveGridSize(gridSize)
- return true
- }
- return false
- }
-
- private fun setUpGridSizeMenu(
- fragment: AbsRecyclerViewCustomGridSizeFragment<*, *>,
- gridSizeMenu: SubMenu
- ) {
- when (fragment.getGridSize()) {
- 1 -> gridSizeMenu.findItem(R.id.action_grid_size_1).isChecked = true
- 2 -> gridSizeMenu.findItem(R.id.action_grid_size_2).isChecked = true
- 3 -> gridSizeMenu.findItem(R.id.action_grid_size_3).isChecked = true
- 4 -> gridSizeMenu.findItem(R.id.action_grid_size_4).isChecked = true
- 5 -> gridSizeMenu.findItem(R.id.action_grid_size_5).isChecked = true
- 6 -> gridSizeMenu.findItem(R.id.action_grid_size_6).isChecked = true
- 7 -> gridSizeMenu.findItem(R.id.action_grid_size_7).isChecked = true
- 8 -> gridSizeMenu.findItem(R.id.action_grid_size_8).isChecked = true
- }
- val maxGridSize = fragment.maxGridSize
- if (maxGridSize < 8) {
- gridSizeMenu.findItem(R.id.action_grid_size_8).isVisible = false
- }
- if (maxGridSize < 7) {
- gridSizeMenu.findItem(R.id.action_grid_size_7).isVisible = false
- }
- if (maxGridSize < 6) {
- gridSizeMenu.findItem(R.id.action_grid_size_6).isVisible = false
- }
- if (maxGridSize < 5) {
- gridSizeMenu.findItem(R.id.action_grid_size_5).isVisible = false
- }
- if (maxGridSize < 4) {
- gridSizeMenu.findItem(R.id.action_grid_size_4).isVisible = false
- }
- if (maxGridSize < 3) {
- gridSizeMenu.findItem(R.id.action_grid_size_3).isVisible = false
- }
- }
-
- private fun setupLayoutMenu(
- fragment: AbsRecyclerViewCustomGridSizeFragment<*, *>,
- subMenu: SubMenu
- ) {
- when (fragment.itemLayoutRes()) {
- R.layout.item_card ->
- subMenu.findItem(R.id.action_layout_card).isChecked = true
- R.layout.item_card_color ->
- subMenu.findItem(R.id.action_layout_colored_card).isChecked = true
- R.layout.item_grid_circle ->
- subMenu.findItem(R.id.action_layout_circular).isChecked = true
- R.layout.image ->
- subMenu.findItem(R.id.action_layout_image).isChecked = true
- R.layout.item_image_gradient ->
- subMenu.findItem(R.id.action_layout_gradient_image).isChecked = true
- R.layout.item_grid ->
- subMenu.findItem(R.id.action_layout_normal).isChecked = true
- else ->
- subMenu.findItem(R.id.action_layout_normal).isChecked = true
- }
- }
-
- private fun setUpSortOrderMenu(
- fragment: AbsRecyclerViewCustomGridSizeFragment<*, *>,
- sortOrderMenu: SubMenu
- ) {
- val currentSortOrder = fragment.getSortOrder()
- sortOrderMenu.clear()
- when (fragment) {
- is AlbumsFragment -> {
- sortOrderMenu.add(
- 0,
- R.id.action_album_sort_order_asc,
- 0,
- R.string.sort_order_a_z
- ).isChecked = currentSortOrder == AlbumSortOrder.ALBUM_A_Z
- sortOrderMenu.add(
- 0,
- R.id.action_album_sort_order_desc,
- 1,
- R.string.sort_order_z_a
- ).isChecked =
- currentSortOrder == AlbumSortOrder.ALBUM_Z_A
- sortOrderMenu.add(
- 0,
- R.id.action_album_sort_order_artist,
- 2,
- R.string.sort_order_artist
- ).isChecked =
- currentSortOrder == AlbumSortOrder.ALBUM_ARTIST
- sortOrderMenu.add(
- 0,
- R.id.action_album_sort_order_year,
- 3,
- R.string.sort_order_year
- ).isChecked =
- currentSortOrder == AlbumSortOrder.ALBUM_YEAR
- }
- is ArtistsFragment -> {
- sortOrderMenu.add(
- 0,
- R.id.action_artist_sort_order_asc,
- 0,
- R.string.sort_order_a_z
- ).isChecked =
- currentSortOrder == ArtistSortOrder.ARTIST_A_Z
- sortOrderMenu.add(
- 0,
- R.id.action_artist_sort_order_desc,
- 1,
- R.string.sort_order_z_a
- ).isChecked =
- currentSortOrder == ArtistSortOrder.ARTIST_Z_A
- }
- is SongsFragment -> {
- sortOrderMenu.add(
- 0,
- R.id.action_song_sort_order_asc,
- 0,
- R.string.sort_order_a_z
- ).isChecked =
- currentSortOrder == SongSortOrder.SONG_A_Z
- sortOrderMenu.add(
- 0,
- R.id.action_song_sort_order_desc,
- 1,
- R.string.sort_order_z_a
- ).isChecked =
- currentSortOrder == SongSortOrder.SONG_Z_A
- sortOrderMenu.add(
- 0,
- R.id.action_song_sort_order_artist,
- 2,
- R.string.sort_order_artist
- ).isChecked =
- currentSortOrder == SongSortOrder.SONG_ARTIST
- sortOrderMenu.add(
- 0,
- R.id.action_song_sort_order_album,
- 3,
- R.string.sort_order_album
- ).isChecked =
- currentSortOrder == SongSortOrder.SONG_ALBUM
- sortOrderMenu.add(
- 0,
- R.id.action_song_sort_order_year,
- 4,
- R.string.sort_order_year
- ).isChecked =
- currentSortOrder == SongSortOrder.SONG_YEAR
- sortOrderMenu.add(
- 0,
- R.id.action_song_sort_order_date,
- 5,
- R.string.sort_order_date
- ).isChecked =
- currentSortOrder == SongSortOrder.SONG_DATE
- sortOrderMenu.add(
- 0,
- R.id.action_song_sort_order_date_modified,
- 6,
- R.string.sort_order_date_modified
- ).isChecked = currentSortOrder == SongSortOrder.SONG_DATE_MODIFIED
- sortOrderMenu.add(
- 0,
- R.id.action_song_sort_order_composer,
- 7,
- R.string.sort_order_composer
- ).isChecked = currentSortOrder == SongSortOrder.COMPOSER
- }
- }
- sortOrderMenu.setGroupCheckable(0, true, true)
- }
-
- private fun getCurrentFragment(): Fragment? {
- return supportFragmentManager.findFragmentById(R.id.fragment_container)
- }
-
- private fun isFolderPage(): Boolean {
- return supportFragmentManager.findFragmentByTag(FoldersFragment.TAG) is FoldersFragment
- }
-
- private fun isHomePage(): Boolean {
- return supportFragmentManager.findFragmentByTag(BannerHomeFragment.TAG) is BannerHomeFragment
- }
-
- private fun isPlaylistPage(): Boolean {
- return supportFragmentManager.findFragmentByTag(PlaylistsFragment.TAG) is PlaylistsFragment
- }
-
- fun addOnAppBarOffsetChangedListener(
- changedListener: AppBarLayout.OnOffsetChangedListener
- ) {
- appBarLayout.addOnOffsetChangedListener(changedListener)
- }
-
- fun removeOnAppBarOffsetChangedListener(
- changedListener: AppBarLayout.OnOffsetChangedListener
- ) {
- appBarLayout.removeOnOffsetChangedListener(changedListener)
- }
-
- fun getTotalAppBarScrollingRange(): Int {
- return appBarLayout.totalScrollRange
- }
-
override fun requestPermissions() {
if (!blockRequestPermissions) {
super.requestPermissions()
@@ -522,76 +90,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(),
}
}
- private fun setupToolbar() {
- toolbar.setBackgroundColor(resolveColor(this, R.attr.colorSurface))
- appBarLayout.setBackgroundColor(resolveColor(this, R.attr.colorSurface))
- setSupportActionBar(toolbar)
- }
-
- private fun setCurrentFragment(
- fragment: Fragment,
- tag: String
- ) {
- supportFragmentManager.commit {
- setCustomAnimations(
- R.anim.retro_fragment_open_enter,
- R.anim.retro_fragment_open_exit,
- R.anim.retro_fragment_fade_enter,
- R.anim.retro_fragment_fade_exit
- )
- replace(R.id.fragment_container, fragment, tag)
- }
- currentFragment = fragment as MainActivityFragmentCallbacks
- }
-
- private fun selectedFragment(itemId: Int) {
- when (itemId) {
- R.id.action_album -> setCurrentFragment(
- AlbumsFragment.newInstance(),
- AlbumsFragment.TAG
- )
- R.id.action_artist -> setCurrentFragment(
- ArtistsFragment.newInstance(),
- ArtistsFragment.TAG
- )
- R.id.action_playlist -> setCurrentFragment(
- PlaylistsFragment.newInstance(),
- PlaylistsFragment.TAG
- )
- R.id.action_genre -> setCurrentFragment(
- GenresFragment.newInstance(),
- GenresFragment.TAG
- )
- R.id.action_playing_queue -> setCurrentFragment(
- PlayingQueueFragment.newInstance(),
- PlayingQueueFragment.TAG
- )
- R.id.action_song -> setCurrentFragment(
- SongsFragment.newInstance(),
- SongsFragment.TAG
- )
- R.id.action_folder -> setCurrentFragment(
- FoldersFragment.newInstance(this),
- FoldersFragment.TAG
- )
- R.id.action_home -> setCurrentFragment(
- BannerHomeFragment.newInstance(),
- BannerHomeFragment.TAG
- )
- else -> setCurrentFragment(
- BannerHomeFragment.newInstance(),
- BannerHomeFragment.TAG
- )
- }
- }
-
- private fun restoreCurrentFragment() {
- val fragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
- if (fragment != null) {
- currentFragment = fragment as MainActivityFragmentCallbacks
- }
- }
-
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
if (key == GENERAL_THEME || key == BLACK_THEME || key == ADAPTIVE_COLOR_APP || key == USER_NAME || key == TOGGLE_FULL_SCREEN || key == TOGGLE_VOLUME || key == ROUND_CORNERS || key == CAROUSEL_EFFECT || key == NOW_PLAYING_SCREEN_ID || key == TOGGLE_GENRE || key == BANNER_IMAGE_PATH || key == PROFILE_IMAGE_PATH || key == CIRCULAR_ALBUM_ART || key == KEEP_SCREEN_ON || key == TOGGLE_SEPARATE_LINE || key == TOGGLE_HOME_BANNER || key == TOGGLE_ADD_CONTROLS || key == ALBUM_COVER_STYLE || key == HOME_ARTIST_GRID_STYLE || key == ALBUM_COVER_TRANSFORM || key == DESATURATED_COLOR || key == EXTRA_SONG_INFO || key == TAB_TEXT_MODE || key == LANGUAGE_NAME || key == LIBRARY_CATEGORIES
) {
@@ -637,16 +135,20 @@ class MainActivity : AbsSlidingMusicPanelActivity(),
} else if (MediaStore.Audio.Albums.CONTENT_TYPE == mimeType) {
val id = parseIdFromIntent(intent, "albumId", "album").toInt()
if (id >= 0) {
- val position = intent.getIntExtra("position", 0)
- openQueue(getAlbum(this, id).songs!!, position, true)
- handled = true
+ lifecycleScope.launch(Dispatchers.Main) {
+ val position = intent.getIntExtra("position", 0)
+ openQueue(repository.albumById(id).songs!!, position, true)
+ handled = true
+ }
}
} else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) {
val id = parseIdFromIntent(intent, "artistId", "artist").toInt()
if (id >= 0) {
- val position = intent.getIntExtra("position", 0)
- openQueue(getArtist(this, id).songs, position, true)
- handled = true
+ lifecycleScope.launch {
+ val position = intent.getIntExtra("position", 0)
+ openQueue(repository.artistById(id).songs, position, true)
+ handled = true
+ }
}
}
if (handled) {
@@ -671,31 +173,4 @@ class MainActivity : AbsSlidingMusicPanelActivity(),
}
return id
}
-
- override fun handleBackPress(): Boolean {
- if (cab != null && cab!!.isActive) {
- cab?.finish()
- return true
- }
- return super.handleBackPress() || currentFragment.handleBackPress()
- }
-
- override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
- cab?.let {
- if (it.isActive) it.finish()
- }
- cab = MaterialCab(this, R.id.cab_stub)
- .setMenu(menuRes)
- .setCloseDrawableRes(R.drawable.ic_close)
- .setBackgroundColor(
- RetroColorUtil.shiftBackgroundColorForLightText(
- resolveColor(
- this,
- R.attr.colorSurface
- )
- )
- )
- .start(callback)
- return cab as MaterialCab
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/PlayingQueueActivity.kt b/app/src/main/java/io/github/muntashirakon/music/activities/PlayingQueueActivity.kt
index 17f91853c..ad4661670 100644
--- a/app/src/main/java/io/github/muntashirakon/music/activities/PlayingQueueActivity.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/activities/PlayingQueueActivity.kt
@@ -7,6 +7,11 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
+import com.h6ah4i.android.widget.advrecyclerview.animator.DraggableItemAnimator
+import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager
+import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager
+import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager
+import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.activities.base.AbsMusicServiceActivity
import io.github.muntashirakon.music.adapter.song.PlayingQueueAdapter
@@ -14,11 +19,7 @@ import io.github.muntashirakon.music.extensions.accentColor
import io.github.muntashirakon.music.extensions.surfaceColor
import io.github.muntashirakon.music.helper.MusicPlayerRemote
import io.github.muntashirakon.music.util.MusicUtil
-import com.h6ah4i.android.widget.advrecyclerview.animator.DraggableItemAnimator
-import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager
-import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager
-import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager
-import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
+import io.github.muntashirakon.music.util.ThemedFastScroller
import kotlinx.android.synthetic.main.activity_playing_queue.*
open class PlayingQueueActivity : AbsMusicServiceActivity() {
@@ -103,7 +104,7 @@ open class PlayingQueueActivity : AbsMusicServiceActivity() {
}
}
})
- //ViewUtil.setUpFastScrollRecyclerViewColor(this, recyclerView)
+ val fastScroller = ThemedFastScroller.create(recyclerView)
}
private fun checkForPadding() {
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/SettingsActivity.kt b/app/src/main/java/io/github/muntashirakon/music/activities/SettingsActivity.kt
old mode 100755
new mode 100644
index 8d038b549..a82d834a7
--- a/app/src/main/java/io/github/muntashirakon/music/activities/SettingsActivity.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/activities/SettingsActivity.kt
@@ -2,26 +2,18 @@ package io.github.muntashirakon.music.activities
import android.os.Bundle
import android.view.MenuItem
-import androidx.annotation.StringRes
-import androidx.fragment.app.Fragment
import androidx.navigation.NavController
-import androidx.navigation.fragment.NavHostFragment
-import androidx.navigation.ui.AppBarConfiguration
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.VersionUtils
+import com.afollestad.materialdialogs.color.ColorChooserDialog
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.activities.base.AbsBaseActivity
import io.github.muntashirakon.music.appshortcuts.DynamicShortcutManager
import io.github.muntashirakon.music.extensions.applyToolbar
-import com.afollestad.materialdialogs.color.ColorChooserDialog
+import io.github.muntashirakon.music.extensions.findNavController
import kotlinx.android.synthetic.main.activity_settings.*
class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback {
-
- private val fragmentManager = supportFragmentManager
- private lateinit var appBarConfiguration: AppBarConfiguration
- private lateinit var navController: NavController
-
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
super.onCreate(savedInstanceState)
@@ -35,56 +27,14 @@ class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback {
private fun setupToolbar() {
setTitle(R.string.action_settings)
applyToolbar(toolbar)
- val navHostFragment =
- supportFragmentManager.findFragmentById(R.id.contentFrame) as NavHostFragment
- val navController: NavController = navHostFragment.navController
+ val navController: NavController = findNavController(R.id.contentFrame)
navController.addOnDestinationChangedListener { _, _, _ ->
toolbar.title = navController.currentDestination?.label
}
-
- //It removes the back button
- //appBarConfiguration = AppBarConfiguration(navController.graph)
- //setupActionBarWithNavController(navController, appBarConfiguration)
}
override fun onSupportNavigateUp(): Boolean {
- return navController.navigateUp() || super.onSupportNavigateUp()
- }
-
- fun setupFragment(fragment: Fragment, @StringRes titleName: Int) {
- val fragmentTransaction = fragmentManager
- .beginTransaction()
- .setCustomAnimations(
- R.anim.sliding_in_left,
- R.anim.sliding_out_right,
- android.R.anim.slide_in_left,
- android.R.anim.slide_out_right
- )
- fragmentTransaction.replace(R.id.contentFrame, fragment, fragment.tag)
- fragmentTransaction.addToBackStack(null)
- fragmentTransaction.commit()
- setTitle(titleName)
- }
-
- override fun onBackPressed() {
- if (fragmentManager.backStackEntryCount == 0) {
- super.onBackPressed()
- } else {
- setTitle(R.string.action_settings)
- fragmentManager.popBackStack()
- }
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- if (item.itemId == android.R.id.home) {
- onBackPressed()
- return true
- }
- return super.onOptionsItemSelected(item)
- }
-
- companion object {
- const val TAG: String = "SettingsActivity"
+ return findNavController(R.id.contentFrame).navigateUp() || super.onSupportNavigateUp()
}
override fun onColorSelection(dialog: ColorChooserDialog, selectedColor: Int) {
@@ -101,4 +51,11 @@ class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback {
override fun onColorChooserDismissed(dialog: ColorChooserDialog) {
}
-}
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ if (item.itemId == android.R.id.home) {
+ onBackPressed()
+ }
+ return super.onOptionsItemSelected(item)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/UserInfoActivity.kt b/app/src/main/java/io/github/muntashirakon/music/activities/UserInfoActivity.kt
index 7606b73e3..4f40dff43 100644
--- a/app/src/main/java/io/github/muntashirakon/music/activities/UserInfoActivity.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/activities/UserInfoActivity.kt
@@ -10,10 +10,16 @@ import android.text.TextUtils
import android.view.MenuItem
import android.widget.Toast
import code.name.monkey.appthemehelper.util.ColorUtil
-import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.engine.DiskCacheStrategy
+import com.bumptech.glide.request.RequestListener
+import com.bumptech.glide.request.target.Target
+import com.github.dhaval2404.imagepicker.ImagePicker
+import com.github.dhaval2404.imagepicker.constant.ImageProvider
import io.github.muntashirakon.music.Constants.USER_BANNER
import io.github.muntashirakon.music.Constants.USER_PROFILE
+import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.activities.base.AbsBaseActivity
import io.github.muntashirakon.music.extensions.accentColor
import io.github.muntashirakon.music.extensions.applyToolbar
@@ -21,13 +27,6 @@ import io.github.muntashirakon.music.glide.ProfileBannerGlideRequest
import io.github.muntashirakon.music.glide.UserProfileGlideRequest
import io.github.muntashirakon.music.util.ImageUtil
import io.github.muntashirakon.music.util.PreferenceUtil
-import com.bumptech.glide.Glide
-import com.bumptech.glide.load.engine.DiskCacheStrategy
-import com.bumptech.glide.request.RequestListener
-import com.bumptech.glide.request.target.Target
-import com.github.dhaval2404.imagepicker.ImagePicker
-import com.github.dhaval2404.imagepicker.constant.ImageProvider
-import io.github.muntashirakon.music.R
import kotlinx.android.synthetic.main.activity_user_info.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -49,7 +48,7 @@ class UserInfoActivity : AbsBaseActivity() {
setLightNavigationBar(true)
applyToolbar(toolbar)
- MaterialUtil.setTint(nameContainer, false)
+ nameContainer.accentColor()
name.setText(PreferenceUtil.userName)
userImage.setOnClickListener {
@@ -161,7 +160,7 @@ class UserInfoActivity : AbsBaseActivity() {
}
private fun saveImage(bitmap: Bitmap, fileName: String) {
- CoroutineScope(Dispatchers.IO).launch() {
+ CoroutineScope(Dispatchers.IO).launch {
val appDir = applicationContext.filesDir
val file = File(appDir, fileName)
var successful = false
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/albums/AlbumDetailsFragment.kt b/app/src/main/java/io/github/muntashirakon/music/activities/albums/AlbumDetailsFragment.kt
deleted file mode 100644
index aafdfc31d..000000000
--- a/app/src/main/java/io/github/muntashirakon/music/activities/albums/AlbumDetailsFragment.kt
+++ /dev/null
@@ -1,250 +0,0 @@
-package io.github.muntashirakon.music.activities.albums
-
-import android.app.ActivityOptions
-import android.os.Bundle
-import android.transition.TransitionInflater
-import android.util.Pair
-import android.view.MenuItem
-import android.view.View
-import androidx.appcompat.app.AppCompatActivity
-import androidx.navigation.fragment.findNavController
-import androidx.recyclerview.widget.DefaultItemAnimator
-import androidx.recyclerview.widget.GridLayoutManager
-import androidx.recyclerview.widget.LinearLayoutManager
-import code.name.monkey.appthemehelper.util.MaterialUtil
-import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.adapter.album.HorizontalAlbumAdapter
-import io.github.muntashirakon.music.adapter.song.SimpleSongAdapter
-import io.github.muntashirakon.music.extensions.extraNotNull
-import io.github.muntashirakon.music.extensions.show
-import io.github.muntashirakon.music.fragments.base.AbsMusicServiceFragment
-import io.github.muntashirakon.music.glide.AlbumGlideRequest
-import io.github.muntashirakon.music.glide.ArtistGlideRequest
-import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
-import io.github.muntashirakon.music.helper.MusicPlayerRemote
-import io.github.muntashirakon.music.model.Album
-import io.github.muntashirakon.music.model.Artist
-import io.github.muntashirakon.music.network.model.LastFmAlbum
-import io.github.muntashirakon.music.util.MusicUtil
-import io.github.muntashirakon.music.util.NavigationUtil
-import io.github.muntashirakon.music.util.PreferenceUtil
-import io.github.muntashirakon.music.util.RetroUtil
-import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
-import com.bumptech.glide.Glide
-import kotlinx.android.synthetic.main.activity_album.*
-import kotlinx.android.synthetic.main.activity_album_content.*
-import org.koin.androidx.viewmodel.ext.android.viewModel
-import org.koin.core.parameter.parametersOf
-import java.util.*
-
-class AlbumDetailsFragment : AbsMusicServiceFragment(R.layout.fragment_album_details) {
- private lateinit var simpleSongAdapter: SimpleSongAdapter
- private lateinit var album: Album
- private val savedSortOrder: String
- get() = PreferenceUtil.albumDetailSongSortOrder
- private val detailsViewModel by viewModel {
- parametersOf(extraNotNull(AlbumDetailsActivity.EXTRA_ALBUM_ID).value)
- }
-
- private fun setSharedElementTransitionOnEnter() {
- sharedElementEnterTransition = TransitionInflater.from(context)
- .inflateTransition(R.transition.change_bounds)
- }
-
- override fun onActivityCreated(savedInstanceState: Bundle?) {
- super.onActivityCreated(savedInstanceState)
- setSharedElementTransitionOnEnter()
- postponeEnterTransition()
- playerActivity?.addMusicServiceEventListener(detailsViewModel)
-
- detailsViewModel.getAlbum().observe(viewLifecycleOwner, androidx.lifecycle.Observer {
- startPostponedEnterTransition()
- showAlbum(it)
- })
- detailsViewModel.getArtist().observe(viewLifecycleOwner, androidx.lifecycle.Observer {
- loadArtistImage(it)
- })
- detailsViewModel.getMoreAlbums().observe(viewLifecycleOwner, androidx.lifecycle.Observer {
- moreAlbums(it)
- })
- detailsViewModel.getAlbumInfo().observe(viewLifecycleOwner, androidx.lifecycle.Observer {
- aboutAlbum(it)
- })
- setupRecyclerView()
- artistImage.setOnClickListener {
- val artistPairs = ActivityOptions.makeSceneTransitionAnimation(
- requireActivity(),
- Pair.create(
- artistImage,
- getString(R.string.transition_artist_image)
- )
- )
- NavigationUtil.goToArtistOptions(requireActivity(), album.artistId, artistPairs)
- }
- playAction.setOnClickListener { MusicPlayerRemote.openQueue(album.songs!!, 0, true) }
-
- shuffleAction.setOnClickListener {
- MusicPlayerRemote.openAndShuffleQueue(
- album.songs!!,
- true
- )
- }
-
- aboutAlbumText.setOnClickListener {
- if (aboutAlbumText.maxLines == 4) {
- aboutAlbumText.maxLines = Integer.MAX_VALUE
- } else {
- aboutAlbumText.maxLines = 4
- }
- }
- image.apply {
- transitionName = getString(R.string.transition_album_art)
- }
- }
-
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- val activity = activity as AppCompatActivity
- activity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
- }
-
- override fun onDestroy() {
- super.onDestroy()
- playerActivity?.removeMusicServiceEventListener(detailsViewModel)
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- when (item.itemId) {
- android.R.id.home -> findNavController().navigateUp()
- }
- return super.onOptionsItemSelected(item)
- }
-
- private fun setupRecyclerView() {
- simpleSongAdapter = SimpleSongAdapter(
- requireActivity() as AppCompatActivity,
- ArrayList(),
- R.layout.item_song,
- null
- )
- recyclerView.apply {
- layoutManager = LinearLayoutManager(requireContext())
- itemAnimator = DefaultItemAnimator()
- isNestedScrollingEnabled = false
- adapter = simpleSongAdapter
- }
- }
-
- private fun showAlbum(album: Album) {
- if (album.songs!!.isEmpty()) {
- return
- }
- this.album = album
-
- albumTitle.text = album.title
- val songText =
- resources.getQuantityString(
- R.plurals.albumSongs,
- album.songCount,
- album.songCount
- )
- songTitle.text = songText
-
- if (MusicUtil.getYearString(album.year) == "-") {
- albumText.text = String.format(
- "%s • %s",
- album.artistName,
- MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(album.songs))
- )
- } else {
- albumText.text = String.format(
- "%s • %s • %s",
- album.artistName,
- MusicUtil.getYearString(album.year),
- MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(album.songs))
- )
- }
- loadAlbumCover()
- simpleSongAdapter.swapDataSet(album.songs)
- detailsViewModel.loadArtist(album.artistId)
- detailsViewModel.loadAlbumInfo(album)
- }
-
- private fun moreAlbums(albums: List) {
- moreTitle.show()
- moreRecyclerView.show()
- moreTitle.text = String.format(getString(R.string.label_more_from), album.artistName)
-
- val albumAdapter =
- HorizontalAlbumAdapter(requireActivity() as AppCompatActivity, albums, null)
- moreRecyclerView.layoutManager = GridLayoutManager(
- requireContext(),
- 1,
- GridLayoutManager.HORIZONTAL,
- false
- )
- moreRecyclerView.adapter = albumAdapter
- }
-
- private fun aboutAlbum(lastFmAlbum: LastFmAlbum) {
- if (lastFmAlbum.album != null) {
- if (lastFmAlbum.album.wiki != null) {
- aboutAlbumText.show()
- aboutAlbumTitle.show()
- aboutAlbumTitle.text =
- String.format(getString(R.string.about_album_label), lastFmAlbum.album.name)
- aboutAlbumText.text = lastFmAlbum.album.wiki.content
- }
- if (lastFmAlbum.album.listeners.isNotEmpty()) {
- listeners.show()
- listenersLabel.show()
- scrobbles.show()
- scrobblesLabel.show()
-
- listeners.text = RetroUtil.formatValue(lastFmAlbum.album.listeners.toFloat())
- scrobbles.text = RetroUtil.formatValue(lastFmAlbum.album.playcount.toFloat())
- }
- }
- }
-
- private fun loadArtistImage(artist: Artist) {
- ArtistGlideRequest.Builder.from(Glide.with(requireContext()), artist)
- .generatePalette(requireContext())
- .build()
- .dontAnimate()
- .dontTransform()
- .into(object : RetroMusicColoredTarget(artistImage) {
- override fun onColorReady(colors: MediaNotificationProcessor) {
- }
- })
- }
-
- private fun loadAlbumCover() {
- AlbumGlideRequest.Builder.from(Glide.with(requireContext()), album.safeGetFirstSong())
- .checkIgnoreMediaStore(requireContext())
- .ignoreMediaStore(PreferenceUtil.isIgnoreMediaStoreArtwork)
- .generatePalette(requireContext())
- .build()
- .dontAnimate()
- .dontTransform()
- .into(object : RetroMusicColoredTarget(image) {
- override fun onColorReady(colors: MediaNotificationProcessor) {
- setColors(colors)
- }
- })
- }
-
- private fun setColors(color: MediaNotificationProcessor) {
- MaterialUtil.tintColor(
- button = shuffleAction,
- textColor = color.primaryTextColor,
- backgroundColor = color.backgroundColor
- )
- MaterialUtil.tintColor(
- button = playAction,
- textColor = color.primaryTextColor,
- backgroundColor = color.backgroundColor
- )
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/base/AbsSlidingMusicPanelActivity.kt b/app/src/main/java/io/github/muntashirakon/music/activities/base/AbsSlidingMusicPanelActivity.kt
index fdcd683e1..e05776f72 100644
--- a/app/src/main/java/io/github/muntashirakon/music/activities/base/AbsSlidingMusicPanelActivity.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/activities/base/AbsSlidingMusicPanelActivity.kt
@@ -7,27 +7,29 @@ import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.widget.FrameLayout
import androidx.annotation.LayoutRes
+import androidx.core.view.ViewCompat
+import androidx.core.view.isVisible
import androidx.lifecycle.Observer
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil
+import com.google.android.material.bottomsheet.BottomSheetBehavior
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.RetroBottomSheetBehavior
import io.github.muntashirakon.music.extensions.hide
import io.github.muntashirakon.music.extensions.show
+import io.github.muntashirakon.music.extensions.whichFragment
import io.github.muntashirakon.music.fragments.LibraryViewModel
import io.github.muntashirakon.music.fragments.MiniPlayerFragment
import io.github.muntashirakon.music.fragments.NowPlayingScreen
import io.github.muntashirakon.music.fragments.NowPlayingScreen.*
import io.github.muntashirakon.music.helper.MusicPlayerRemote
import io.github.muntashirakon.music.model.CategoryInfo
-import io.github.muntashirakon.music.util.DensityUtil
import io.github.muntashirakon.music.util.PreferenceUtil
import io.github.muntashirakon.music.views.BottomNavigationBarTinted
-import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.android.synthetic.main.sliding_music_panel_layout.*
import org.koin.androidx.viewmodel.ext.android.viewModel
-abstract class AbsSlidingMusicPanelActivity() : AbsMusicServiceActivity() {
+abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
companion object {
val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName
}
@@ -120,8 +122,9 @@ abstract class AbsSlidingMusicPanelActivity() : AbsMusicServiceActivity() {
return slidingMusicPanelLayout
}
- private fun collapsePanel() {
+ fun collapsePanel() {
behavior.state = BottomSheetBehavior.STATE_COLLAPSED
+ setMiniPlayerAlphaProgress(0f)
}
fun expandPanel() {
@@ -133,9 +136,7 @@ abstract class AbsSlidingMusicPanelActivity() : AbsMusicServiceActivity() {
if (miniPlayerFragment?.view == null) return
val alpha = 1 - progress
miniPlayerFragment?.view?.alpha = alpha
- // necessary to make the views below clickable
miniPlayerFragment?.view?.visibility = if (alpha == 0f) View.GONE else View.VISIBLE
-
bottomNavigationView.translationY = progress * 500
bottomNavigationView.alpha = alpha
}
@@ -172,40 +173,31 @@ abstract class AbsSlidingMusicPanelActivity() : AbsMusicServiceActivity() {
return bottomNavigationView
}
- fun setBottomBarVisibility(visible: Int) {
- bottomNavigationView.visibility = visible
+ fun hideBottomBarVisibility(visible: Boolean) {
+ bottomNavigationView.isVisible = visible
hideBottomBar(MusicPlayerRemote.playingQueue.isEmpty())
}
private fun hideBottomBar(hide: Boolean) {
- val heightOfBar = resources.getDimensionPixelSize(R.dimen.mini_player_height)
- val heightOfBarWithTabs =
- resources.getDimensionPixelSize(R.dimen.mini_player_height_expanded)
+ val heightOfBar = bottomNavigationView.height
+ val isBottomBarVisible = bottomNavigationView.isVisible
if (hide) {
behavior.isHideable = true
behavior.peekHeight = 0
- bottomNavigationView.elevation = DensityUtil.dip2px(this, 10f).toFloat()
collapsePanel()
+ ViewCompat.setElevation(bottomNavigationView, 10f)
} else {
- if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
- slidingPanel.elevation = DensityUtil.dip2px(this, 10f).toFloat()
- bottomNavigationView.elevation = DensityUtil.dip2px(this, 10f).toFloat()
- behavior.isHideable = false
- behavior.peekHeight =
- if (bottomNavigationView.visibility == View.VISIBLE) {
- heightOfBarWithTabs
- } else {
- heightOfBar
- }
- }
+ 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 =
- supportFragmentManager.findFragmentById(R.id.miniPlayerFragment) as MiniPlayerFragment
+ miniPlayerFragment = whichFragment(R.id.miniPlayerFragment)
miniPlayerFragment?.view?.setOnClickListener { expandPanel() }
}
@@ -232,7 +224,6 @@ abstract class AbsSlidingMusicPanelActivity() : AbsMusicServiceActivity() {
}
open fun handleBackPress(): Boolean {
-
if (panelState == BottomSheetBehavior.STATE_EXPANDED) {
collapsePanel()
return true
@@ -305,6 +296,12 @@ abstract class AbsSlidingMusicPanelActivity() : AbsMusicServiceActivity() {
}
}
+ fun hideBottomNavigation() {
+ behavior.isHideable = true
+ behavior.peekHeight = 0
+ hideBottomBarVisibility(false)
+ }
+
fun updateTabs() {
bottomNavigationView.menu.clear()
val currentTabs: List = PreferenceUtil.libraryCategory
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/genre/GenreDetailsActivity.kt b/app/src/main/java/io/github/muntashirakon/music/activities/genre/GenreDetailsActivity.kt
deleted file mode 100644
index 1464d4b2a..000000000
--- a/app/src/main/java/io/github/muntashirakon/music/activities/genre/GenreDetailsActivity.kt
+++ /dev/null
@@ -1,143 +0,0 @@
-package io.github.muntashirakon.music.activities.genre
-
-import android.os.Bundle
-import android.view.Menu
-import android.view.MenuItem
-import android.view.View
-import androidx.recyclerview.widget.DefaultItemAnimator
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import code.name.monkey.appthemehelper.util.ATHUtil
-import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.activities.base.AbsSlidingMusicPanelActivity
-import io.github.muntashirakon.music.adapter.song.ShuffleButtonSongAdapter
-import io.github.muntashirakon.music.extensions.applyToolbar
-import io.github.muntashirakon.music.extensions.extraNotNull
-import io.github.muntashirakon.music.helper.menu.GenreMenuHelper
-import io.github.muntashirakon.music.interfaces.CabHolder
-import io.github.muntashirakon.music.model.Genre
-import io.github.muntashirakon.music.model.Song
-import io.github.muntashirakon.music.util.DensityUtil
-import io.github.muntashirakon.music.util.RetroColorUtil
-import com.afollestad.materialcab.MaterialCab
-import kotlinx.android.synthetic.main.activity_playlist_detail.*
-import org.koin.androidx.viewmodel.ext.android.viewModel
-import org.koin.core.parameter.parametersOf
-import java.util.*
-
-/**
- * @author Hemanth S (h4h13).
- */
-
-class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder {
-
-
- private val detailsViewModel: GenreDetailsViewModel by viewModel {
- parametersOf(extraNotNull(EXTRA_GENRE_ID).value)
- }
-
- private lateinit var genre: Genre
- private lateinit var songAdapter: ShuffleButtonSongAdapter
- private var cab: MaterialCab? = null
-
- private fun getEmojiByUnicode(unicode: Int): String {
- return String(Character.toChars(unicode))
- }
-
- private fun checkIsEmpty() {
- checkForPadding()
- emptyEmoji.text = getEmojiByUnicode(0x1F631)
- empty?.visibility = if (songAdapter.itemCount == 0) View.VISIBLE else View.GONE
- }
-
- private fun checkForPadding() {
- val height = DensityUtil.dip2px(this, 52f)
- recyclerView.setPadding(0, 0, 0, (height))
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
- setDrawUnderStatusBar()
- super.onCreate(savedInstanceState)
- setStatusbarColorAuto()
- setNavigationbarColorAuto()
- setTaskDescriptionColorAuto()
- setLightNavigationBar(true)
- setBottomBarVisibility(View.GONE)
- applyToolbar(toolbar)
- setupRecyclerView()
-
- detailsViewModel.getSongs().observe(this, androidx.lifecycle.Observer {
- songs(it)
- })
-
- detailsViewModel.getGenre().observe(this, androidx.lifecycle.Observer {
- genre = it
- supportActionBar?.title = it.name
- })
-
- addMusicServiceEventListener(detailsViewModel)
- }
-
- override fun createContentView(): View {
- return wrapSlidingMusicPanel(R.layout.activity_playlist_detail)
- }
-
-
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
- menuInflater.inflate(R.menu.menu_genre_detail, menu)
- return super.onCreateOptionsMenu(menu)
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- if (item.itemId == android.R.id.home) {
- onBackPressed()
- }
- return GenreMenuHelper.handleMenuClick(this, genre, item)
- }
-
- private fun setupRecyclerView() {
- songAdapter = ShuffleButtonSongAdapter(this, ArrayList(), R.layout.item_list, this)
- recyclerView.apply {
- itemAnimator = DefaultItemAnimator()
- layoutManager = LinearLayoutManager(this@GenreDetailsActivity)
- adapter = songAdapter
- }
- songAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
- override fun onChanged() {
- super.onChanged()
- checkIsEmpty()
- }
- })
- }
-
- fun songs(songs: List) {
- songAdapter.swapDataSet(songs)
- }
-
- override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
- if (cab != null && cab!!.isActive) cab?.finish()
- cab = MaterialCab(this, R.id.cab_stub).setMenu(menuRes)
- .setCloseDrawableRes(R.drawable.ic_close)
- .setBackgroundColor(
- RetroColorUtil.shiftBackgroundColorForLightText(
- ATHUtil.resolveColor(
- this,
- R.attr.colorSurface
- )
- )
- ).start(callback)
- return cab!!
- }
-
- override fun onBackPressed() {
- if (cab != null && cab!!.isActive) cab!!.finish()
- else {
- recyclerView!!.stopScroll()
- super.onBackPressed()
- }
- }
-
- companion object {
- const val EXTRA_GENRE_ID = "extra_genre_id"
- }
-}
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/search/SearchActivity.kt b/app/src/main/java/io/github/muntashirakon/music/activities/search/SearchActivity.kt
deleted file mode 100644
index 8eebd95eb..000000000
--- a/app/src/main/java/io/github/muntashirakon/music/activities/search/SearchActivity.kt
+++ /dev/null
@@ -1,224 +0,0 @@
-package io.github.muntashirakon.music.activities.search
-
-import android.app.Activity
-import android.app.Service
-import android.content.ActivityNotFoundException
-import android.content.Intent
-import android.content.res.ColorStateList
-import android.os.Bundle
-import android.speech.RecognizerIntent
-import android.text.Editable
-import android.text.TextWatcher
-import android.view.View
-import android.view.inputmethod.InputMethodManager
-import android.widget.TextView.BufferType
-import android.widget.Toast
-import androidx.appcompat.widget.SearchView.OnQueryTextListener
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import androidx.transition.TransitionManager
-import code.name.monkey.appthemehelper.ThemeStore
-import code.name.monkey.appthemehelper.util.ATHUtil
-import code.name.monkey.appthemehelper.util.ColorUtil
-import code.name.monkey.appthemehelper.util.MaterialValueHelper
-import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.activities.base.AbsMusicServiceActivity
-import io.github.muntashirakon.music.adapter.SearchAdapter
-import io.github.muntashirakon.music.extensions.extra
-import io.github.muntashirakon.music.util.RetroUtil
-import com.google.android.material.textfield.TextInputEditText
-import kotlinx.android.synthetic.main.activity_search.*
-import org.koin.android.ext.android.inject
-import java.util.*
-import kotlin.collections.ArrayList
-
-class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatcher {
-
- private val viewModel: SearchViewModel by inject()
- private var searchAdapter: SearchAdapter? = null
- private var query: String? = null
-
- override fun onCreate(savedInstanceState: Bundle?) {
- setDrawUnderStatusBar()
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_search)
- setStatusbarColorAuto()
- setNavigationbarColorAuto()
- setTaskDescriptionColorAuto()
- setLightNavigationBar(true)
-
- setupRecyclerView()
- setUpToolBar()
- setupSearchView()
-
- if (extra(EXTRA_SHOW_MIC).value == true) {
- startMicSearch()
- }
-
- back.setOnClickListener { onBackPressed() }
- voiceSearch.setOnClickListener { startMicSearch() }
- clearText.setOnClickListener { searchView.clearText() }
- searchContainer.backgroundTintList =
- ColorStateList.valueOf(ATHUtil.resolveColor(this, R.attr.colorSurface))
-
- keyboardPopup.setOnClickListener {
- val inputManager = getSystemService(Service.INPUT_METHOD_SERVICE) as InputMethodManager
- inputManager.showSoftInput(searchView, InputMethodManager.SHOW_IMPLICIT)
- }
-
- keyboardPopup.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
- ColorStateList.valueOf(
- MaterialValueHelper.getPrimaryTextColor(
- this,
- ColorUtil.isColorLight(ThemeStore.accentColor(this))
- )
- ).apply {
- keyboardPopup.setTextColor(this)
- keyboardPopup.iconTint = this
- }
- if (savedInstanceState != null) {
- query = savedInstanceState.getString(QUERY)
- }
-
- viewModel.getSearchResult().observe(this, androidx.lifecycle.Observer {
- showData(it)
- })
- }
-
- private fun setupRecyclerView() {
- searchAdapter = SearchAdapter(this, emptyList())
- searchAdapter?.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
- override fun onChanged() {
- super.onChanged()
- empty.visibility = if (searchAdapter!!.itemCount < 1) View.VISIBLE else View.GONE
- }
- })
- recyclerView.apply {
- layoutManager = LinearLayoutManager(this@SearchActivity)
- adapter = searchAdapter
- }
- recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
- override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
- super.onScrolled(recyclerView, dx, dy)
- if (dy > 0) {
- keyboardPopup.shrink()
- } else if (dy < 0) {
- keyboardPopup.extend()
- }
- }
- })
- }
-
- private fun setupSearchView() {
- searchView.addTextChangedListener(this)
- }
-
- override fun onSaveInstanceState(outState: Bundle) {
- super.onSaveInstanceState(outState)
- outState.putString(QUERY, query)
- }
-
- private fun setUpToolBar() {
- title = null
- }
-
- private fun search(query: String) {
- this.query = query
- TransitionManager.beginDelayedTransition(appBarLayout)
- voiceSearch.visibility = if (query.isNotEmpty()) View.GONE else View.VISIBLE
- clearText.visibility = if (query.isNotEmpty()) View.VISIBLE else View.GONE
- viewModel.search(query)
- }
-
- override fun onMediaStoreChanged() {
- super.onMediaStoreChanged()
- query?.let { search(it) }
- }
-
- override fun onQueryTextSubmit(query: String): Boolean {
- hideSoftKeyboard()
- return false
- }
-
- override fun onQueryTextChange(newText: String): Boolean {
- search(newText)
- return false
- }
-
- private fun hideSoftKeyboard() {
- RetroUtil.hideSoftKeyboard(this@SearchActivity)
- if (searchView != null) {
- searchView.clearFocus()
- }
- }
-
- private fun showEmptyView() {
- searchAdapter?.swapDataSet(ArrayList())
- }
-
- private fun showData(data: MutableList) {
- if (data.isNotEmpty()) {
- searchAdapter?.swapDataSet(data)
- } else {
- showEmptyView()
- }
- }
-
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- super.onActivityResult(requestCode, resultCode, data)
- when (requestCode) {
- REQ_CODE_SPEECH_INPUT -> {
- if (resultCode == Activity.RESULT_OK && null != data) {
- val result: ArrayList? =
- data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)
- query = result?.get(0)
- searchView.setText(query, BufferType.EDITABLE)
- viewModel.search(query!!)
- }
- }
- }
- }
-
- private fun startMicSearch() {
- val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
- intent.putExtra(
- RecognizerIntent.EXTRA_LANGUAGE_MODEL,
- RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
- )
- intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault())
- intent.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.speech_prompt))
- try {
- startActivityForResult(
- intent,
- REQ_CODE_SPEECH_INPUT
- )
- } catch (e: ActivityNotFoundException) {
- e.printStackTrace()
- Toast.makeText(this, getString(R.string.speech_not_supported), Toast.LENGTH_SHORT)
- .show()
- }
- }
-
- override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
- }
-
- override fun onTextChanged(newText: CharSequence, start: Int, before: Int, count: Int) {
- search(newText.toString())
- }
-
- override fun afterTextChanged(s: Editable) {
- }
-
- companion object {
- val TAG: String = SearchActivity::class.java.simpleName
-
- const val EXTRA_SHOW_MIC = "extra_show_mic"
- const val QUERY: String = "query"
-
- private const val REQ_CODE_SPEECH_INPUT = 9002
- }
-}
-
-fun TextInputEditText.clearText() {
- text = null
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/AbsTagEditorActivity.kt b/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/AbsTagEditorActivity.kt
index 19990376c..67f300d90 100755
--- a/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/AbsTagEditorActivity.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/AbsTagEditorActivity.kt
@@ -14,35 +14,38 @@ import android.view.MenuItem
import android.view.View
import android.view.animation.OvershootInterpolator
import androidx.appcompat.app.AlertDialog
+import androidx.lifecycle.lifecycleScope
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.TintHelper
+import com.google.android.material.button.MaterialButton
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.R.drawable
import io.github.muntashirakon.music.activities.base.AbsBaseActivity
import io.github.muntashirakon.music.activities.saf.SAFGuideActivity
+import io.github.muntashirakon.music.repository.Repository
import io.github.muntashirakon.music.util.RetroUtil
import io.github.muntashirakon.music.util.SAFUtil
-import com.google.android.material.button.MaterialButton
-import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.android.synthetic.main.activity_album_tag_editor.*
import org.jaudiotagger.audio.AudioFile
import org.jaudiotagger.audio.AudioFileIO
import org.jaudiotagger.tag.FieldKey
+import org.koin.android.ext.android.inject
import java.io.File
import java.util.*
abstract class AbsTagEditorActivity : AbsBaseActivity() {
+ val repository by inject()
+ lateinit var saveFab: MaterialButton
protected var id: Int = 0
private set
private var paletteColorPrimary: Int = 0
private var isInNoImageMode: Boolean = false
private var songPaths: List? = null
- lateinit var saveFab: MaterialButton
-
private var savedSongPaths: List? = null
private val currentSongPath: String? = null
private var savedTags: Map? = null
@@ -172,41 +175,35 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(contentViewLayout)
+ setStatusbarColorAuto()
+ setNavigationbarColorAuto()
+ setTaskDescriptionColorAuto()
saveFab = findViewById(R.id.saveTags)
getIntentExtras()
- songPaths = getSongPaths()
- if (songPaths!!.isEmpty()) {
- finish()
- return
+ lifecycleScope.launchWhenCreated {
+ songPaths = getSongPaths()
+ if (songPaths!!.isEmpty()) {
+ finish()
+ }
}
-
setUpViews()
-
- setStatusbarColorAuto()
- setNavigationbarColorAuto()
- setTaskDescriptionColorAuto()
}
private fun setUpViews() {
- setUpScrollView()
setUpFab()
setUpImageView()
}
- private fun setUpScrollView() {
- //observableScrollView.setScrollViewCallbacks(observableScrollViewCallbacks);
- }
-
private lateinit var items: List
private fun setUpImageView() {
loadCurrentImage()
items = listOf(
- getString(R.string.pick_from_local_storage),
- getString(R.string.web_search),
- getString(R.string.remove_cover)
+ getString(io.github.muntashirakon.music.R.string.pick_from_local_storage),
+ getString(io.github.muntashirakon.music.R.string.web_search),
+ getString(io.github.muntashirakon.music.R.string.remove_cover)
)
editorImage?.setOnClickListener { show }
}
@@ -217,7 +214,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
startActivityForResult(
Intent.createChooser(
intent,
- getString(R.string.pick_from_local_storage)
+ getString(io.github.muntashirakon.music.R.string.pick_from_local_storage)
), REQUEST_CODE_SELECT_IMAGE
)
}
@@ -261,7 +258,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
}
}
- protected abstract fun getSongPaths(): List
+ protected abstract suspend fun getSongPaths(): List
protected fun searchWebFor(vararg keys: String) {
val stringBuilder = StringBuilder()
@@ -336,7 +333,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
hideFab()
- savedSongPaths = getSongPaths()
+ savedSongPaths = songPaths
savedTags = fieldKeyValueMap
savedArtworkInfo = artworkInfo
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/AlbumTagEditorActivity.kt b/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/AlbumTagEditorActivity.kt
index af45b7f60..9f01b7063 100755
--- a/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/AlbumTagEditorActivity.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/AlbumTagEditorActivity.kt
@@ -14,23 +14,23 @@ import android.transition.Slide
import android.widget.Toast
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.MaterialUtil
-import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.extensions.appHandleColor
-import io.github.muntashirakon.music.glide.palette.BitmapPaletteTranscoder
-import io.github.muntashirakon.music.glide.palette.BitmapPaletteWrapper
-import io.github.muntashirakon.music.loaders.AlbumLoader
-import io.github.muntashirakon.music.util.ImageUtil
-import io.github.muntashirakon.music.util.RetroColorUtil.generatePalette
-import io.github.muntashirakon.music.util.RetroColorUtil.getColor
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
+import io.github.muntashirakon.music.R
+import io.github.muntashirakon.music.extensions.appHandleColor
+import io.github.muntashirakon.music.glide.palette.BitmapPaletteTranscoder
+import io.github.muntashirakon.music.glide.palette.BitmapPaletteWrapper
+import io.github.muntashirakon.music.util.ImageUtil
+import io.github.muntashirakon.music.util.RetroColorUtil.generatePalette
+import io.github.muntashirakon.music.util.RetroColorUtil.getColor
import kotlinx.android.synthetic.main.activity_album_tag_editor.*
import org.jaudiotagger.tag.FieldKey
import java.util.*
class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
+
override val contentViewLayout: Int
get() = R.layout.activity_album_tag_editor
@@ -162,13 +162,13 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
writeValuesToFiles(
fieldKeyValueMap,
- if (deleteAlbumArt) AbsTagEditorActivity.ArtworkInfo(id, null)
+ if (deleteAlbumArt) ArtworkInfo(id, null)
else if (albumArtBitmap == null) null else ArtworkInfo(id, albumArtBitmap!!)
)
}
- override fun getSongPaths(): List {
- val songs = AlbumLoader.getAlbum(this, id).songs
+ override suspend fun getSongPaths(): List {
+ val songs = repository.albumById(id).songs
val paths = ArrayList(songs!!.size)
for (song in songs) {
paths.add(song.data)
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/SongTagEditorActivity.kt b/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/SongTagEditorActivity.kt
index 0dd9b2cf3..30ae4ce48 100755
--- a/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/SongTagEditorActivity.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/SongTagEditorActivity.kt
@@ -8,9 +8,10 @@ import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.MaterialUtil
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.extensions.appHandleColor
-import io.github.muntashirakon.music.loaders.SongLoader
+import io.github.muntashirakon.music.repository.SongRepository
import kotlinx.android.synthetic.main.activity_song_tag_editor.*
import org.jaudiotagger.tag.FieldKey
+import org.koin.android.ext.android.inject
import java.util.*
class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
@@ -18,6 +19,8 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
override val contentViewLayout: Int
get() = R.layout.activity_song_tag_editor
+ private val songRepository by inject()
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -85,9 +88,9 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
writeValuesToFiles(fieldKeyValueMap, null)
}
- override fun getSongPaths(): List {
+ override suspend fun getSongPaths(): List {
val paths = ArrayList(1)
- paths.add(SongLoader.getSong(this, id).data)
+ paths.add(songRepository.song(id).data)
return paths
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/WriteTagsAsyncTask.java b/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/WriteTagsAsyncTask.java
index 25cb35cf6..07aaf76b8 100644
--- a/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/WriteTagsAsyncTask.java
+++ b/app/src/main/java/io/github/muntashirakon/music/activities/tageditor/WriteTagsAsyncTask.java
@@ -63,7 +63,7 @@ public class WriteTagsAsyncTask extends DialogAsyncTask,
private val mItemLayoutRes: Int
) : RecyclerView.Adapter() {
@@ -48,9 +50,10 @@ class GenreAdapter(
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
override fun onClick(v: View?) {
- super.onClick(v)
- val genre = dataSet[layoutPosition]
- NavigationUtil.goToGenre(activity, genre)
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.genreDetailsFragment,
+ bundleOf(EXTRA_GENRE to dataSet[layoutPosition])
+ )
}
}
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/adapter/HomeAdapter.kt b/app/src/main/java/io/github/muntashirakon/music/adapter/HomeAdapter.kt
index f943e20c2..ac163e1a7 100644
--- a/app/src/main/java/io/github/muntashirakon/music/adapter/HomeAdapter.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/adapter/HomeAdapter.kt
@@ -1,38 +1,37 @@
package io.github.muntashirakon.music.adapter
-import android.util.DisplayMetrics
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.widget.ImageView
import android.widget.TextView
-import androidx.annotation.IntDef
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatTextView
+import androidx.core.os.bundleOf
+import androidx.navigation.findNavController
+import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
-import androidx.recyclerview.widget.RecyclerView.HORIZONTAL
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil
-import io.github.muntashirakon.music.PeekingLinearLayoutManager
-import io.github.muntashirakon.music.R
+import com.bumptech.glide.Glide
+import com.google.android.material.card.MaterialCardView
+import io.github.muntashirakon.music.*
import io.github.muntashirakon.music.adapter.album.AlbumAdapter
import io.github.muntashirakon.music.adapter.artist.ArtistAdapter
import io.github.muntashirakon.music.adapter.song.SongAdapter
-import io.github.muntashirakon.music.extensions.show
+import io.github.muntashirakon.music.extensions.hide
+import io.github.muntashirakon.music.fragments.albums.AlbumClickListener
+import io.github.muntashirakon.music.fragments.artists.ArtistClickListener
import io.github.muntashirakon.music.glide.SongGlideRequest
import io.github.muntashirakon.music.helper.MusicPlayerRemote
-import io.github.muntashirakon.music.loaders.PlaylistSongsLoader
import io.github.muntashirakon.music.model.*
-import io.github.muntashirakon.music.model.Playlist
import io.github.muntashirakon.music.util.PreferenceUtil
-import com.bumptech.glide.Glide
-import com.google.android.material.card.MaterialCardView
class HomeAdapter(
- private val activity: AppCompatActivity,
- private val displayMetrics: DisplayMetrics
-) : RecyclerView.Adapter() {
+ private val activity: AppCompatActivity
+) : RecyclerView.Adapter(), ArtistClickListener, AlbumClickListener {
private var list = listOf()
@@ -45,14 +44,9 @@ class HomeAdapter(
.inflate(R.layout.section_recycler_view, parent, false)
return when (viewType) {
RECENT_ARTISTS, TOP_ARTISTS -> ArtistViewHolder(layout)
- TOP_ALBUMS, RECENT_ALBUMS -> {
- AlbumViewHolder(
- LayoutInflater.from(activity)
- .inflate(R.layout.metal_section_recycler_view, parent, false)
- )
- }
GENRES -> GenreViewHolder(layout)
FAVOURITES -> PlaylistViewHolder(layout)
+ TOP_ALBUMS, RECENT_ALBUMS -> AlbumViewHolder(layout)
else -> {
SuggestionsViewHolder(
LayoutInflater.from(activity).inflate(
@@ -66,48 +60,62 @@ class HomeAdapter(
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ val home = list[position]
when (getItemViewType(position)) {
RECENT_ALBUMS -> {
val viewHolder = holder as AlbumViewHolder
- viewHolder.bindView(
- list[position].arrayList as List,
- R.string.recent_albums
- )
+ viewHolder.bindView(home.arrayList as List, R.string.recent_albums)
+ viewHolder.clickableArea.setOnClickListener {
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.detailListFragment,
+ bundleOf("type" to RECENT_ALBUMS)
+ )
+ }
}
TOP_ALBUMS -> {
val viewHolder = holder as AlbumViewHolder
- viewHolder.bindView(
- list[position].arrayList as List,
- R.string.top_albums
- )
+ viewHolder.bindView(home.arrayList as List, R.string.top_albums)
+ viewHolder.clickableArea.setOnClickListener {
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.detailListFragment,
+ bundleOf("type" to TOP_ALBUMS)
+ )
+ }
}
RECENT_ARTISTS -> {
val viewHolder = holder as ArtistViewHolder
- viewHolder.bindView(
- list[position].arrayList as List,
- R.string.recent_artists
- )
+ viewHolder.bindView(home.arrayList, R.string.recent_artists)
+ viewHolder.clickableArea.setOnClickListener {
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.detailListFragment,
+ bundleOf("type" to RECENT_ARTISTS)
+ )
+ }
}
TOP_ARTISTS -> {
val viewHolder = holder as ArtistViewHolder
- viewHolder.bindView(list[position].arrayList as List, R.string.top_artists)
+ viewHolder.bindView(home.arrayList, R.string.top_artists)
+ viewHolder.clickableArea.setOnClickListener {
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.detailListFragment,
+ bundleOf("type" to TOP_ARTISTS)
+ )
+ }
}
SUGGESTIONS -> {
val viewHolder = holder as SuggestionsViewHolder
- viewHolder.bindView(
- list[position].arrayList as List
- )
+ viewHolder.bindView(home.arrayList)
}
FAVOURITES -> {
val viewHolder = holder as PlaylistViewHolder
- viewHolder.bindView(
- list[position].arrayList as List,
- R.string.favorites
- )
+ viewHolder.bindView(home.arrayList, R.string.favorites)
}
GENRES -> {
val viewHolder = holder as GenreViewHolder
- viewHolder.bind(list[position].arrayList as List, R.string.genres)
+ viewHolder.bind(home.arrayList, R.string.genres)
+ }
+ PLAYLISTS -> {
+
}
}
}
@@ -121,60 +129,23 @@ class HomeAdapter(
notifyDataSetChanged()
}
- companion object {
-
- @IntDef(
- RECENT_ALBUMS,
- TOP_ALBUMS,
- RECENT_ARTISTS,
- TOP_ARTISTS,
- SUGGESTIONS,
- FAVOURITES,
- GENRES
- )
- @Retention(AnnotationRetention.SOURCE)
- annotation class HomeSection
-
- const val RECENT_ALBUMS = 3
- const val TOP_ALBUMS = 1
- const val RECENT_ARTISTS = 2
- const val TOP_ARTISTS = 0
- const val SUGGESTIONS = 5
- const val FAVOURITES = 4
- const val GENRES = 6
- }
-
private inner class AlbumViewHolder(view: View) : AbsHomeViewItem(view) {
- fun bindView(list: List, titleRes: Int) {
- if (list.isNotEmpty()) {
- recyclerView.apply {
- show()
- adapter = AlbumAdapter(activity, list, R.layout.pager_item, null)
- layoutManager =
- PeekingLinearLayoutManager(activity, HORIZONTAL, false)
- }
- title.text = activity.getString(titleRes)
+ fun bindView(albums: List, titleRes: Int) {
+ title.text = activity.getString(titleRes)
+ recyclerView.apply {
+ adapter = albumAdapter(albums)
+ layoutManager = gridLayoutManager()
}
}
}
- inner class ArtistViewHolder(view: View) : AbsHomeViewItem(view) {
- fun bindView(list: List, titleRes: Int) {
- if (list.isNotEmpty()) {
- val manager = LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
- val artistAdapter = ArtistAdapter(
- activity,
- list,
- PreferenceUtil.homeGridStyle,
- null
- )
- recyclerView.apply {
- show()
- layoutManager = manager
- adapter = artistAdapter
- }
- title.text = activity.getString(titleRes)
+ private inner class ArtistViewHolder(view: View) : AbsHomeViewItem(view) {
+ fun bindView(artists: List, titleRes: Int) {
+ recyclerView.apply {
+ layoutManager = linearLayoutManager()
+ adapter = artistsAdapter(artists as List)
}
+ title.text = activity.getString(titleRes)
}
}
@@ -190,52 +161,50 @@ class HomeAdapter(
R.id.image8
)
- fun bindView(arrayList: List) {
+ fun bindView(songs: List) {
+ songs as List
val color = ThemeStore.accentColor(activity)
- itemView.findViewById(R.id.text).setTextColor(color)
+ itemView.findViewById(R.id.message).setTextColor(color)
itemView.findViewById(R.id.card6).apply {
- setCardBackgroundColor(ColorUtil.withAlpha(color, 0.2f))
+ setCardBackgroundColor(ColorUtil.withAlpha(color, 0.12f))
}
- if (arrayList.size > 9)
- images.forEachIndexed { index, i ->
- itemView.findViewById(i).setOnClickListener {
- MusicPlayerRemote.playNext(arrayList[index])
- }
- SongGlideRequest.Builder.from(Glide.with(activity), arrayList[index])
- .asBitmap()
- .build()
- .into(itemView.findViewById(i))
-
+ images.forEachIndexed { index, id ->
+ itemView.findViewById(id).setOnClickListener {
+ MusicPlayerRemote.playNext(songs[index])
}
+ SongGlideRequest.Builder.from(Glide.with(activity), songs[index])
+ .asBitmap()
+ .build()
+ .into(itemView.findViewById(id))
+
+ }
}
}
private inner class PlaylistViewHolder(view: View) : AbsHomeViewItem(view) {
- fun bindView(arrayList: List, titleRes: Int) {
- if (arrayList.isNotEmpty()) {
- val songs = PlaylistSongsLoader.getPlaylistSongList(activity, arrayList[0])
- if (songs.isNotEmpty()) {
- recyclerView.apply {
- show()
- val songAdapter =
- SongAdapter(activity, songs, R.layout.item_album_card, null)
- layoutManager =
- GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
- adapter = songAdapter
- }
- title.text = activity.getString(titleRes)
- }
+ fun bindView(songs: List, titleRes: Int) {
+ arrow.hide()
+ recyclerView.apply {
+ val songAdapter = SongAdapter(
+ activity,
+ songs as MutableList,
+ R.layout.item_album_card, null
+ )
+ layoutManager = linearLayoutManager()
+ adapter = songAdapter
}
+ title.text = activity.getString(titleRes)
}
}
private inner class GenreViewHolder(itemView: View) : AbsHomeViewItem(itemView) {
- fun bind(genres: List, titleRes: Int) {
+ fun bind(genres: List, titleRes: Int) {
+ arrow.hide()
title.text = activity.getString(titleRes)
recyclerView.apply {
- show()
- layoutManager = GridLayoutManager(activity, 2, GridLayoutManager.HORIZONTAL, false)
- val genreAdapter = GenreAdapter(activity, genres, R.layout.item_grid_genre)
+ layoutManager = GridLayoutManager(activity, 3, GridLayoutManager.HORIZONTAL, false)
+ val genreAdapter =
+ GenreAdapter(activity, genres as List, R.layout.item_grid_genre)
adapter = genreAdapter
}
}
@@ -244,5 +213,38 @@ class HomeAdapter(
open inner class AbsHomeViewItem(itemView: View) : RecyclerView.ViewHolder(itemView) {
val recyclerView: RecyclerView = itemView.findViewById(R.id.recyclerView)
val title: AppCompatTextView = itemView.findViewById(R.id.title)
+ val arrow: ImageView = itemView.findViewById(R.id.arrow)
+ val clickableArea: ViewGroup = itemView.findViewById(R.id.clickable_area)
}
-}
+
+ fun artistsAdapter(artists: List) =
+ ArtistAdapter(activity, artists, PreferenceUtil.homeGridStyle, null, this)
+
+ fun albumAdapter(albums: List) =
+ AlbumAdapter(activity, albums, R.layout.item_image, null, this)
+
+ fun gridLayoutManager() = GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
+ fun linearLayoutManager() = LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
+
+ override fun onArtist(artistId: Int, imageView: ImageView) {
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.artistDetailsFragment,
+ bundleOf(EXTRA_ARTIST_ID to artistId),
+ null,
+ FragmentNavigatorExtras(
+ imageView to activity.getString(R.string.transition_album_art)
+ )
+ )
+ }
+
+ override fun onAlbumClick(albumId: Int, view: View) {
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.albumDetailsFragment,
+ bundleOf(EXTRA_ALBUM_ID to albumId),
+ null,
+ FragmentNavigatorExtras(
+ view to activity.getString(R.string.transition_album_art)
+ )
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/adapter/SearchAdapter.kt b/app/src/main/java/io/github/muntashirakon/music/adapter/SearchAdapter.kt
index 722e94851..fcef5c254 100644
--- a/app/src/main/java/io/github/muntashirakon/music/adapter/SearchAdapter.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/adapter/SearchAdapter.kt
@@ -1,29 +1,28 @@
package io.github.muntashirakon.music.adapter
-import android.app.ActivityOptions
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.appcompat.app.AppCompatActivity
+import androidx.core.os.bundleOf
+import androidx.fragment.app.FragmentActivity
+import androidx.navigation.findNavController
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.ThemeStore
-import io.github.muntashirakon.music.R
+import com.bumptech.glide.Glide
+import io.github.muntashirakon.music.*
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
import io.github.muntashirakon.music.glide.AlbumGlideRequest
import io.github.muntashirakon.music.glide.ArtistGlideRequest
import io.github.muntashirakon.music.helper.MusicPlayerRemote
import io.github.muntashirakon.music.helper.menu.SongMenuHelper
-import io.github.muntashirakon.music.loaders.PlaylistSongsLoader
import io.github.muntashirakon.music.model.*
import io.github.muntashirakon.music.model.smartplaylist.AbsSmartPlaylist
+import io.github.muntashirakon.music.repository.PlaylistSongsLoader
import io.github.muntashirakon.music.util.MusicUtil
-import io.github.muntashirakon.music.util.NavigationUtil
-import com.bumptech.glide.Glide
-import android.util.Pair as UtilPair
class SearchAdapter(
- private val activity: AppCompatActivity,
- private var dataSet: List?
+ private val activity: FragmentActivity,
+ private var dataSet: List
) : RecyclerView.Adapter() {
fun swapDataSet(dataSet: MutableList) {
@@ -32,11 +31,11 @@ class SearchAdapter(
}
override fun getItemViewType(position: Int): Int {
- if (dataSet!![position] is Album) return ALBUM
- if (dataSet!![position] is Artist) return ARTIST
- if (dataSet!![position] is Genre) return GENRE
- if (dataSet!![position] is Playlist) return PLAYLIST
- return if (dataSet!![position] is Song) SONG else HEADER
+ if (dataSet[position] is Album) return ALBUM
+ if (dataSet[position] is Artist) return ARTIST
+ if (dataSet[position] is Genre) return GENRE
+ if (dataSet[position] is Playlist) return PLAYLIST
+ return if (dataSet[position] is Song) SONG else HEADER
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
@@ -57,35 +56,35 @@ class SearchAdapter(
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
when (getItemViewType(position)) {
ALBUM -> {
- val album = dataSet?.get(position) as Album
+ val album = dataSet.get(position) as Album
holder.title?.text = album.title
holder.text?.text = album.artistName
AlbumGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
.checkIgnoreMediaStore(activity).build().into(holder.image)
}
ARTIST -> {
- val artist = dataSet?.get(position) as Artist
+ val artist = dataSet.get(position) as Artist
holder.title?.text = artist.name
holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
ArtistGlideRequest.Builder.from(Glide.with(activity), artist).build()
.into(holder.image)
}
SONG -> {
- val song = dataSet?.get(position) as Song
+ val song = dataSet.get(position) as Song
holder.title?.text = song.title
holder.text?.text = song.albumName
}
GENRE -> {
- val genre = dataSet?.get(position) as Genre
+ val genre = dataSet.get(position) as Genre
holder.title?.text = genre.name
}
PLAYLIST -> {
- val playlist = dataSet?.get(position) as Playlist
+ val playlist = dataSet.get(position) as Playlist
holder.title?.text = playlist.name
holder.text?.text = MusicUtil.getPlaylistInfoString(activity, getSongs(playlist))
}
else -> {
- holder.title?.text = dataSet?.get(position).toString()
+ holder.title?.text = dataSet.get(position).toString()
holder.title?.setTextColor(ThemeStore.accentColor(activity))
}
}
@@ -94,7 +93,7 @@ class SearchAdapter(
private fun getSongs(playlist: Playlist): java.util.ArrayList {
val songs = java.util.ArrayList()
if (playlist is AbsSmartPlaylist) {
- songs.addAll(playlist.getSongs(activity))
+ songs.addAll(playlist.getSongs())
} else {
songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id))
}
@@ -102,7 +101,7 @@ class SearchAdapter(
}
override fun getItemCount(): Int {
- return dataSet!!.size
+ return dataSet.size
}
inner class ViewHolder(itemView: View, itemViewType: Int) : MediaEntryViewHolder(itemView) {
@@ -113,7 +112,7 @@ class SearchAdapter(
menu?.visibility = View.VISIBLE
menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
override val song: Song
- get() = dataSet!![layoutPosition] as Song
+ get() = dataSet[layoutPosition] as Song
})
} else {
menu?.visibility = View.GONE
@@ -130,27 +129,31 @@ class SearchAdapter(
}
override fun onClick(v: View?) {
- val item = dataSet!![layoutPosition]
+ val item = dataSet[layoutPosition]
when (itemViewType) {
ALBUM -> {
- val options = ActivityOptions.makeSceneTransitionAnimation(
- activity,
- UtilPair.create(image, activity.getString(R.string.transition_album_art))
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.albumDetailsFragment,
+ bundleOf(EXTRA_ALBUM_ID to (item as Album).id)
)
- NavigationUtil.goToAlbumOptions(activity, (item as Album).id, options)
}
ARTIST -> {
- val options = ActivityOptions.makeSceneTransitionAnimation(
- activity,
- UtilPair.create(image, activity.getString(R.string.transition_artist_image))
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.artistDetailsFragment,
+ bundleOf(EXTRA_ARTIST_ID to (item as Artist).id)
)
- NavigationUtil.goToArtistOptions(activity, (item as Artist).id, options)
}
GENRE -> {
- NavigationUtil.goToGenre(activity, item as Genre)
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.genreDetailsFragment,
+ bundleOf(EXTRA_GENRE to (item as Genre))
+ )
}
PLAYLIST -> {
- NavigationUtil.goToPlaylistNew(activity, item as Playlist)
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.artistDetailsFragment,
+ bundleOf(EXTRA_PLAYLIST to (item as Playlist))
+ )
}
SONG -> {
val playList = ArrayList()
diff --git a/app/src/main/java/io/github/muntashirakon/music/adapter/SongFileAdapter.kt b/app/src/main/java/io/github/muntashirakon/music/adapter/SongFileAdapter.kt
index a7fd9e87c..b6c8503c4 100644
--- a/app/src/main/java/io/github/muntashirakon/music/adapter/SongFileAdapter.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/adapter/SongFileAdapter.kt
@@ -22,20 +22,20 @@ import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.appthemehelper.util.ATHUtil
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.engine.DiskCacheStrategy
+import com.bumptech.glide.signature.MediaStoreSignature
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
import io.github.muntashirakon.music.glide.audiocover.AudioFileCover
import io.github.muntashirakon.music.interfaces.CabHolder
+import io.github.muntashirakon.music.interfaces.Callbacks
import io.github.muntashirakon.music.util.MusicUtil
import io.github.muntashirakon.music.util.RetroUtil
-import com.bumptech.glide.Glide
-import com.bumptech.glide.load.engine.DiskCacheStrategy
-import com.bumptech.glide.signature.MediaStoreSignature
import me.zhanghai.android.fastscroll.PopupTextProvider
import java.io.File
import java.text.DecimalFormat
-import java.util.*
import kotlin.math.log10
import kotlin.math.pow
@@ -135,9 +135,9 @@ class SongFileAdapter(
return getFileTitle(`object`)
}
- override fun onMultipleItemAction(menuItem: MenuItem, selection: ArrayList) {
+ override fun onMultipleItemAction(menuItem: MenuItem, selection: List) {
if (callbacks == null) return
- callbacks.onMultipleItemAction(menuItem, selection)
+ callbacks.onMultipleItemAction(menuItem, selection as ArrayList)
}
override fun getPopupText(position: Int): String {
@@ -148,13 +148,6 @@ class SongFileAdapter(
return MusicUtil.getSectionName(dataSet[position].name)
}
- interface Callbacks {
- fun onFileSelected(file: File)
-
- fun onFileMenuClicked(file: File, view: View)
-
- fun onMultipleItemAction(item: MenuItem, files: ArrayList)
- }
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
diff --git a/app/src/main/java/io/github/muntashirakon/music/adapter/album/AlbumAdapter.kt b/app/src/main/java/io/github/muntashirakon/music/adapter/album/AlbumAdapter.kt
index f1147f71a..011356c60 100644
--- a/app/src/main/java/io/github/muntashirakon/music/adapter/album/AlbumAdapter.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/adapter/album/AlbumAdapter.kt
@@ -1,16 +1,17 @@
package io.github.muntashirakon.music.adapter.album
-import android.app.ActivityOptions
import android.content.res.ColorStateList
import android.content.res.Resources
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
-import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.FragmentActivity
+import com.bumptech.glide.Glide
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
+import io.github.muntashirakon.music.fragments.albums.AlbumClickListener
import io.github.muntashirakon.music.glide.AlbumGlideRequest
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
import io.github.muntashirakon.music.helper.MusicPlayerRemote
@@ -20,17 +21,16 @@ import io.github.muntashirakon.music.interfaces.CabHolder
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.NavigationUtil
import io.github.muntashirakon.music.util.PreferenceUtil
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
-import com.bumptech.glide.Glide
import me.zhanghai.android.fastscroll.PopupTextProvider
open class AlbumAdapter(
- protected val activity: AppCompatActivity,
+ protected val activity: FragmentActivity,
var dataSet: List,
protected var itemLayoutRes: Int,
- cabHolder: CabHolder?
+ cabHolder: CabHolder?,
+ private val albumClickListener: AlbumClickListener?
) : AbsMultiSelectAdapter(
activity,
cabHolder,
@@ -129,12 +129,12 @@ open class AlbumAdapter(
}
override fun onMultipleItemAction(
- menuItem: MenuItem, selection: ArrayList
+ menuItem: MenuItem, selection: List
) {
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
}
- private fun getSongList(albums: List): ArrayList {
+ private fun getSongList(albums: List): List {
val songs = ArrayList()
for (album in albums) {
songs.addAll(album.songs!!)
@@ -156,7 +156,6 @@ open class AlbumAdapter(
dataSet[position].year
)
}
-
return MusicUtil.getSectionName(sectionName)
}
@@ -172,16 +171,7 @@ open class AlbumAdapter(
if (isInQuickSelectMode) {
toggleChecked(layoutPosition)
} else {
- val activityOptions = ActivityOptions.makeSceneTransitionAnimation(
- activity,
- imageContainerCard ?: image,
- activity.getString(R.string.transition_album_art)
- )
- NavigationUtil.goToAlbumOptions(
- activity,
- dataSet[layoutPosition].id,
- activityOptions
- )
+ image?.let { albumClickListener?.onAlbumClick(dataSet[layoutPosition].id, it) }
}
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/adapter/album/HorizontalAlbumAdapter.kt b/app/src/main/java/io/github/muntashirakon/music/adapter/album/HorizontalAlbumAdapter.kt
index 99cf66910..cb6dd36e1 100644
--- a/app/src/main/java/io/github/muntashirakon/music/adapter/album/HorizontalAlbumAdapter.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/adapter/album/HorizontalAlbumAdapter.kt
@@ -1,10 +1,11 @@
package io.github.muntashirakon.music.adapter.album
-import android.graphics.drawable.Drawable
import android.view.View
import android.view.ViewGroup
-import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.FragmentActivity
import code.name.monkey.appthemehelper.util.ATHUtil
+import com.bumptech.glide.Glide
+import io.github.muntashirakon.music.fragments.albums.AlbumClickListener
import io.github.muntashirakon.music.glide.AlbumGlideRequest
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
import io.github.muntashirakon.music.helper.HorizontalAdapterHelper
@@ -12,14 +13,14 @@ import io.github.muntashirakon.music.interfaces.CabHolder
import io.github.muntashirakon.music.model.Album
import io.github.muntashirakon.music.util.MusicUtil
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
-import com.bumptech.glide.Glide
class HorizontalAlbumAdapter(
- activity: AppCompatActivity,
+ activity: FragmentActivity,
dataSet: List,
- cabHolder: CabHolder?
+ cabHolder: CabHolder?,
+ albumClickListener: AlbumClickListener
) : AlbumAdapter(
- activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, cabHolder
+ activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, cabHolder, albumClickListener
) {
override fun createViewHolder(view: View, viewType: Int): ViewHolder {
@@ -40,11 +41,6 @@ class HorizontalAlbumAdapter(
.generatePalette(activity)
.build()
.into(object : RetroMusicColoredTarget(holder.image!!) {
- override fun onLoadCleared(placeholder: Drawable?) {
- super.onLoadCleared(placeholder)
- //setColors(albumArtistFooterColor, holder)
- }
-
override fun onColorReady(colors: MediaNotificationProcessor) {
setColors(colors, holder)
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/adapter/artist/ArtistAdapter.kt b/app/src/main/java/io/github/muntashirakon/music/adapter/artist/ArtistAdapter.kt
index 60f62d042..54fd14e16 100644
--- a/app/src/main/java/io/github/muntashirakon/music/adapter/artist/ArtistAdapter.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/adapter/artist/ArtistAdapter.kt
@@ -1,17 +1,19 @@
package io.github.muntashirakon.music.adapter.artist
-import android.app.ActivityOptions
import android.content.res.ColorStateList
import android.content.res.Resources
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
-import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ViewCompat
+import androidx.fragment.app.FragmentActivity
+import com.bumptech.glide.Glide
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
import io.github.muntashirakon.music.extensions.hide
+import io.github.muntashirakon.music.fragments.artists.ArtistClickListener
import io.github.muntashirakon.music.glide.ArtistGlideRequest
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
import io.github.muntashirakon.music.helper.menu.SongsMenuHelper
@@ -19,17 +21,16 @@ import io.github.muntashirakon.music.interfaces.CabHolder
import io.github.muntashirakon.music.model.Artist
import io.github.muntashirakon.music.model.Song
import io.github.muntashirakon.music.util.MusicUtil
-import io.github.muntashirakon.music.util.NavigationUtil
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
-import com.bumptech.glide.Glide
import me.zhanghai.android.fastscroll.PopupTextProvider
import java.util.*
class ArtistAdapter(
- val activity: AppCompatActivity,
+ val activity: FragmentActivity,
var dataSet: List,
var itemLayoutRes: Int,
- cabHolder: CabHolder?
+ cabHolder: CabHolder?,
+ private val artistClickListener: ArtistClickListener
) : AbsMultiSelectAdapter(
activity, cabHolder, R.menu.menu_media_selection
), PopupTextProvider {
@@ -106,12 +107,12 @@ class ArtistAdapter(
}
override fun onMultipleItemAction(
- menuItem: MenuItem, selection: ArrayList
+ menuItem: MenuItem, selection: List
) {
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
}
- private fun getSongList(artists: List): ArrayList {
+ private fun getSongList(artists: List): List {
val songs = ArrayList()
for (artist in artists) {
songs.addAll(artist.songs) // maybe async in future?
@@ -130,7 +131,6 @@ class ArtistAdapter(
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
init {
- setImageTransitionName(activity.getString(R.string.transition_artist_image))
menu?.visibility = View.GONE
}
@@ -139,14 +139,13 @@ class ArtistAdapter(
if (isInQuickSelectMode) {
toggleChecked(layoutPosition)
} else {
- val activityOptions = ActivityOptions.makeSceneTransitionAnimation(
- activity,
- imageContainerCard ?: image,
- activity.getString(R.string.transition_artist_image)
- )
- NavigationUtil.goToArtistOptions(
- activity, dataSet[layoutPosition].id, activityOptions
- )
+ image?.let {
+ ViewCompat.setTransitionName(
+ it,
+ activity.getString(R.string.transition_artist_image)
+ )
+ artistClickListener.onArtist(dataSet[layoutPosition].id, it)
+ }
}
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/adapter/base/AbsMultiSelectAdapter.java b/app/src/main/java/io/github/muntashirakon/music/adapter/base/AbsMultiSelectAdapter.java
index 59e48087a..1cdb9a531 100644
--- a/app/src/main/java/io/github/muntashirakon/music/adapter/base/AbsMultiSelectAdapter.java
+++ b/app/src/main/java/io/github/muntashirakon/music/adapter/base/AbsMultiSelectAdapter.java
@@ -12,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.afollestad.materialcab.MaterialCab;
import java.util.ArrayList;
+import java.util.List;
import io.github.muntashirakon.music.R;
import io.github.muntashirakon.music.interfaces.CabHolder;
@@ -24,7 +25,7 @@ public abstract class AbsMultiSelectAdapter checked;
+ private List checked;
private int menuRes;
public AbsMultiSelectAdapter(@NonNull Context context, @Nullable CabHolder cabHolder, @MenuRes int menuRes) {
@@ -86,7 +87,7 @@ public abstract class AbsMultiSelectAdapter selection);
+ protected abstract void onMultipleItemAction(MenuItem menuItem, List selection);
protected void setMultiSelectMenuRes(@MenuRes int menuRes) {
this.menuRes = menuRes;
diff --git a/app/src/main/java/io/github/muntashirakon/music/adapter/playlist/PlaylistAdapter.kt b/app/src/main/java/io/github/muntashirakon/music/adapter/playlist/PlaylistAdapter.kt
index 165351398..223cff33d 100755
--- a/app/src/main/java/io/github/muntashirakon/music/adapter/playlist/PlaylistAdapter.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/adapter/playlist/PlaylistAdapter.kt
@@ -9,11 +9,14 @@ import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
-import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.PopupMenu
+import androidx.core.os.bundleOf
+import androidx.fragment.app.FragmentActivity
+import androidx.navigation.findNavController
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.TintHelper
+import io.github.muntashirakon.music.EXTRA_PLAYLIST
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
@@ -22,19 +25,18 @@ import io.github.muntashirakon.music.extensions.show
import io.github.muntashirakon.music.helper.menu.PlaylistMenuHelper
import io.github.muntashirakon.music.helper.menu.SongsMenuHelper
import io.github.muntashirakon.music.interfaces.CabHolder
-import io.github.muntashirakon.music.loaders.PlaylistSongsLoader
import io.github.muntashirakon.music.model.AbsCustomPlaylist
import io.github.muntashirakon.music.model.Playlist
import io.github.muntashirakon.music.model.Song
import io.github.muntashirakon.music.model.smartplaylist.AbsSmartPlaylist
+import io.github.muntashirakon.music.repository.PlaylistSongsLoader
import io.github.muntashirakon.music.util.AutoGeneratedPlaylistBitmap
import io.github.muntashirakon.music.util.MusicUtil
-import io.github.muntashirakon.music.util.NavigationUtil
import io.github.muntashirakon.music.util.RetroColorUtil
import java.util.*
class PlaylistAdapter(
- private val activity: AppCompatActivity,
+ private val activity: FragmentActivity,
var dataSet: List,
private var itemLayoutRes: Int,
cabHolder: CabHolder?
@@ -120,7 +122,7 @@ class PlaylistAdapter(
return playlist.name
}
- override fun onMultipleItemAction(menuItem: MenuItem, selection: ArrayList) {
+ override fun onMultipleItemAction(menuItem: MenuItem, selection: List) {
when (menuItem.itemId) {
else -> SongsMenuHelper.handleMenuClick(
activity,
@@ -130,11 +132,11 @@ class PlaylistAdapter(
}
}
- private fun getSongList(playlists: List): ArrayList {
+ private fun getSongList(playlists: List): List {
val songs = ArrayList()
for (playlist in playlists) {
if (playlist is AbsCustomPlaylist) {
- songs.addAll(playlist.getSongs(activity))
+ songs.addAll(playlist.songs())
} else {
songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id))
}
@@ -142,12 +144,12 @@ class PlaylistAdapter(
return songs
}
- private fun getSongs(playlist: Playlist): ArrayList {
+ private fun getSongs(playlist: Playlist): List {
val songs = ArrayList()
if (playlist is AbsSmartPlaylist) {
- songs.addAll(playlist.getSongs(activity))
+ songs.addAll(playlist.songs())
} else {
- songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id))
+ songs.addAll(playlist.getSongs())
}
return songs
}
@@ -165,9 +167,7 @@ class PlaylistAdapter(
val popupMenu = PopupMenu(activity, view)
popupMenu.inflate(R.menu.menu_item_playlist)
popupMenu.setOnMenuItemClickListener { item ->
- PlaylistMenuHelper.handleMenuClick(
- activity, dataSet[layoutPosition], item
- )
+ PlaylistMenuHelper.handleMenuClick(activity, dataSet[layoutPosition], item)
}
popupMenu.show()
}
@@ -182,8 +182,10 @@ class PlaylistAdapter(
if (isInQuickSelectMode) {
toggleChecked(layoutPosition)
} else {
- val playlist = dataSet[layoutPosition]
- NavigationUtil.goToPlaylistNew(activity, playlist)
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.playlistDetailsFragment,
+ bundleOf(EXTRA_PLAYLIST to dataSet[layoutPosition])
+ )
}
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/adapter/song/OrderablePlaylistSongAdapter.kt b/app/src/main/java/io/github/muntashirakon/music/adapter/song/OrderablePlaylistSongAdapter.kt
index 030daf3b8..0bc4efe30 100644
--- a/app/src/main/java/io/github/muntashirakon/music/adapter/song/OrderablePlaylistSongAdapter.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/adapter/song/OrderablePlaylistSongAdapter.kt
@@ -2,7 +2,11 @@ package io.github.muntashirakon.music.adapter.song
import android.view.MenuItem
import android.view.View
-import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.FragmentActivity
+import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter
+import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemViewHolder
+import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange
+import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.R.menu
import io.github.muntashirakon.music.dialogs.RemoveFromPlaylistDialog
@@ -10,19 +14,18 @@ import io.github.muntashirakon.music.interfaces.CabHolder
import io.github.muntashirakon.music.model.PlaylistSong
import io.github.muntashirakon.music.model.Song
import io.github.muntashirakon.music.util.ViewUtil
-import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter
-import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemViewHolder
-import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange
-import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags
class OrderablePlaylistSongAdapter(
- activity: AppCompatActivity,
+ activity: FragmentActivity,
dataSet: ArrayList,
itemLayoutRes: Int,
cabHolder: CabHolder?,
private val onMoveItemListener: OnMoveItemListener?
-) : PlaylistSongAdapter(
- activity, dataSet, itemLayoutRes, cabHolder
+) : SongAdapter(
+ activity,
+ dataSet,
+ itemLayoutRes,
+ cabHolder
), DraggableItemAdapter {
init {
@@ -48,7 +51,7 @@ class OrderablePlaylistSongAdapter(
return long
}
- override fun onMultipleItemAction(menuItem: MenuItem, selection: ArrayList) {
+ override fun onMultipleItemAction(menuItem: MenuItem, selection: List) {
when (menuItem.itemId) {
R.id.action_remove_from_playlist -> {
RemoveFromPlaylistDialog.create(selection as ArrayList)
@@ -91,7 +94,7 @@ class OrderablePlaylistSongAdapter(
fun onMoveItem(fromPosition: Int, toPosition: Int)
}
- inner class ViewHolder(itemView: View) : PlaylistSongAdapter.ViewHolder(itemView),
+ inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView),
DraggableItemViewHolder {
@DraggableItemStateFlags
private var mDragStateFlags: Int = 0
@@ -132,8 +135,4 @@ class OrderablePlaylistSongAdapter(
mDragStateFlags = flags
}
}
-
- companion object {
- val TAG: String = OrderablePlaylistSongAdapter::class.java.simpleName
- }
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/adapter/song/PlayingQueueAdapter.kt b/app/src/main/java/io/github/muntashirakon/music/adapter/song/PlayingQueueAdapter.kt
index b58df715e..4f3c1891a 100644
--- a/app/src/main/java/io/github/muntashirakon/music/adapter/song/PlayingQueueAdapter.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/adapter/song/PlayingQueueAdapter.kt
@@ -3,14 +3,7 @@ package io.github.muntashirakon.music.adapter.song
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity
-import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.helper.MusicPlayerRemote
-import io.github.muntashirakon.music.helper.MusicPlayerRemote.isPlaying
-import io.github.muntashirakon.music.helper.MusicPlayerRemote.playNextSong
-import io.github.muntashirakon.music.helper.MusicPlayerRemote.removeFromQueue
-import io.github.muntashirakon.music.model.Song
-import io.github.muntashirakon.music.util.MusicUtil
-import io.github.muntashirakon.music.util.ViewUtil
+import androidx.fragment.app.FragmentActivity
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange
import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags
@@ -20,6 +13,14 @@ import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultAct
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionDefault
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionRemoveItem
import com.h6ah4i.android.widget.advrecyclerview.swipeable.annotation.SwipeableItemResults
+import io.github.muntashirakon.music.R
+import io.github.muntashirakon.music.helper.MusicPlayerRemote
+import io.github.muntashirakon.music.helper.MusicPlayerRemote.isPlaying
+import io.github.muntashirakon.music.helper.MusicPlayerRemote.playNextSong
+import io.github.muntashirakon.music.helper.MusicPlayerRemote.removeFromQueue
+import io.github.muntashirakon.music.model.Song
+import io.github.muntashirakon.music.util.MusicUtil
+import io.github.muntashirakon.music.util.ViewUtil
import me.zhanghai.android.fastscroll.PopupTextProvider
class PlayingQueueAdapter(
@@ -192,7 +193,7 @@ class PlayingQueueAdapter(
internal class SwipedResultActionRemoveItem(
private val adapter: PlayingQueueAdapter,
private val position: Int,
- private val activity: AppCompatActivity
+ private val activity: FragmentActivity
) : SwipeResultActionRemoveItem() {
private var songToRemove: Song? = null
diff --git a/app/src/main/java/io/github/muntashirakon/music/adapter/song/PlaylistSongAdapter.kt b/app/src/main/java/io/github/muntashirakon/music/adapter/song/PlaylistSongAdapter.kt
index e3aa67fec..4a73c7441 100644
--- a/app/src/main/java/io/github/muntashirakon/music/adapter/song/PlaylistSongAdapter.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/adapter/song/PlaylistSongAdapter.kt
@@ -1,15 +1,16 @@
package io.github.muntashirakon.music.adapter.song
-import android.app.ActivityOptions
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity
+import androidx.core.os.bundleOf
+import androidx.navigation.findNavController
+import com.google.android.material.button.MaterialButton
+import io.github.muntashirakon.music.EXTRA_ALBUM_ID
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.helper.MusicPlayerRemote
import io.github.muntashirakon.music.interfaces.CabHolder
import io.github.muntashirakon.music.model.Song
-import io.github.muntashirakon.music.util.NavigationUtil
-import com.google.android.material.button.MaterialButton
open class PlaylistSongAdapter(
activity: AppCompatActivity,
@@ -57,19 +58,14 @@ open class PlaylistSongAdapter(
override fun onSongMenuItemClick(item: MenuItem): Boolean {
if (item.itemId == R.id.action_go_to_album) {
- val activityOptions = ActivityOptions.makeSceneTransitionAnimation(
- activity,
- imageContainerCard ?: image,
- activity.getString(R.string.transition_album_art)
- )
- NavigationUtil.goToAlbumOptions(activity, song.albumId, activityOptions)
+ activity.findNavController(R.id.fragment_container)
+ .navigate(
+ R.id.albumDetailsFragment,
+ bundleOf(EXTRA_ALBUM_ID to song.albumId)
+ )
return true
}
return super.onSongMenuItemClick(item)
}
}
-
- companion object {
- val TAG: String = PlaylistSongAdapter::class.java.simpleName
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/adapter/song/SimpleSongAdapter.kt b/app/src/main/java/io/github/muntashirakon/music/adapter/song/SimpleSongAdapter.kt
index 2ffa38428..7c7a8cbd5 100755
--- a/app/src/main/java/io/github/muntashirakon/music/adapter/song/SimpleSongAdapter.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/adapter/song/SimpleSongAdapter.kt
@@ -2,14 +2,14 @@ package io.github.muntashirakon.music.adapter.song
import android.view.LayoutInflater
import android.view.ViewGroup
-import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.FragmentActivity
import io.github.muntashirakon.music.interfaces.CabHolder
import io.github.muntashirakon.music.model.Song
import io.github.muntashirakon.music.util.MusicUtil
import java.util.*
class SimpleSongAdapter(
- context: AppCompatActivity,
+ context: FragmentActivity,
songs: ArrayList,
layoutRes: Int,
cabHolder: CabHolder?
diff --git a/app/src/main/java/io/github/muntashirakon/music/adapter/song/SongAdapter.kt b/app/src/main/java/io/github/muntashirakon/music/adapter/song/SongAdapter.kt
index 42d260b4b..4af8e3f85 100644
--- a/app/src/main/java/io/github/muntashirakon/music/adapter/song/SongAdapter.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/adapter/song/SongAdapter.kt
@@ -1,13 +1,17 @@
package io.github.muntashirakon.music.adapter.song
-import android.app.ActivityOptions
import android.content.res.ColorStateList
import android.content.res.Resources
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
-import androidx.appcompat.app.AppCompatActivity
+import androidx.core.os.bundleOf
+import androidx.fragment.app.FragmentActivity
+import androidx.navigation.findNavController
+import com.afollestad.materialcab.MaterialCab
+import com.bumptech.glide.Glide
+import io.github.muntashirakon.music.EXTRA_ALBUM_ID
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.adapter.base.AbsMultiSelectAdapter
import io.github.muntashirakon.music.adapter.base.MediaEntryViewHolder
@@ -22,11 +26,8 @@ import io.github.muntashirakon.music.helper.menu.SongsMenuHelper
import io.github.muntashirakon.music.interfaces.CabHolder
import io.github.muntashirakon.music.model.Song
import io.github.muntashirakon.music.util.MusicUtil
-import io.github.muntashirakon.music.util.NavigationUtil
import io.github.muntashirakon.music.util.PreferenceUtil
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
-import com.afollestad.materialcab.MaterialCab
-import com.bumptech.glide.Glide
import me.zhanghai.android.fastscroll.PopupTextProvider
/**
@@ -34,7 +35,7 @@ import me.zhanghai.android.fastscroll.PopupTextProvider
*/
open class SongAdapter(
- protected val activity: AppCompatActivity,
+ protected val activity: FragmentActivity,
var dataSet: MutableList,
protected var itemLayoutRes: Int,
cabHolder: CabHolder?,
@@ -132,7 +133,7 @@ open class SongAdapter(
return song.title
}
- override fun onMultipleItemAction(menuItem: MenuItem, selection: ArrayList) {
+ override fun onMultipleItemAction(menuItem: MenuItem, selection: List) {
SongsMenuHelper.handleMenuClick(activity, selection, menuItem.itemId)
}
@@ -147,7 +148,6 @@ open class SongAdapter(
return ""
}
}
-
return MusicUtil.getSectionName(sectionName)
}
@@ -175,12 +175,11 @@ open class SongAdapter(
if (image != null && image!!.visibility == View.VISIBLE) {
when (item.itemId) {
R.id.action_go_to_album -> {
- val activityOptions = ActivityOptions.makeSceneTransitionAnimation(
- activity,
- imageContainerCard ?: image,
- activity.getString(R.string.transition_album_art)
- )
- NavigationUtil.goToAlbumOptions(activity, song.albumId, activityOptions)
+ activity.findNavController(R.id.fragment_container)
+ .navigate(
+ R.id.albumDetailsFragment,
+ bundleOf(EXTRA_ALBUM_ID to song.albumId)
+ )
return true
}
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/appshortcuts/AppShortcutLauncherActivity.kt b/app/src/main/java/io/github/muntashirakon/music/appshortcuts/AppShortcutLauncherActivity.kt
index fc5417778..185db958b 100644
--- a/app/src/main/java/io/github/muntashirakon/music/appshortcuts/AppShortcutLauncherActivity.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/appshortcuts/AppShortcutLauncherActivity.kt
@@ -17,15 +17,13 @@ package io.github.muntashirakon.music.appshortcuts
import android.app.Activity
import android.content.Intent
import android.os.Bundle
-import io.github.muntashirakon.music.activities.search.SearchActivity
import io.github.muntashirakon.music.appshortcuts.shortcuttype.LastAddedShortcutType
-import io.github.muntashirakon.music.appshortcuts.shortcuttype.SearchShortCutType
import io.github.muntashirakon.music.appshortcuts.shortcuttype.ShuffleAllShortcutType
import io.github.muntashirakon.music.appshortcuts.shortcuttype.TopTracksShortcutType
import io.github.muntashirakon.music.model.Playlist
import io.github.muntashirakon.music.model.smartplaylist.LastAddedPlaylist
-import io.github.muntashirakon.music.model.smartplaylist.MyTopTracksPlaylist
import io.github.muntashirakon.music.model.smartplaylist.ShuffleAllPlaylist
+import io.github.muntashirakon.music.model.smartplaylist.TopTracksPlaylist
import io.github.muntashirakon.music.service.MusicService
import io.github.muntashirakon.music.service.MusicService.*
@@ -45,26 +43,22 @@ class AppShortcutLauncherActivity : Activity() {
when (shortcutType) {
SHORTCUT_TYPE_SHUFFLE_ALL -> {
startServiceWithPlaylist(
- MusicService.SHUFFLE_MODE_SHUFFLE, ShuffleAllPlaylist(applicationContext)
+ SHUFFLE_MODE_SHUFFLE, ShuffleAllPlaylist()
)
DynamicShortcutManager.reportShortcutUsed(this, ShuffleAllShortcutType.id)
}
SHORTCUT_TYPE_TOP_TRACKS -> {
startServiceWithPlaylist(
- MusicService.SHUFFLE_MODE_NONE, MyTopTracksPlaylist(applicationContext)
+ SHUFFLE_MODE_NONE, TopTracksPlaylist()
)
DynamicShortcutManager.reportShortcutUsed(this, TopTracksShortcutType.id)
}
SHORTCUT_TYPE_LAST_ADDED -> {
startServiceWithPlaylist(
- MusicService.SHUFFLE_MODE_NONE, LastAddedPlaylist(applicationContext)
+ SHUFFLE_MODE_NONE, LastAddedPlaylist()
)
DynamicShortcutManager.reportShortcutUsed(this, LastAddedShortcutType.id)
}
- SHORTCUT_TYPE_SEARCH -> {
- startActivity(Intent(this, SearchActivity::class.java))
- DynamicShortcutManager.reportShortcutUsed(this, SearchShortCutType.id)
- }
}
finish()
}
@@ -87,7 +81,6 @@ class AppShortcutLauncherActivity : Activity() {
const val SHORTCUT_TYPE_SHUFFLE_ALL = 0
const val SHORTCUT_TYPE_TOP_TRACKS = 1
const val SHORTCUT_TYPE_LAST_ADDED = 2
- const val SHORTCUT_TYPE_SEARCH = 3
const val SHORTCUT_TYPE_NONE = 4
}
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/appshortcuts/DynamicShortcutManager.kt b/app/src/main/java/io/github/muntashirakon/music/appshortcuts/DynamicShortcutManager.kt
index 6cfcedba5..5c7b7b571 100644
--- a/app/src/main/java/io/github/muntashirakon/music/appshortcuts/DynamicShortcutManager.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/appshortcuts/DynamicShortcutManager.kt
@@ -22,7 +22,6 @@ import android.content.pm.ShortcutManager
import android.graphics.drawable.Icon
import android.os.Build
import io.github.muntashirakon.music.appshortcuts.shortcuttype.LastAddedShortcutType
-import io.github.muntashirakon.music.appshortcuts.shortcuttype.SearchShortCutType
import io.github.muntashirakon.music.appshortcuts.shortcuttype.ShuffleAllShortcutType
import io.github.muntashirakon.music.appshortcuts.shortcuttype.TopTracksShortcutType
import java.util.*
@@ -34,11 +33,9 @@ class DynamicShortcutManager(private val context: Context) {
private val defaultShortcuts: List
get() = Arrays.asList(
- SearchShortCutType(context).shortcutInfo,
ShuffleAllShortcutType(context).shortcutInfo,
TopTracksShortcutType(context).shortcutInfo,
LastAddedShortcutType(context).shortcutInfo
-
)
fun initDynamicShortcuts() {
diff --git a/app/src/main/java/io/github/muntashirakon/music/appshortcuts/shortcuttype/SearchShortCutType.kt b/app/src/main/java/io/github/muntashirakon/music/appshortcuts/shortcuttype/SearchShortCutType.kt
deleted file mode 100644
index 4a37a4cce..000000000
--- a/app/src/main/java/io/github/muntashirakon/music/appshortcuts/shortcuttype/SearchShortCutType.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package io.github.muntashirakon.music.appshortcuts.shortcuttype
-
-import android.annotation.TargetApi
-import android.content.Context
-import android.content.pm.ShortcutInfo
-import android.os.Build
-import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.appshortcuts.AppShortcutIconGenerator
-import io.github.muntashirakon.music.appshortcuts.AppShortcutLauncherActivity
-
-@TargetApi(Build.VERSION_CODES.N_MR1)
-class SearchShortCutType(context: Context) : BaseShortcutType(context) {
- companion object {
-
- val id: String
- get() = BaseShortcutType.ID_PREFIX + "search"
- }
-
- override val shortcutInfo: ShortcutInfo
- get() = ShortcutInfo.Builder(
- context,
- id
- ).setShortLabel(context.getString(R.string.action_search))
- .setLongLabel(context.getString(R.string.search_hint)).setIcon(
- AppShortcutIconGenerator.generateThemedIcon(
- context,
- R.drawable.ic_app_shortcut_search
- )
- ).setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_SEARCH))
- .build()
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/dialogs/AddToPlaylistDialog.kt b/app/src/main/java/io/github/muntashirakon/music/dialogs/AddToPlaylistDialog.kt
index 70779a683..79560c438 100644
--- a/app/src/main/java/io/github/muntashirakon/music/dialogs/AddToPlaylistDialog.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/dialogs/AddToPlaylistDialog.kt
@@ -22,22 +22,22 @@ import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.extensions.colorButtons
import io.github.muntashirakon.music.extensions.extraNotNull
import io.github.muntashirakon.music.extensions.materialDialog
-import io.github.muntashirakon.music.loaders.PlaylistLoader
import io.github.muntashirakon.music.model.Song
+import io.github.muntashirakon.music.repository.PlaylistRepository
import io.github.muntashirakon.music.util.PlaylistsUtil
+import org.koin.android.ext.android.inject
class AddToPlaylistDialog : DialogFragment() {
-
+ private val playlistRepository by inject()
override fun onCreateDialog(
savedInstanceState: Bundle?
): Dialog {
- val playlists = PlaylistLoader.getAllPlaylists(requireContext())
+ val playlists = playlistRepository.playlists()
val playlistNames = mutableListOf()
playlistNames.add(requireContext().resources.getString(R.string.action_new_playlist))
for (p in playlists) {
playlistNames.add(p.name)
}
-
return materialDialog(R.string.add_playlist_title)
.setItems(playlistNames.toTypedArray()) { _, which ->
val songs = extraNotNull>(EXTRA_SONG).value
diff --git a/app/src/main/java/io/github/muntashirakon/music/dialogs/DeleteSongsDialog.kt b/app/src/main/java/io/github/muntashirakon/music/dialogs/DeleteSongsDialog.kt
index 17ae9b1dc..43ba88dc5 100644
--- a/app/src/main/java/io/github/muntashirakon/music/dialogs/DeleteSongsDialog.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/dialogs/DeleteSongsDialog.kt
@@ -98,7 +98,9 @@ class DeleteSongsDialog : DialogFragment() {
}
fun deleteSongs(songs: List, safUris: List?) {
- MusicUtil.deleteTracks(requireActivity(), songs, safUris) { this.dismiss() }
+ MusicUtil.deleteTracks(requireActivity(), songs, safUris, Runnable {
+ dismiss()
+ })
}
companion object {
diff --git a/app/src/main/java/io/github/muntashirakon/music/extensions/ColorExt.kt b/app/src/main/java/io/github/muntashirakon/music/extensions/ColorExt.kt
index 7e9c60bcb..3f93d4d3c 100644
--- a/app/src/main/java/io/github/muntashirakon/music/extensions/ColorExt.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/extensions/ColorExt.kt
@@ -22,11 +22,17 @@ import android.widget.Button
import android.widget.CheckBox
import android.widget.SeekBar
import androidx.annotation.AttrRes
+import androidx.annotation.ColorInt
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.Fragment
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil
+import code.name.monkey.appthemehelper.util.MaterialValueHelper
+import com.google.android.material.button.MaterialButton
+import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
+import com.google.android.material.textfield.TextInputEditText
+import com.google.android.material.textfield.TextInputLayout
import io.github.muntashirakon.music.App
import io.github.muntashirakon.music.R
@@ -83,4 +89,45 @@ fun SeekBar.addAccentColor() {
fun Button.accentTextColor() {
setTextColor(ThemeStore.accentColor(App.getContext()))
+}
+
+fun SeekBar.applyColor(@ColorInt color: Int) {
+ thumbTintList = ColorStateList.valueOf(color)
+ progressTintList = ColorStateList.valueOf(color)
+ progressBackgroundTintList = ColorStateList.valueOf(color)
+}
+
+fun ExtendedFloatingActionButton.accentColor() {
+ val color = ThemeStore.accentColor(context)
+ val textColor = MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color))
+ val colorStateList = ColorStateList.valueOf(color)
+ val textColorStateList = ColorStateList.valueOf(textColor)
+ backgroundTintList = colorStateList
+ setTextColor(textColorStateList)
+ iconTint = textColorStateList
+}
+
+fun MaterialButton.applyColor(color: Int) {
+ val backgroundColorStateList = ColorStateList.valueOf(color)
+ val textColorColorStateList = ColorStateList.valueOf(
+ MaterialValueHelper.getPrimaryTextColor(
+ context,
+ ColorUtil.isColorLight(color)
+ )
+ )
+ backgroundTintList = backgroundColorStateList
+ setTextColor(textColorColorStateList)
+ iconTint = textColorColorStateList
+}
+
+fun TextInputLayout.accentColor() {
+ val accentColor = ThemeStore.accentColor(context)
+ val colorState = ColorStateList.valueOf(accentColor)
+ boxStrokeColor = accentColor
+ defaultHintTextColor = colorState
+ isHintAnimationEnabled = true
+}
+
+fun TextInputEditText.accentColor() {
+
}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/extensions/DimenExtension.kt b/app/src/main/java/io/github/muntashirakon/music/extensions/DimenExtension.kt
new file mode 100644
index 000000000..836f2e47a
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/extensions/DimenExtension.kt
@@ -0,0 +1,20 @@
+package io.github.muntashirakon.music.extensions
+
+import android.app.Activity
+import androidx.annotation.DimenRes
+import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.Fragment
+
+fun AppCompatActivity.dimToPixel(@DimenRes dimenRes: Int): Int {
+ return resources.getDimensionPixelSize(dimenRes)
+}
+
+fun Activity.dipToPix(dpInFloat: Float): Float {
+ val scale = resources.displayMetrics.density
+ return dpInFloat * scale + 0.5f
+}
+
+fun Fragment.dipToPix(dpInFloat: Float): Float {
+ val scale = resources.displayMetrics.density
+ return dpInFloat * scale + 0.5f
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/extensions/FragmentExt.kt b/app/src/main/java/io/github/muntashirakon/music/extensions/FragmentExt.kt
index 7da29401a..7c300f54a 100644
--- a/app/src/main/java/io/github/muntashirakon/music/extensions/FragmentExt.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/extensions/FragmentExt.kt
@@ -3,7 +3,10 @@ package io.github.muntashirakon.music.extensions
import android.content.Context
import android.content.res.Configuration
import android.os.PowerManager
+import android.widget.Toast
+import androidx.annotation.IdRes
import androidx.annotation.IntegerRes
+import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
@@ -51,5 +54,23 @@ fun AppCompatActivity.currentFragment(navHostId: Int): Fragment? {
val navHostFragment: NavHostFragment =
supportFragmentManager.findFragmentById(navHostId) as NavHostFragment
navHostFragment.targetFragment
- return navHostFragment?.childFragmentManager?.fragments?.first()
+ return navHostFragment.childFragmentManager.fragments.first()
}
+
+@Suppress("UNCHECKED_CAST")
+fun AppCompatActivity.whichFragment(@IdRes id: Int): T {
+ return supportFragmentManager.findFragmentById(id) as T
+}
+
+@Suppress("UNCHECKED_CAST")
+fun Fragment.whichFragment(@IdRes id: Int): T {
+ return childFragmentManager.findFragmentById(id) as T
+}
+
+fun Fragment.showToast(@StringRes stringRes: Int) {
+ showToast(getString(stringRes))
+}
+
+fun Fragment.showToast(message: String) {
+ Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/extensions/NavigationExtensions.kt b/app/src/main/java/io/github/muntashirakon/music/extensions/NavigationExtensions.kt
index 17cfbe196..7b2d0473f 100644
--- a/app/src/main/java/io/github/muntashirakon/music/extensions/NavigationExtensions.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/extensions/NavigationExtensions.kt
@@ -4,17 +4,22 @@ import androidx.annotation.IdRes
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
+import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.fragment.findNavController
fun Fragment.navigate(@IdRes id: Int) = findNavController().navigate(id)
-fun Fragment.navController(@IdRes id: Int): NavController {
+fun Fragment.findNavController(@IdRes id: Int): NavController {
val fragment = childFragmentManager.findFragmentById(id) as NavHostFragment
return fragment.navController
}
-fun AppCompatActivity.navController(@IdRes id: Int): NavController {
+fun Fragment.findActivityNavController(@IdRes id: Int): NavController {
+ return requireActivity().findNavController(id)
+}
+
+fun AppCompatActivity.findNavController(@IdRes id: Int): NavController {
val fragment = supportFragmentManager.findFragmentById(id) as NavHostFragment
return fragment.navController
}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/extensions/ViewExtensions.kt b/app/src/main/java/io/github/muntashirakon/music/extensions/ViewExtensions.kt
index f34def9c0..bc75abf41 100644
--- a/app/src/main/java/io/github/muntashirakon/music/extensions/ViewExtensions.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/extensions/ViewExtensions.kt
@@ -14,13 +14,10 @@
package io.github.muntashirakon.music.extensions
-import android.content.res.ColorStateList
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
-import android.widget.SeekBar
-import androidx.annotation.ColorInt
import androidx.annotation.LayoutRes
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.TintHelper
@@ -48,9 +45,3 @@ fun EditText.appHandleColor(): EditText {
TintHelper.colorHandles(this, ThemeStore.accentColor(context))
return this
}
-
-fun SeekBar.applyColor(@ColorInt color: Int) {
- thumbTintList = ColorStateList.valueOf(color)
- progressTintList = ColorStateList.valueOf(color)
- progressBackgroundTintList = ColorStateList.valueOf(color)
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/DetailListFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/DetailListFragment.kt
new file mode 100644
index 000000000..f90145eca
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/DetailListFragment.kt
@@ -0,0 +1,130 @@
+package io.github.muntashirakon.music.fragments
+
+import android.os.Bundle
+import android.view.View
+import android.widget.ImageView
+import androidx.navigation.fragment.navArgs
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.LinearLayoutManager
+import io.github.muntashirakon.music.*
+import io.github.muntashirakon.music.adapter.album.AlbumAdapter
+import io.github.muntashirakon.music.adapter.artist.ArtistAdapter
+import io.github.muntashirakon.music.adapter.song.SongAdapter
+import io.github.muntashirakon.music.fragments.albums.AlbumClickListener
+import io.github.muntashirakon.music.fragments.artists.ArtistClickListener
+import io.github.muntashirakon.music.fragments.base.AbsMainActivityFragment
+import io.github.muntashirakon.music.model.Album
+import io.github.muntashirakon.music.model.Artist
+import io.github.muntashirakon.music.model.Song
+import io.github.muntashirakon.music.repository.RealRepository
+import kotlinx.android.synthetic.main.fragment_playlist_detail.*
+import kotlinx.coroutines.CoroutineScope
+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 DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_detail),
+ ArtistClickListener, AlbumClickListener {
+ private val args by navArgs()
+ private val repository by inject()
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ mainActivity.setSupportActionBar(toolbar)
+ mainActivity.hideBottomBarVisibility(false)
+ when (args.type) {
+ TOP_ARTISTS -> {
+ loadArtists(R.string.top_artists, TOP_ARTISTS)
+ }
+ RECENT_ARTISTS -> {
+ loadArtists(R.string.recent_artists, RECENT_ARTISTS)
+ }
+ TOP_ALBUMS -> {
+ loadAlbums(R.string.top_albums, TOP_ALBUMS)
+ }
+ RECENT_ALBUMS -> {
+ loadAlbums(R.string.recent_albums, RECENT_ALBUMS)
+ }
+ FAVOURITES -> {
+ loadFavorite()
+ }
+ }
+ }
+
+ private fun loadFavorite() {
+ toolbar.setTitle(R.string.favorites)
+ CoroutineScope(IO).launch {
+ val songs = repository.favoritePlaylistHome()
+ withContext(Main) {
+ recyclerView.apply {
+ adapter = SongAdapter(
+ requireActivity(),
+ songs.arrayList as MutableList,
+ R.layout.item_list, null
+ )
+ layoutManager = linearLayoutManager()
+ }
+ }
+ }
+ }
+
+ private fun loadArtists(title: Int, type: Int) {
+ toolbar.setTitle(title)
+ CoroutineScope(IO).launch {
+ val artists =
+ if (type == TOP_ARTISTS) repository.topArtists() else repository.recentArtists()
+ withContext(Main) {
+ recyclerView.apply {
+ adapter = artistAdapter(artists)
+ layoutManager = gridLayoutManager()
+ }
+ }
+ }
+ }
+
+ private fun loadAlbums(title: Int, type: Int) {
+ toolbar.setTitle(title)
+ CoroutineScope(IO).launch {
+ val albums =
+ if (type == TOP_ALBUMS) repository.topAlbums() else repository.recentAlbums()
+ withContext(Main) {
+ recyclerView.apply {
+ adapter = albumAdapter(albums)
+ layoutManager = gridLayoutManager()
+
+ }
+ }
+ }
+ }
+
+ private fun artistAdapter(artists: List): ArtistAdapter = ArtistAdapter(
+ requireActivity(),
+ artists,
+ R.layout.item_grid_circle,
+ null, this@DetailListFragment
+ )
+
+ private fun albumAdapter(albums: List): AlbumAdapter = AlbumAdapter(
+ requireActivity(),
+ albums,
+ R.layout.item_grid,
+ null, this@DetailListFragment
+ )
+
+ private fun linearLayoutManager(): LinearLayoutManager =
+ LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
+
+ private fun gridLayoutManager(): GridLayoutManager =
+ GridLayoutManager(requireContext(), 2, GridLayoutManager.VERTICAL, false)
+
+
+ override fun onArtist(artistId: Int, imageView: ImageView) {
+
+ }
+
+ override fun onAlbumClick(albumId: Int, view: View) {
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/LibraryViewModel.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/LibraryViewModel.kt
index 149e17f69..6406d0ffc 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/LibraryViewModel.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/LibraryViewModel.kt
@@ -4,27 +4,26 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import io.github.muntashirakon.music.adapter.HomeAdapter
import io.github.muntashirakon.music.fragments.ReloadType.*
import io.github.muntashirakon.music.interfaces.MusicServiceEventListener
import io.github.muntashirakon.music.model.*
-import io.github.muntashirakon.music.providers.RepositoryImpl
+import io.github.muntashirakon.music.repository.RealRepository
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
class LibraryViewModel(
- private val repository: RepositoryImpl
+ private val realRepository: RealRepository
) : ViewModel(), MusicServiceEventListener {
+ private val paletteColor = MutableLiveData()
private val albums = MutableLiveData>()
private val songs = MutableLiveData>()
private val artists = MutableLiveData>()
private val playlists = MutableLiveData>()
private val genres = MutableLiveData>()
private val home = MutableLiveData>()
- private val paletteColor = MutableLiveData()
val paletteColorLiveData: LiveData = paletteColor
val homeLiveData: LiveData> = home
@@ -46,59 +45,36 @@ class LibraryViewModel(
artists.value = loadArtists.await()
playlists.value = loadPlaylists.await()
genres.value = loadGenres.await()
- loadHomeSections()
+ home.value = loadHome.await()
}
- private fun loadHomeSections() = viewModelScope.launch {
- val list = mutableListOf()
- val result = listOf(
- repository.topArtists(),
- repository.topAlbums(),
- repository.recentArtists(),
- repository.recentAlbums(),
- repository.suggestions(),
- repository.favoritePlaylist(),
- repository.homeGenres()
- )
- result.forEach {
- if (it != null && it.arrayList.isNotEmpty()) {
- if (it.homeSection == HomeAdapter.SUGGESTIONS) {
- if (it.arrayList.size > 9) {
- list.add(it)
- }
- } else {
- list.add(it)
- }
- }
- }
- home.value = list
- }
+ private val loadHome: Deferred>
+ get() = viewModelScope.async { realRepository.homeSections() }
private val loadSongs: Deferred>
- get() = viewModelScope.async(IO) {
- repository.allSongs()
- }
+ get() = viewModelScope.async(IO) { realRepository.allSongs() }
private val loadAlbums: Deferred>
get() = viewModelScope.async(IO) {
- repository.allAlbums()
+ realRepository.allAlbums()
}
private val loadArtists: Deferred>
get() = viewModelScope.async(IO) {
- repository.allArtists()
+ realRepository.albumArtists()
}
private val loadPlaylists: Deferred>
get() = viewModelScope.async(IO) {
- repository.allPlaylists()
+ realRepository.allPlaylists()
}
private val loadGenres: Deferred>
get() = viewModelScope.async(IO) {
- repository.allGenres()
+ realRepository.allGenres()
}
+
fun forceReload(reloadType: ReloadType) = viewModelScope.launch {
when (reloadType) {
Songs -> songs.value = loadSongs.await()
@@ -114,15 +90,37 @@ class LibraryViewModel(
override fun onMediaStoreChanged() {
loadLibraryContent()
+ println("onMediaStoreChanged")
}
- override fun onServiceConnected() {}
- override fun onServiceDisconnected() {}
- override fun onQueueChanged() {}
- override fun onPlayingMetaChanged() {}
- override fun onPlayStateChanged() {}
- override fun onRepeatModeChanged() {}
- override fun onShuffleModeChanged() {}
+
+ override fun onServiceConnected() {
+ println("onServiceConnected")
+ }
+
+ override fun onServiceDisconnected() {
+ println("onServiceDisconnected")
+ }
+
+ override fun onQueueChanged() {
+ println("onQueueChanged")
+ }
+
+ override fun onPlayingMetaChanged() {
+ println("onPlayingMetaChanged")
+ }
+
+ override fun onPlayStateChanged() {
+ println("onPlayStateChanged")
+ }
+
+ override fun onRepeatModeChanged() {
+ println("onRepeatModeChanged")
+ }
+
+ override fun onShuffleModeChanged() {
+ println("onShuffleModeChanged")
+ }
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/AboutActivity.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/about/AboutFragment.kt
similarity index 55%
rename from app/src/main/java/io/github/muntashirakon/music/activities/AboutActivity.kt
rename to app/src/main/java/io/github/muntashirakon/music/fragments/about/AboutFragment.kt
index b097f9b1f..b76f8cb32 100644
--- a/app/src/main/java/io/github/muntashirakon/music/activities/AboutActivity.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/about/AboutFragment.kt
@@ -1,32 +1,21 @@
-package io.github.muntashirakon.music.activities
+package io.github.muntashirakon.music.fragments.about
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
-import android.view.MenuItem
import android.view.View
import androidx.core.app.ShareCompat
+import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
-import io.github.muntashirakon.music.Constants.APP_INSTAGRAM_LINK
-import io.github.muntashirakon.music.Constants.APP_TELEGRAM_LINK
-import io.github.muntashirakon.music.Constants.APP_TWITTER_LINK
-import io.github.muntashirakon.music.Constants.FAQ_LINK
-import io.github.muntashirakon.music.Constants.GITHUB_PROJECT
-import io.github.muntashirakon.music.Constants.PINTEREST
-import io.github.muntashirakon.music.Constants.RATE_ON_GOOGLE_PLAY
-import io.github.muntashirakon.music.Constants.TELEGRAM_CHANGE_LOG
-import io.github.muntashirakon.music.Constants.TRANSLATE
-import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.activities.base.AbsBaseActivity
-import io.github.muntashirakon.music.adapter.ContributorAdapter
-import io.github.muntashirakon.music.extensions.applyToolbar
-import io.github.muntashirakon.music.model.Contributor
-import io.github.muntashirakon.music.util.NavigationUtil
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
-import kotlinx.android.synthetic.main.activity_about.*
+import io.github.muntashirakon.music.Constants
+import io.github.muntashirakon.music.R
+import io.github.muntashirakon.music.adapter.ContributorAdapter
+import io.github.muntashirakon.music.model.Contributor
+import io.github.muntashirakon.music.util.NavigationUtil
import kotlinx.android.synthetic.main.card_credit.*
import kotlinx.android.synthetic.main.card_other.*
import kotlinx.android.synthetic.main.card_retro_info.*
@@ -34,13 +23,19 @@ import kotlinx.android.synthetic.main.card_social.*
import java.io.IOException
import java.nio.charset.StandardCharsets
-class AboutActivity : AbsBaseActivity(), View.OnClickListener {
+class AboutFragment : Fragment(R.layout.fragment_about), View.OnClickListener {
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ version.setSummary(getAppVersion())
+ setUpView()
+ loadContributors()
+ }
private val contributorsJson: String?
get() {
val json: String
try {
- val inputStream = assets.open("contributors.json")
+ val inputStream = requireActivity().assets.open("contributors.json")
val size = inputStream.available()
val buffer = ByteArray(size)
inputStream.read(buffer)
@@ -53,27 +48,6 @@ class AboutActivity : AbsBaseActivity(), View.OnClickListener {
return json
}
- override fun onCreate(savedInstanceState: Bundle?) {
- setDrawUnderStatusBar()
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_about)
- setStatusbarColorAuto()
- setNavigationbarColorAuto()
- setLightNavigationBar(true)
-
- applyToolbar(toolbar)
- version.setSummary(getAppVersion())
- setUpView()
- loadContributors()
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- if (item.itemId == android.R.id.home) {
- onBackPressed()
- return true
- }
- return super.onOptionsItemSelected(item)
- }
private fun openUrl(url: String) {
val i = Intent(Intent.ACTION_VIEW)
@@ -89,6 +63,7 @@ class AboutActivity : AbsBaseActivity(), View.OnClickListener {
appRate.setOnClickListener(this)
appTranslation.setOnClickListener(this)
appShare.setOnClickListener(this)
+ donateLink.setOnClickListener(this)
instagramLink.setOnClickListener(this)
twitterLink.setOnClickListener(this)
changelog.setOnClickListener(this)
@@ -99,25 +74,26 @@ class AboutActivity : AbsBaseActivity(), View.OnClickListener {
override fun onClick(view: View) {
when (view.id) {
- R.id.pinterestLink -> openUrl(PINTEREST)
- R.id.faqLink -> openUrl(FAQ_LINK)
- R.id.telegramLink -> openUrl(APP_TELEGRAM_LINK)
- R.id.appGithub -> openUrl(GITHUB_PROJECT)
- R.id.appTranslation -> openUrl(TRANSLATE)
- R.id.appRate -> openUrl(RATE_ON_GOOGLE_PLAY)
+ R.id.pinterestLink -> openUrl(Constants.PINTEREST)
+ R.id.faqLink -> openUrl(Constants.FAQ_LINK)
+ R.id.telegramLink -> openUrl(Constants.APP_TELEGRAM_LINK)
+ R.id.appGithub -> openUrl(Constants.GITHUB_PROJECT)
+ R.id.appTranslation -> openUrl(Constants.TRANSLATE)
+ R.id.appRate -> openUrl(Constants.RATE_ON_GOOGLE_PLAY)
R.id.appShare -> shareApp()
- R.id.instagramLink -> openUrl(APP_INSTAGRAM_LINK)
- R.id.twitterLink -> openUrl(APP_TWITTER_LINK)
- R.id.changelog -> openUrl(TELEGRAM_CHANGE_LOG)
- R.id.openSource -> NavigationUtil.goToOpenSource(this)
- R.id.bugReportLink -> NavigationUtil.bugReport(this)
+ R.id.instagramLink -> openUrl(Constants.APP_INSTAGRAM_LINK)
+ R.id.twitterLink -> openUrl(Constants.APP_TWITTER_LINK)
+ R.id.changelog -> openUrl(Constants.TELEGRAM_CHANGE_LOG)
+ R.id.openSource -> NavigationUtil.goToOpenSource(requireActivity())
+ R.id.bugReportLink -> NavigationUtil.bugReport(requireActivity())
}
}
private fun getAppVersion(): String {
return try {
val isPro = "Pro"
- val packageInfo = packageManager.getPackageInfo(packageName, 0)
+ val packageInfo =
+ requireActivity().packageManager.getPackageInfo(requireActivity().packageName, 0)
"${packageInfo.versionName} $isPro"
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
@@ -126,9 +102,10 @@ class AboutActivity : AbsBaseActivity(), View.OnClickListener {
}
private fun shareApp() {
- ShareCompat.IntentBuilder.from(this).setType("text/plain")
+ ShareCompat.IntentBuilder.from(requireActivity()).setType("text/plain")
.setChooserTitle(R.string.share_app)
- .setText(String.format(getString(R.string.app_share), packageName)).startChooser()
+ .setText(String.format(getString(R.string.app_share), requireActivity().packageName))
+ .startChooser()
}
private fun loadContributors() {
@@ -138,8 +115,10 @@ class AboutActivity : AbsBaseActivity(), View.OnClickListener {
val contributors = Gson().fromJson>(contributorsJson, type)
val contributorAdapter = ContributorAdapter(contributors)
- recyclerView.layoutManager = LinearLayoutManager(this)
- recyclerView.itemAnimator = DefaultItemAnimator()
- recyclerView.adapter = contributorAdapter
+ recyclerView.apply {
+ layoutManager = LinearLayoutManager(requireContext())
+ itemAnimator = DefaultItemAnimator()
+ adapter = contributorAdapter
+ }
}
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/albums/AlbumDetailsActivity.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsFragment.kt
similarity index 56%
rename from app/src/main/java/io/github/muntashirakon/music/activities/albums/AlbumDetailsActivity.kt
rename to app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsFragment.kt
index 94e081d57..15bf1b0e9 100644
--- a/app/src/main/java/io/github/muntashirakon/music/activities/albums/AlbumDetailsActivity.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsFragment.kt
@@ -1,137 +1,103 @@
-package io.github.muntashirakon.music.activities.albums
+package io.github.muntashirakon.music.fragments.albums
import android.app.ActivityOptions
import android.content.Intent
import android.os.Bundle
-import android.transition.Slide
-import android.view.Menu
-import android.view.MenuItem
-import android.view.SubMenu
-import android.view.View
-import androidx.core.app.ActivityCompat
+import android.view.*
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.os.bundleOf
+import androidx.lifecycle.Observer
+import androidx.navigation.findNavController
+import androidx.navigation.fragment.findNavController
+import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
-import code.name.monkey.appthemehelper.util.ATHUtil
-import code.name.monkey.appthemehelper.util.MaterialUtil
+import code.name.monkey.appthemehelper.common.ATHToolbarActivity.getToolbarBackgroundColor
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
+import com.bumptech.glide.Glide
+import io.github.muntashirakon.music.EXTRA_ALBUM_ID
+import io.github.muntashirakon.music.EXTRA_ARTIST_ID
import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.activities.base.AbsSlidingMusicPanelActivity
import io.github.muntashirakon.music.activities.tageditor.AbsTagEditorActivity
import io.github.muntashirakon.music.activities.tageditor.AlbumTagEditorActivity
import io.github.muntashirakon.music.adapter.album.HorizontalAlbumAdapter
import io.github.muntashirakon.music.adapter.song.SimpleSongAdapter
import io.github.muntashirakon.music.dialogs.AddToPlaylistDialog
import io.github.muntashirakon.music.dialogs.DeleteSongsDialog
-import io.github.muntashirakon.music.extensions.extraNotNull
+import io.github.muntashirakon.music.extensions.applyColor
import io.github.muntashirakon.music.extensions.show
-import io.github.muntashirakon.music.extensions.surfaceColor
+import io.github.muntashirakon.music.fragments.base.AbsMainActivityFragment
import io.github.muntashirakon.music.glide.AlbumGlideRequest
import io.github.muntashirakon.music.glide.ArtistGlideRequest
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
import io.github.muntashirakon.music.helper.MusicPlayerRemote
-import io.github.muntashirakon.music.helper.SortOrder.AlbumSongSortOrder
-import io.github.muntashirakon.music.interfaces.CabHolder
+import io.github.muntashirakon.music.helper.SortOrder
import io.github.muntashirakon.music.model.Album
import io.github.muntashirakon.music.model.Artist
import io.github.muntashirakon.music.network.model.LastFmAlbum
-import io.github.muntashirakon.music.util.*
+import io.github.muntashirakon.music.util.MusicUtil
+import io.github.muntashirakon.music.util.PreferenceUtil
+import io.github.muntashirakon.music.util.RetroUtil
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
-import com.afollestad.materialcab.MaterialCab
-import com.bumptech.glide.Glide
-import kotlinx.android.synthetic.main.activity_album.*
-import kotlinx.android.synthetic.main.activity_album_content.*
+import kotlinx.android.synthetic.main.fragment_album_content.*
+import kotlinx.android.synthetic.main.fragment_album_details.*
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
import java.util.*
-import android.util.Pair as UtilPair
-class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder {
- override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
- cab?.let {
- if (it.isActive) it.finish()
- }
- cab = MaterialCab(this, R.id.cab_stub)
- .setMenu(menuRes)
- .setCloseDrawableRes(R.drawable.ic_close)
- .setBackgroundColor(
- RetroColorUtil.shiftBackgroundColorForLightText(
- ATHUtil.resolveColor(
- this,
- R.attr.colorSurface
- )
- )
- )
- .start(callback)
- return cab as MaterialCab
- }
+class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_details),
+ AlbumClickListener {
+ private val arguments by navArgs()
private val detailsViewModel by viewModel {
- parametersOf(extraNotNull(EXTRA_ALBUM_ID).value)
+ parametersOf(arguments.extraAlbumId)
}
+
private lateinit var simpleSongAdapter: SimpleSongAdapter
private lateinit var album: Album
- private var cab: MaterialCab? = null
+
private val savedSortOrder: String
get() = PreferenceUtil.albumDetailSongSortOrder
- override fun createContentView(): View {
- return wrapSlidingMusicPanel(R.layout.activity_album)
- }
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ setHasOptionsMenu(true)
+ mainActivity.hideBottomBarVisibility(false)
+ mainActivity.addMusicServiceEventListener(detailsViewModel)
+ mainActivity.setSupportActionBar(toolbar)
- private fun windowEnterTransition() {
- val slide = Slide()
- slide.excludeTarget(R.id.appBarLayout, true)
- slide.excludeTarget(R.id.status_bar, true)
- slide.excludeTarget(android.R.id.statusBarBackground, true)
- slide.excludeTarget(android.R.id.navigationBarBackground, true)
- window.enterTransition = slide
- }
+ toolbar.title = null
- override fun onCreate(savedInstanceState: Bundle?) {
- setDrawUnderStatusBar()
- super.onCreate(savedInstanceState)
- setStatusbarColorAuto()
- setNavigationbarColorAuto()
- setTaskDescriptionColorAuto()
- setLightNavigationBar(true)
- setBottomBarVisibility(View.GONE)
- window.sharedElementsUseOverlay = true
- windowEnterTransition()
- toolbar.setBackgroundColor(surfaceColor())
-
- addMusicServiceEventListener(detailsViewModel)
- ActivityCompat.postponeEnterTransition(this)
-
- detailsViewModel.getAlbum().observe(this, androidx.lifecycle.Observer {
- ActivityCompat.startPostponedEnterTransition(this@AlbumDetailsActivity)
+ postponeEnterTransition()
+ detailsViewModel.getAlbum().observe(viewLifecycleOwner, Observer {
showAlbum(it)
+ startPostponedEnterTransition()
})
- detailsViewModel.getArtist().observe(this, androidx.lifecycle.Observer {
+ detailsViewModel.getArtist().observe(viewLifecycleOwner, Observer {
loadArtistImage(it)
})
- detailsViewModel.getMoreAlbums().observe(this, androidx.lifecycle.Observer {
+ detailsViewModel.getMoreAlbums().observe(viewLifecycleOwner, Observer {
moreAlbums(it)
})
- detailsViewModel.getAlbumInfo().observe(this, androidx.lifecycle.Observer {
+ detailsViewModel.getAlbumInfo().observe(viewLifecycleOwner, Observer {
aboutAlbum(it)
})
setupRecyclerView()
artistImage.setOnClickListener {
- val artistPairs = ActivityOptions.makeSceneTransitionAnimation(
- this,
- UtilPair.create(
- artistImage,
- getString(R.string.transition_artist_image)
+ requireActivity().findNavController(R.id.fragment_container)
+ .navigate(
+ R.id.artistDetailsFragment,
+ bundleOf(EXTRA_ARTIST_ID to album.artistId)
)
+ }
+ playAction.setOnClickListener { MusicPlayerRemote.openQueue(album.songs!!, 0, true) }
+
+ shuffleAction.setOnClickListener {
+ MusicPlayerRemote.openAndShuffleQueue(
+ album.songs!!,
+ true
)
- NavigationUtil.goToArtistOptions(this, album.artistId, artistPairs)
- }
- playAction.apply {
- setOnClickListener { MusicPlayerRemote.openQueue(album.songs!!, 0, true) }
- }
- shuffleAction.apply {
- setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(album.songs!!, true) }
}
aboutAlbumText.setOnClickListener {
@@ -141,12 +107,26 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder {
aboutAlbumText.maxLines = 4
}
}
+ image.apply {
+ transitionName = getString(R.string.transition_album_art)
+ }
}
+ override fun onDestroy() {
+ super.onDestroy()
+ playerActivity?.removeMusicServiceEventListener(detailsViewModel)
+ }
+
+
private fun setupRecyclerView() {
- simpleSongAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song, this)
+ simpleSongAdapter = SimpleSongAdapter(
+ requireActivity() as AppCompatActivity,
+ ArrayList(),
+ R.layout.item_song,
+ null
+ )
recyclerView.apply {
- layoutManager = LinearLayoutManager(this@AlbumDetailsActivity)
+ layoutManager = LinearLayoutManager(requireContext())
itemAnimator = DefaultItemAnimator()
isNestedScrollingEnabled = false
adapter = simpleSongAdapter
@@ -155,7 +135,6 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder {
private fun showAlbum(album: Album) {
if (album.songs!!.isEmpty()) {
- finish()
return
}
this.album = album
@@ -194,9 +173,10 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder {
moreRecyclerView.show()
moreTitle.text = String.format(getString(R.string.label_more_from), album.artistName)
- val albumAdapter = HorizontalAlbumAdapter(this, albums, null)
+ val albumAdapter =
+ HorizontalAlbumAdapter(requireActivity() as AppCompatActivity, albums, null, this)
moreRecyclerView.layoutManager = GridLayoutManager(
- this,
+ requireContext(),
1,
GridLayoutManager.HORIZONTAL,
false
@@ -226,8 +206,8 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder {
}
private fun loadArtistImage(artist: Artist) {
- ArtistGlideRequest.Builder.from(Glide.with(this), artist)
- .generatePalette(this)
+ ArtistGlideRequest.Builder.from(Glide.with(requireContext()), artist)
+ .generatePalette(requireContext())
.build()
.dontAnimate()
.dontTransform()
@@ -238,10 +218,10 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder {
}
private fun loadAlbumCover() {
- AlbumGlideRequest.Builder.from(Glide.with(this), album.safeGetFirstSong())
- .checkIgnoreMediaStore(this)
+ AlbumGlideRequest.Builder.from(Glide.with(requireContext()), album.safeGetFirstSong())
+ .checkIgnoreMediaStore(requireContext())
.ignoreMediaStore(PreferenceUtil.isIgnoreMediaStoreArtwork)
- .generatePalette(this)
+ .generatePalette(requireContext())
.build()
.dontAnimate()
.dontTransform()
@@ -253,32 +233,28 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder {
}
private fun setColors(color: MediaNotificationProcessor) {
- MaterialUtil.tintColor(
- button = shuffleAction,
- textColor = color.primaryTextColor,
- backgroundColor = color.backgroundColor
- )
- MaterialUtil.tintColor(
- button = playAction,
- textColor = color.primaryTextColor,
- backgroundColor = color.backgroundColor
- )
-
- setSupportActionBar(toolbar)
- supportActionBar?.title = null
+ shuffleAction.applyColor(color.backgroundColor)
+ playAction.applyColor(color.backgroundColor)
}
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
- menuInflater.inflate(R.menu.menu_album_detail, menu)
+ override fun onAlbumClick(albumId: Int, view: View) {
+ findNavController().navigate(
+ R.id.albumDetailsFragment,
+ bundleOf(EXTRA_ALBUM_ID to albumId)
+ )
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ super.onCreateOptionsMenu(menu, inflater)
+ inflater.inflate(R.menu.menu_album_detail, menu)
val sortOrder = menu.findItem(R.id.action_sort_order)
setUpSortOrderMenu(sortOrder.subMenu)
ToolbarContentTintHelper.handleOnCreateOptionsMenu(
- this,
+ requireContext(),
toolbar,
menu,
getToolbarBackgroundColor(toolbar)
)
- return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
@@ -289,6 +265,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder {
var sortOrder: String? = null
val songs = simpleSongAdapter.dataSet
when (item.itemId) {
+ android.R.id.home -> findNavController().navigateUp()
R.id.action_play_next -> {
MusicPlayerRemote.playNext(songs)
return true
@@ -298,22 +275,18 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder {
return true
}
R.id.action_add_to_playlist -> {
- AddToPlaylistDialog.create(songs).show(supportFragmentManager, "ADD_PLAYLIST")
+ AddToPlaylistDialog.create(songs).show(childFragmentManager, "ADD_PLAYLIST")
return true
}
R.id.action_delete_from_device -> {
- DeleteSongsDialog.create(songs).show(supportFragmentManager, "DELETE_SONGS")
- return true
- }
- android.R.id.home -> {
- super.onBackPressed()
+ DeleteSongsDialog.create(songs).show(childFragmentManager, "DELETE_SONGS")
return true
}
R.id.action_tag_editor -> {
- val intent = Intent(this, AlbumTagEditorActivity::class.java)
+ val intent = Intent(requireContext(), AlbumTagEditorActivity::class.java)
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, album.id)
val options = ActivityOptions.makeSceneTransitionAnimation(
- this,
+ requireActivity(),
albumCoverContainer,
"${getString(R.string.transition_album_art)}_${album.id}"
)
@@ -324,11 +297,12 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder {
return true
}
/*Sort*/
- R.id.action_sort_order_title -> sortOrder = AlbumSongSortOrder.SONG_A_Z
- R.id.action_sort_order_title_desc -> sortOrder = AlbumSongSortOrder.SONG_Z_A
- R.id.action_sort_order_track_list -> sortOrder = AlbumSongSortOrder.SONG_TRACK_LIST
+ R.id.action_sort_order_title -> sortOrder = SortOrder.AlbumSongSortOrder.SONG_A_Z
+ R.id.action_sort_order_title_desc -> sortOrder = SortOrder.AlbumSongSortOrder.SONG_Z_A
+ R.id.action_sort_order_track_list -> sortOrder =
+ SortOrder.AlbumSongSortOrder.SONG_TRACK_LIST
R.id.action_sort_order_artist_song_duration ->
- sortOrder = AlbumSongSortOrder.SONG_DURATION
+ sortOrder = SortOrder.AlbumSongSortOrder.SONG_DURATION
}
if (sortOrder != null) {
item.isChecked = true
@@ -339,13 +313,13 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder {
private fun setUpSortOrderMenu(sortOrder: SubMenu) {
when (savedSortOrder) {
- AlbumSongSortOrder.SONG_A_Z -> sortOrder.findItem(R.id.action_sort_order_title)
+ SortOrder.AlbumSongSortOrder.SONG_A_Z -> sortOrder.findItem(R.id.action_sort_order_title)
.isChecked = true
- AlbumSongSortOrder.SONG_Z_A -> sortOrder.findItem(R.id.action_sort_order_title_desc)
+ SortOrder.AlbumSongSortOrder.SONG_Z_A -> sortOrder.findItem(R.id.action_sort_order_title_desc)
.isChecked = true
- AlbumSongSortOrder.SONG_TRACK_LIST -> sortOrder.findItem(R.id.action_sort_order_track_list)
+ SortOrder.AlbumSongSortOrder.SONG_TRACK_LIST -> sortOrder.findItem(R.id.action_sort_order_track_list)
.isChecked = true
- AlbumSongSortOrder.SONG_DURATION -> sortOrder.findItem(R.id.action_sort_order_artist_song_duration)
+ SortOrder.AlbumSongSortOrder.SONG_DURATION -> sortOrder.findItem(R.id.action_sort_order_artist_song_duration)
.isChecked = true
}
}
@@ -353,22 +327,22 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder {
private fun setSaveSortOrder(sortOrder: String) {
PreferenceUtil.albumDetailSongSortOrder = sortOrder
when (sortOrder) {
- AlbumSongSortOrder.SONG_TRACK_LIST -> album.songs?.sortWith(Comparator { o1, o2 ->
+ SortOrder.AlbumSongSortOrder.SONG_TRACK_LIST -> album.songs?.sortWith(Comparator { o1, o2 ->
o1.trackNumber.compareTo(
o2.trackNumber
)
})
- AlbumSongSortOrder.SONG_A_Z -> album.songs?.sortWith(Comparator { o1, o2 ->
+ SortOrder.AlbumSongSortOrder.SONG_A_Z -> album.songs?.sortWith(Comparator { o1, o2 ->
o1.title.compareTo(
o2.title
)
})
- AlbumSongSortOrder.SONG_Z_A -> album.songs?.sortWith(Comparator { o1, o2 ->
+ SortOrder.AlbumSongSortOrder.SONG_Z_A -> album.songs?.sortWith(Comparator { o1, o2 ->
o2.title.compareTo(
o1.title
)
})
- AlbumSongSortOrder.SONG_DURATION -> album.songs?.sortWith(Comparator { o1, o2 ->
+ SortOrder.AlbumSongSortOrder.SONG_DURATION -> album.songs?.sortWith(Comparator { o1, o2 ->
o1.duration.compareTo(
o2.duration
)
@@ -377,23 +351,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder {
album.songs?.let { simpleSongAdapter.swapDataSet(it) }
}
-
- override fun onBackPressed() {
- if (cab != null && cab!!.isActive) {
- cab?.finish()
- } else {
- super.onBackPressed()
- }
- }
-
- override fun onDestroy() {
- super.onDestroy()
- removeMusicServiceEventListener(detailsViewModel)
- }
-
companion object {
-
- const val EXTRA_ALBUM_ID = "extra_album_id"
- private const val TAG_EDITOR_REQUEST = 2001
+ const val TAG_EDITOR_REQUEST = 9002
}
}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/albums/AlbumDetailsViewModel.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsViewModel.kt
similarity index 87%
rename from app/src/main/java/io/github/muntashirakon/music/activities/albums/AlbumDetailsViewModel.kt
rename to app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsViewModel.kt
index 2ffc2e636..65b7338b2 100644
--- a/app/src/main/java/io/github/muntashirakon/music/activities/albums/AlbumDetailsViewModel.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsViewModel.kt
@@ -1,4 +1,4 @@
-package io.github.muntashirakon.music.activities.albums
+package io.github.muntashirakon.music.fragments.albums
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
@@ -8,15 +8,14 @@ import io.github.muntashirakon.music.interfaces.MusicServiceEventListener
import io.github.muntashirakon.music.model.Album
import io.github.muntashirakon.music.model.Artist
import io.github.muntashirakon.music.network.model.LastFmAlbum
-import io.github.muntashirakon.music.providers.RepositoryImpl
+import io.github.muntashirakon.music.repository.RealRepository
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
-import java.lang.Exception
class AlbumDetailsViewModel(
- private val repository: RepositoryImpl,
+ private val realRepository: RealRepository,
private val albumId: Int
) : ViewModel(), MusicServiceEventListener {
@@ -41,7 +40,7 @@ class AlbumDetailsViewModel(
fun loadAlbumInfo(album: Album) = viewModelScope.launch(Dispatchers.IO) {
try {
- val lastFmAlbum = repository.albumInfo(
+ val lastFmAlbum = realRepository.albumInfo(
album.artistName ?: "-", album.title ?: "-"
)
_lastFmAlbum.postValue(lastFmAlbum)
@@ -49,7 +48,7 @@ class AlbumDetailsViewModel(
}
fun loadArtist(artistId: Int) = viewModelScope.launch(Dispatchers.IO) {
- val artist = repository.artistById(artistId)
+ val artist = realRepository.artistById(artistId)
_artist.postValue(artist)
artist.albums?.filter { item -> item.id != albumId }?.let { albums ->
@@ -59,7 +58,7 @@ class AlbumDetailsViewModel(
private val loadAlbumAsync: Deferred
get() = viewModelScope.async(Dispatchers.IO) {
- repository.albumById(albumId)
+ realRepository.albumById(albumId)
}
override fun onMediaStoreChanged() {
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumsFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumsFragment.kt
index 1b5e0d5c0..9724b3247 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumsFragment.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumsFragment.kt
@@ -2,32 +2,30 @@ package io.github.muntashirakon.music.fragments.albums
import android.os.Bundle
import android.view.View
+import androidx.core.os.bundleOf
import androidx.lifecycle.Observer
+import androidx.navigation.findNavController
+import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.recyclerview.widget.GridLayoutManager
+import io.github.muntashirakon.music.EXTRA_ALBUM_ID
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.adapter.album.AlbumAdapter
import io.github.muntashirakon.music.fragments.ReloadType
import io.github.muntashirakon.music.fragments.base.AbsRecyclerViewCustomGridSizeFragment
-import io.github.muntashirakon.music.interfaces.MainActivityFragmentCallbacks
import io.github.muntashirakon.music.util.PreferenceUtil
class AlbumsFragment :
AbsRecyclerViewCustomGridSizeFragment(),
- MainActivityFragmentCallbacks {
-
- override fun handleBackPress(): Boolean {
- return false
- }
+ AlbumClickListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- libraryViewModel.albumsLiveData
- .observe(viewLifecycleOwner, Observer { albums ->
- if (albums.isNotEmpty())
- adapter?.swapDataSet(albums)
- else
- adapter?.swapDataSet(listOf())
- })
+ libraryViewModel.albumsLiveData.observe(viewLifecycleOwner, Observer {
+ if (it.isNotEmpty())
+ adapter?.swapDataSet(it)
+ else
+ adapter?.swapDataSet(listOf())
+ })
}
override val emptyMessage: Int
@@ -40,10 +38,11 @@ class AlbumsFragment :
override fun createAdapter(): AlbumAdapter {
val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet
return AlbumAdapter(
- mainActivity,
+ requireActivity(),
dataSet,
- itemLayoutRes(),
- mainActivity
+ R.layout.item_grid,
+ null,
+ this
)
}
@@ -90,12 +89,24 @@ class AlbumsFragment :
companion object {
- @JvmField
- var TAG: String = AlbumsFragment::class.java.simpleName
-
- @JvmStatic
fun newInstance(): AlbumsFragment {
return AlbumsFragment()
}
}
+
+ override fun onAlbumClick(albumId: Int, view: View) {
+ val controller = requireActivity().findNavController(R.id.fragment_container)
+ controller.navigate(
+ R.id.albumDetailsFragment,
+ bundleOf(EXTRA_ALBUM_ID to albumId),
+ null,
+ FragmentNavigatorExtras(
+ view to getString(R.string.transition_album_art)
+ )
+ )
+ }
}
+
+interface AlbumClickListener {
+ fun onAlbumClick(albumId: Int, view: View)
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/artists/ArtistDetailActivity.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistDetailsFragment.kt
old mode 100755
new mode 100644
similarity index 55%
rename from app/src/main/java/io/github/muntashirakon/music/activities/artists/ArtistDetailActivity.kt
rename to app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistDetailsFragment.kt
index 53f0d5215..679be368a
--- a/app/src/main/java/io/github/muntashirakon/music/activities/artists/ArtistDetailActivity.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistDetailsFragment.kt
@@ -1,115 +1,79 @@
-package io.github.muntashirakon.music.activities.artists
+package io.github.muntashirakon.music.fragments.artists
-import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.text.Spanned
-import android.transition.Slide
import android.view.Menu
+import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
-import android.widget.Toast
-import androidx.core.app.ActivityCompat
+import androidx.core.os.bundleOf
import androidx.core.text.HtmlCompat
+import androidx.lifecycle.Observer
+import androidx.navigation.fragment.FragmentNavigatorExtras
+import androidx.navigation.fragment.findNavController
+import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
-import code.name.monkey.appthemehelper.util.ATHUtil
-import code.name.monkey.appthemehelper.util.MaterialUtil
+import com.bumptech.glide.Glide
import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.activities.base.AbsSlidingMusicPanelActivity
import io.github.muntashirakon.music.adapter.album.HorizontalAlbumAdapter
import io.github.muntashirakon.music.adapter.song.SimpleSongAdapter
import io.github.muntashirakon.music.dialogs.AddToPlaylistDialog
-import io.github.muntashirakon.music.extensions.extraNotNull
+import io.github.muntashirakon.music.extensions.applyColor
import io.github.muntashirakon.music.extensions.show
-import io.github.muntashirakon.music.extensions.surfaceColor
+import io.github.muntashirakon.music.extensions.showToast
+import io.github.muntashirakon.music.fragments.albums.AlbumClickListener
+import io.github.muntashirakon.music.fragments.base.AbsMainActivityFragment
import io.github.muntashirakon.music.glide.ArtistGlideRequest
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
import io.github.muntashirakon.music.helper.MusicPlayerRemote
-import io.github.muntashirakon.music.interfaces.CabHolder
import io.github.muntashirakon.music.model.Artist
import io.github.muntashirakon.music.network.model.LastFmArtist
import io.github.muntashirakon.music.util.CustomArtistImageUtil
import io.github.muntashirakon.music.util.MusicUtil
-import io.github.muntashirakon.music.util.RetroColorUtil
import io.github.muntashirakon.music.util.RetroUtil
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
-import com.afollestad.materialcab.MaterialCab
-import com.bumptech.glide.Glide
-import kotlinx.android.synthetic.main.activity_artist_content.*
-import kotlinx.android.synthetic.main.activity_artist_details.*
+import kotlinx.android.synthetic.main.fragment_artist_content.*
+import kotlinx.android.synthetic.main.fragment_artist_details.*
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
import java.util.*
import kotlin.collections.ArrayList
-class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder {
- override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
- cab?.let {
- if (it.isActive) it.finish()
- }
- cab = MaterialCab(this, R.id.cab_stub)
- .setMenu(menuRes)
- .setCloseDrawableRes(R.drawable.ic_close)
- .setBackgroundColor(
- RetroColorUtil.shiftBackgroundColorForLightText(
- ATHUtil.resolveColor(
- this,
- R.attr.colorSurface
- )
- )
- )
- .start(callback)
- return cab as MaterialCab
+class ArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_details),
+ AlbumClickListener {
+ private val arguments by navArgs()
+ private val detailsViewModel: ArtistDetailsViewModel by viewModel {
+ parametersOf(arguments.extraArtistId)
}
- private var cab: MaterialCab? = null
- private var biography: Spanned? = null
private lateinit var artist: Artist
private lateinit var songAdapter: SimpleSongAdapter
private lateinit var albumAdapter: HorizontalAlbumAdapter
private var forceDownload: Boolean = false
- private val detailsViewModel: ArtistDetailsViewModel by viewModel {
- parametersOf(extraNotNull(EXTRA_ARTIST_ID).value)
- }
+ private var lang: String? = null
+ private var biography: Spanned? = null
- override fun createContentView(): View {
- return wrapSlidingMusicPanel(R.layout.activity_artist_details)
- }
- private fun windowEnterTransition() {
- val slide = Slide()
- slide.excludeTarget(R.id.appBarLayout, true)
- slide.excludeTarget(R.id.status_bar, true)
- slide.excludeTarget(android.R.id.statusBarBackground, true)
- slide.excludeTarget(android.R.id.navigationBarBackground, true)
- window.enterTransition = slide
- }
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ setHasOptionsMenu(true)
+ mainActivity.setSupportActionBar(toolbar)
+ mainActivity.hideBottomBarVisibility(false)
+ toolbar.title = null
+ setupRecyclerView()
+ postponeEnterTransition()
+ detailsViewModel.getArtist().observe(viewLifecycleOwner, Observer {
- override fun onCreate(savedInstanceState: Bundle?) {
- setDrawUnderStatusBar()
- super.onCreate(savedInstanceState)
- setStatusbarColorAuto()
- setNavigationbarColorAuto()
- setTaskDescriptionColorAuto()
- setLightNavigationBar(true)
- setBottomBarVisibility(View.GONE)
- window.sharedElementsUseOverlay = true
- windowEnterTransition()
- toolbar.setBackgroundColor(surfaceColor())
-
- addMusicServiceEventListener(detailsViewModel)
-
- ActivityCompat.postponeEnterTransition(this)
- detailsViewModel.getArtist().observe(this, androidx.lifecycle.Observer {
- ActivityCompat.startPostponedEnterTransition(this@ArtistDetailActivity)
- artist(it)
+ showArtist(it)
+ startPostponedEnterTransition()
})
- detailsViewModel.getArtistInfo().observe(this, androidx.lifecycle.Observer {
+ detailsViewModel.getArtistInfo().observe(viewLifecycleOwner, Observer {
artistInfo(it)
})
- setupRecyclerView()
+
playAction.apply {
setOnClickListener { MusicPlayerRemote.openQueue(artist.songs, 0, true) }
}
@@ -127,13 +91,13 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder {
}
private fun setupRecyclerView() {
- albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), null)
+ albumAdapter = HorizontalAlbumAdapter(requireActivity(), ArrayList(), null, this)
albumRecyclerView.apply {
itemAnimator = DefaultItemAnimator()
layoutManager = GridLayoutManager(this.context, 1, GridLayoutManager.HORIZONTAL, false)
adapter = albumAdapter
}
- songAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song, this)
+ songAdapter = SimpleSongAdapter(requireActivity(), ArrayList(), R.layout.item_song, null)
recyclerView.apply {
itemAnimator = DefaultItemAnimator()
layoutManager = LinearLayoutManager(this.context)
@@ -141,33 +105,16 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder {
}
}
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- super.onActivityResult(requestCode, resultCode, data)
- when (requestCode) {
- REQUEST_CODE_SELECT_IMAGE -> if (resultCode == Activity.RESULT_OK) {
- data?.data?.let {
- CustomArtistImageUtil.getInstance(this).setCustomArtistImage(artist, it)
- }
- }
- else -> if (resultCode == Activity.RESULT_OK) {
- //reload()
- }
- }
- }
-
- fun artist(artist: Artist) {
- if (artist.songs.isEmpty()) {
- finish()
- }
+ fun showArtist(artist: Artist) {
this.artist = artist
loadArtistImage(artist)
- if (RetroUtil.isAllowedToDownloadMetadata(this)) {
+ if (RetroUtil.isAllowedToDownloadMetadata(requireContext())) {
loadBiography(artist.name)
}
artistTitle.text = artist.name
text.text = String.format(
"%s • %s",
- MusicUtil.getArtistInfoString(this, artist),
+ MusicUtil.getArtistInfoString(requireContext(), artist),
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(artist.songs))
)
val songText =
@@ -184,7 +131,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder {
)
songTitle.text = songText
albumTitle.text = albumText
- songAdapter.swapDataSet(artist.songs)
+ songAdapter.swapDataSet(artist.songs.sortedBy { it.trackNumber })
artist.albums?.let { albumAdapter.swapDataSet(it) }
}
@@ -224,31 +171,32 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder {
}
}
- private var lang: String? = null
private fun loadArtistImage(artist: Artist) {
- ArtistGlideRequest.Builder.from(Glide.with(this), artist)
- .generatePalette(this).build()
+ ArtistGlideRequest.Builder.from(Glide.with(requireContext()), artist)
+ .generatePalette(requireContext()).build()
.dontAnimate().into(object : RetroMusicColoredTarget(image) {
override fun onColorReady(colors: MediaNotificationProcessor) {
+ startPostponedEnterTransition()
setColors(colors)
}
})
}
private fun setColors(color: MediaNotificationProcessor) {
- MaterialUtil.tintColor(
- button = shuffleAction,
- textColor = color.primaryTextColor,
- backgroundColor = color.backgroundColor
+ shuffleAction.applyColor(color.backgroundColor)
+ playAction.applyColor(color.backgroundColor)
+ }
+
+ override fun onAlbumClick(albumId: Int, view: View) {
+ findNavController().navigate(
+ R.id.albumDetailsFragment,
+ bundleOf("extra_album_id" to albumId),
+ null,
+ FragmentNavigatorExtras(
+ view to getString(R.string.transition_album_art)
+ )
)
- MaterialUtil.tintColor(
- button = playAction,
- textColor = color.primaryTextColor,
- backgroundColor = color.backgroundColor
- )
- setSupportActionBar(toolbar)
- supportActionBar?.title = null
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
@@ -258,10 +206,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder {
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
val songs = artist.songs
when (item.itemId) {
- android.R.id.home -> {
- super.onBackPressed()
- return true
- }
+ android.R.id.home -> findNavController().navigateUp()
R.id.action_play_next -> {
MusicPlayerRemote.playNext(songs)
return true
@@ -271,7 +216,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder {
return true
}
R.id.action_add_to_playlist -> {
- AddToPlaylistDialog.create(songs).show(supportFragmentManager, "ADD_PLAYLIST")
+ AddToPlaylistDialog.create(songs).show(childFragmentManager, "ADD_PLAYLIST")
return true
}
R.id.action_set_artist_image -> {
@@ -284,14 +229,8 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder {
return true
}
R.id.action_reset_artist_image -> {
- Toast.makeText(
- this@ArtistDetailActivity,
- resources.getString(R.string.updating),
- Toast.LENGTH_SHORT
- )
- .show()
- CustomArtistImageUtil.getInstance(this@ArtistDetailActivity)
- .resetCustomArtistImage(artist)
+ showToast(resources.getString(R.string.updating))
+ CustomArtistImageUtil.getInstance(requireContext()).resetCustomArtistImage(artist)
forceDownload = true
return true
}
@@ -299,26 +238,12 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder {
return true
}
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
- menuInflater.inflate(R.menu.menu_artist_detail, menu)
- return super.onCreateOptionsMenu(menu)
- }
-
- override fun onBackPressed() {
- if (cab != null && cab!!.isActive) {
- cab?.finish()
- } else {
- super.onBackPressed()
- }
- }
-
- override fun onDestroy() {
- super.onDestroy()
- removeMusicServiceEventListener(detailsViewModel)
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ super.onCreateOptionsMenu(menu, inflater)
+ inflater.inflate(R.menu.menu_artist_detail, menu)
}
companion object {
- const val EXTRA_ARTIST_ID = "extra_artist_id"
- const val REQUEST_CODE_SELECT_IMAGE = 9003
+ const val REQUEST_CODE_SELECT_IMAGE = 9002
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/artists/ArtistDetailsViewModel.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistDetailsViewModel.kt
similarity index 86%
rename from app/src/main/java/io/github/muntashirakon/music/activities/artists/ArtistDetailsViewModel.kt
rename to app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistDetailsViewModel.kt
index e088921cf..06a6d15e2 100644
--- a/app/src/main/java/io/github/muntashirakon/music/activities/artists/ArtistDetailsViewModel.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistDetailsViewModel.kt
@@ -1,4 +1,4 @@
-package io.github.muntashirakon.music.activities.artists
+package io.github.muntashirakon.music.fragments.artists
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
@@ -6,21 +6,21 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import io.github.muntashirakon.music.interfaces.MusicServiceEventListener
import io.github.muntashirakon.music.model.Artist
-import io.github.muntashirakon.music.providers.RepositoryImpl
import io.github.muntashirakon.music.network.model.LastFmArtist
+import io.github.muntashirakon.music.repository.RealRepository
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
class ArtistDetailsViewModel(
- private val repository: RepositoryImpl,
+ private val realRepository: RealRepository,
private val artistId: Int
) : ViewModel(), MusicServiceEventListener {
private val loadArtistDetailsAsync: Deferred
get() = viewModelScope.async(Dispatchers.IO) {
- repository.artistById(artistId)
+ realRepository.artistById(artistId)
}
private val _artist = MutableLiveData()
@@ -40,7 +40,7 @@ class ArtistDetailsViewModel(
}
fun loadBiography(name: String, lang: String?, cache: String?) = viewModelScope.launch {
- val info = repository.artistInfo(name, lang, cache)
+ val info = realRepository.artistInfo(name, lang, cache)
_lastFmArtist.postValue(info)
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistsFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistsFragment.kt
index 802938b97..bb641ff98 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistsFragment.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistsFragment.kt
@@ -2,10 +2,14 @@ package io.github.muntashirakon.music.fragments.artists
import android.os.Bundle
import android.view.View
+import android.widget.ImageView
+import androidx.core.os.bundleOf
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
+import io.github.muntashirakon.music.EXTRA_ARTIST_ID
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.adapter.artist.ArtistAdapter
+import io.github.muntashirakon.music.extensions.findActivityNavController
import io.github.muntashirakon.music.fragments.ReloadType
import io.github.muntashirakon.music.fragments.base.AbsRecyclerViewCustomGridSizeFragment
import io.github.muntashirakon.music.interfaces.MainActivityFragmentCallbacks
@@ -13,7 +17,7 @@ import io.github.muntashirakon.music.util.PreferenceUtil
class ArtistsFragment :
AbsRecyclerViewCustomGridSizeFragment(),
- MainActivityFragmentCallbacks {
+ MainActivityFragmentCallbacks, ArtistClickListener {
override fun handleBackPress(): Boolean {
return false
@@ -22,14 +26,12 @@ class ArtistsFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- libraryViewModel.artistsLiveData
- .observe(viewLifecycleOwner, Observer { artists ->
- if (artists.isNotEmpty()) {
- adapter?.swapDataSet(artists)
- } else {
- adapter?.swapDataSet(listOf())
- }
- })
+ libraryViewModel.artistsLiveData.observe(viewLifecycleOwner, Observer {
+ if (it.isNotEmpty())
+ adapter?.swapDataSet(it)
+ else
+ adapter?.swapDataSet(listOf())
+ })
}
override val emptyMessage: Int
@@ -46,10 +48,11 @@ class ArtistsFragment :
override fun createAdapter(): ArtistAdapter {
val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet
return ArtistAdapter(
- mainActivity,
+ requireActivity(),
dataSet,
- itemLayoutRes(),
- mainActivity
+ R.layout.item_grid_circle,
+ null,
+ this
)
}
@@ -91,12 +94,18 @@ class ArtistsFragment :
}
companion object {
- @JvmField
- val TAG: String = ArtistsFragment::class.java.simpleName
- @JvmStatic
fun newInstance(): ArtistsFragment {
return ArtistsFragment()
}
}
+
+ override fun onArtist(artistId: Int, imageView: ImageView) {
+ val controller = findActivityNavController(R.id.fragment_container)
+ controller.navigate(R.id.artistDetailsFragment, bundleOf(EXTRA_ARTIST_ID to artistId))
+ }
+}
+
+interface ArtistClickListener {
+ fun onArtist(artistId: Int, imageView: ImageView)
}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsMusicServiceFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsMusicServiceFragment.kt
index 983db8310..bc85842cd 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsMusicServiceFragment.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsMusicServiceFragment.kt
@@ -7,6 +7,8 @@ import android.view.View
import android.webkit.MimeTypeMap
import androidx.annotation.LayoutRes
import androidx.fragment.app.Fragment
+import androidx.navigation.navOptions
+import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.activities.base.AbsMusicServiceActivity
import io.github.muntashirakon.music.interfaces.MusicServiceEventListener
import io.github.muntashirakon.music.model.Song
@@ -23,6 +25,21 @@ import java.util.*
open class AbsMusicServiceFragment(@LayoutRes layout: Int) : Fragment(layout),
MusicServiceEventListener {
+ val navOptions by lazy {
+ navOptions {
+ popUpTo(R.id.action_home) {
+ inclusive = false
+ }
+ launchSingleTop = false
+ anim {
+ enter = R.anim.retro_fragment_open_enter
+ exit = R.anim.retro_fragment_open_exit
+ popEnter = R.anim.retro_fragment_close_enter
+ popExit = R.anim.retro_fragment_close_exit
+ }
+ }
+ }
+
var playerActivity: AbsMusicServiceActivity? = null
private set
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsPlayerFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsPlayerFragment.kt
index 0183592ce..5e3cc98d7 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsPlayerFragment.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsPlayerFragment.kt
@@ -14,6 +14,10 @@ import android.view.View
import android.widget.Toast
import androidx.annotation.LayoutRes
import androidx.appcompat.widget.Toolbar
+import androidx.core.os.bundleOf
+import androidx.navigation.findNavController
+import io.github.muntashirakon.music.EXTRA_ALBUM_ID
+import io.github.muntashirakon.music.EXTRA_ARTIST_ID
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.activities.tageditor.AbsTagEditorActivity
import io.github.muntashirakon.music.activities.tageditor.SongTagEditorActivity
@@ -30,11 +34,8 @@ import kotlinx.android.synthetic.main.shadow_statusbar_toolbar.*
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import java.io.FileNotFoundException
-abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMusicServiceFragment(layout),
- Toolbar.OnMenuItemClickListener,
- PaletteColorHolder,
- PlayerAlbumCoverFragment.Callbacks {
-
+abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragment(layout),
+ Toolbar.OnMenuItemClickListener, PaletteColorHolder, PlayerAlbumCoverFragment.Callbacks {
private var updateIsFavoriteTask: AsyncTask<*, *, *>? = null
private var updateLyricsAsyncTask: AsyncTask<*, *, *>? = null
@@ -86,11 +87,19 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMusicServiceFragme
return true
}
R.id.action_go_to_album -> {
- NavigationUtil.goToAlbum(requireActivity(), song.albumId)
+ mainActivity.collapsePanel()
+ requireActivity().findNavController(R.id.fragment_container).navigate(
+ R.id.albumDetailsFragment,
+ bundleOf(EXTRA_ALBUM_ID to song.albumId)
+ )
return true
}
R.id.action_go_to_artist -> {
- NavigationUtil.goToArtist(requireActivity(), song.artistId)
+ mainActivity.collapsePanel()
+ requireActivity().findNavController(R.id.fragment_container).navigate(
+ R.id.artistDetailsFragment,
+ bundleOf(EXTRA_ARTIST_ID to song.artistId)
+ )
return true
}
R.id.now_playing -> {
@@ -254,11 +263,6 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMusicServiceFragme
statusBarShadow?.hide()
}
- interface Callbacks {
-
- fun onPaletteColorChanged()
- }
-
companion object {
val TAG: String = AbsPlayerFragment::class.java.simpleName
const val VISIBILITY_ANIM_DURATION: Long = 300
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsRecyclerViewFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsRecyclerViewFragment.kt
index 7c6b81e86..8cc11fdbe 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsRecyclerViewFragment.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/base/AbsRecyclerViewFragment.kt
@@ -6,26 +6,24 @@ import android.view.ViewGroup
import androidx.annotation.NonNull
import androidx.annotation.StringRes
import androidx.recyclerview.widget.RecyclerView
+import com.google.android.material.appbar.AppBarLayout
import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.activities.MainActivity
import io.github.muntashirakon.music.fragments.LibraryViewModel
import io.github.muntashirakon.music.helper.MusicPlayerRemote
import io.github.muntashirakon.music.util.DensityUtil
import io.github.muntashirakon.music.util.ThemedFastScroller.create
import io.github.muntashirakon.music.views.ScrollingViewOnApplyWindowInsetsListener
-import com.google.android.material.appbar.AppBarLayout
import kotlinx.android.synthetic.main.fragment_main_activity_recycler_view.*
import me.zhanghai.android.fastscroll.FastScroller
import me.zhanghai.android.fastscroll.FastScrollerBuilder
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
+
abstract class AbsRecyclerViewFragment, LM : RecyclerView.LayoutManager> :
AbsMusicServiceFragment(R.layout.fragment_main_activity_recycler_view),
AppBarLayout.OnOffsetChangedListener {
val libraryViewModel: LibraryViewModel by sharedViewModel()
- val mainActivity: MainActivity
- get() = requireActivity() as MainActivity
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
@@ -38,22 +36,23 @@ abstract class AbsRecyclerViewFragment, LM : Recycle
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- mainActivity.addOnAppBarOffsetChangedListener(this)
initLayoutManager()
initAdapter()
setUpRecyclerView()
}
private fun setUpRecyclerView() {
- recyclerView.layoutManager = layoutManager
- recyclerView.adapter = adapter
- val fastScroller = create(recyclerView)
- recyclerView.setOnApplyWindowInsetsListener(
- ScrollingViewOnApplyWindowInsetsListener(
- recyclerView,
- fastScroller
+ recyclerView.apply {
+ layoutManager = this@AbsRecyclerViewFragment.layoutManager
+ adapter = this@AbsRecyclerViewFragment.adapter
+ val fastScroller = create(this)
+ setOnApplyWindowInsetsListener(
+ ScrollingViewOnApplyWindowInsetsListener(
+ recyclerView,
+ fastScroller
+ )
)
- )
+ }
checkForPadding()
}
@@ -112,7 +111,7 @@ abstract class AbsRecyclerViewFragment, LM : Recycle
container.paddingLeft,
container.paddingTop,
container.paddingRight,
- mainActivity.getTotalAppBarScrollingRange() + i
+ i
)
}
@@ -137,11 +136,6 @@ abstract class AbsRecyclerViewFragment, LM : Recycle
recyclerView.adapter = adapter
}
- override fun onDestroyView() {
- super.onDestroyView()
- mainActivity.removeOnAppBarOffsetChangedListener(this)
- }
-
fun recyclerView(): RecyclerView {
return recyclerView
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/folder/FoldersFragment.java b/app/src/main/java/io/github/muntashirakon/music/fragments/folder/FoldersFragment.java
index eb7b7e2d6..b2415a279 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/folder/FoldersFragment.java
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/folder/FoldersFragment.java
@@ -60,6 +60,7 @@ import io.github.muntashirakon.music.helper.MusicPlayerRemote;
import io.github.muntashirakon.music.helper.menu.SongMenuHelper;
import io.github.muntashirakon.music.helper.menu.SongsMenuHelper;
import io.github.muntashirakon.music.interfaces.CabHolder;
+import io.github.muntashirakon.music.interfaces.Callbacks;
import io.github.muntashirakon.music.interfaces.MainActivityFragmentCallbacks;
import io.github.muntashirakon.music.misc.DialogAsyncTask;
import io.github.muntashirakon.music.misc.UpdateToastMediaScannerCompletionListener;
@@ -76,7 +77,9 @@ import me.zhanghai.android.fastscroll.FastScroller;
public class FoldersFragment extends AbsMainActivityFragment implements
MainActivityFragmentCallbacks,
- CabHolder, BreadCrumbLayout.SelectionCallback, SongFileAdapter.Callbacks,
+ CabHolder,
+ BreadCrumbLayout.SelectionCallback,
+ Callbacks,
LoaderManager.LoaderCallbacks> {
public static final String TAG = FoldersFragment.class.getSimpleName();
@@ -84,7 +87,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
FileUtil.fileIsMimeType(file, "audio/*", MimeTypeMap.getSingleton()) ||
FileUtil.fileIsMimeType(file, "application/opus", MimeTypeMap.getSingleton()) ||
FileUtil.fileIsMimeType(file, "application/ogg", MimeTypeMap.getSingleton()));
- public static final String PATH = "path";
+
private static final String CRUMBS = "crumbs";
private static final int LOADER_ID = 5;
private SongFileAdapter adapter;
@@ -125,18 +128,6 @@ public class FoldersFragment extends AbsMainActivityFragment implements
return startFolder;
}
- public static FoldersFragment newInstance(File directory) {
- FoldersFragment frag = new FoldersFragment();
- Bundle b = new Bundle();
- b.putSerializable(PATH, directory);
- frag.setArguments(b);
- return frag;
- }
-
- public static FoldersFragment newInstance(Context context) {
- return newInstance(PreferenceUtil.INSTANCE.getStartDirectory());
- }
-
private static File tryGetCanonicalFile(File file) {
try {
return file.getCanonicalFile();
@@ -171,7 +162,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
if (savedInstanceState == null) {
//noinspection ConstantConditions
- setCrumb(new BreadCrumbLayout.Crumb(FileUtil.safeGetCanonicalFile((File) requireArguments().getSerializable(PATH))), true);
+ setCrumb(new BreadCrumbLayout.Crumb(FileUtil.safeGetCanonicalFile(PreferenceUtil.INSTANCE.getStartDirectory())), true);
} else {
breadCrumbs.restoreFromStateWrapper(savedInstanceState.getParcelable(CRUMBS));
getLoaderManager().initLoader(LOADER_ID, null, this);
@@ -299,7 +290,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
}
}
if (startIndex > -1) {
- MusicPlayerRemote.INSTANCE.openQueue(songs, startIndex, true);
+ MusicPlayerRemote.openQueue(songs, startIndex, true);
} else {
final File finalFile = file1;
Snackbar.make(coordinatorLayout, Html.fromHtml(
@@ -619,7 +610,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
}
private static class ListSongsAsyncTask
- extends ListingFilesDialogAsyncTask> {
+ extends ListingFilesDialogAsyncTask> {
private final Object extra;
private WeakReference callbackWeakReference;
@@ -633,7 +624,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
}
@Override
- protected ArrayList doInBackground(LoadingInfo... params) {
+ protected List doInBackground(LoadingInfo... params) {
try {
LoadingInfo info = params[0];
List files = FileUtil.listFilesDeep(info.files, info.fileFilter);
@@ -659,7 +650,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
}
@Override
- protected void onPostExecute(ArrayList songs) {
+ protected void onPostExecute(List songs) {
super.onPostExecute(songs);
OnSongsListedCallback callback = checkCallbackReference();
if (songs != null && callback != null) {
@@ -692,7 +683,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
public interface OnSongsListedCallback {
- void onSongsListed(@NonNull ArrayList songs, Object extra);
+ void onSongsListed(@NonNull List songs, Object extra);
}
static class LoadingInfo {
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/genres/GenreDetailsFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/genres/GenreDetailsFragment.kt
new file mode 100644
index 000000000..5b676af48
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/genres/GenreDetailsFragment.kt
@@ -0,0 +1,92 @@
+package io.github.muntashirakon.music.fragments.genres
+
+import android.os.Bundle
+import android.view.Menu
+import android.view.MenuInflater
+import android.view.MenuItem
+import android.view.View
+import androidx.navigation.fragment.navArgs
+import androidx.recyclerview.widget.DefaultItemAnimator
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import io.github.muntashirakon.music.R
+import io.github.muntashirakon.music.adapter.song.SongAdapter
+import io.github.muntashirakon.music.extensions.dipToPix
+import io.github.muntashirakon.music.fragments.base.AbsMainActivityFragment
+import io.github.muntashirakon.music.helper.menu.GenreMenuHelper
+import io.github.muntashirakon.music.model.Genre
+import io.github.muntashirakon.music.model.Song
+import kotlinx.android.synthetic.main.fragment_playlist_detail.*
+import org.koin.androidx.viewmodel.ext.android.viewModel
+import org.koin.core.parameter.parametersOf
+import java.util.*
+
+class GenreDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_detail) {
+ private val arguments by navArgs()
+ private val detailsViewModel: GenreDetailsViewModel by viewModel {
+ parametersOf(arguments.extraGenre)
+ }
+
+ private lateinit var genre: Genre
+ private lateinit var songAdapter: SongAdapter
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ setHasOptionsMenu(true)
+ mainActivity.addMusicServiceEventListener(detailsViewModel)
+ mainActivity.setSupportActionBar(toolbar)
+ mainActivity.hideBottomBarVisibility(false)
+
+ setupRecyclerView()
+ detailsViewModel.getSongs().observe(viewLifecycleOwner, androidx.lifecycle.Observer {
+ songs(it)
+ })
+ detailsViewModel.getGenre().observe(viewLifecycleOwner, androidx.lifecycle.Observer {
+ genre = it
+ toolbar?.title = it.name
+ })
+ }
+
+ private fun setupRecyclerView() {
+ songAdapter = SongAdapter(requireActivity(), ArrayList(), R.layout.item_list, null)
+ recyclerView.apply {
+ itemAnimator = DefaultItemAnimator()
+ layoutManager = LinearLayoutManager(requireContext())
+ adapter = songAdapter
+ }
+ songAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
+ override fun onChanged() {
+ super.onChanged()
+ checkIsEmpty()
+ }
+ })
+ }
+
+ fun songs(songs: List) {
+ songAdapter.swapDataSet(songs)
+ }
+
+ private fun getEmojiByUnicode(unicode: Int): String {
+ return String(Character.toChars(unicode))
+ }
+
+ private fun checkIsEmpty() {
+ checkForPadding()
+ emptyEmoji.text = getEmojiByUnicode(0x1F631)
+ empty?.visibility = if (songAdapter.itemCount == 0) View.VISIBLE else View.GONE
+ }
+
+ private fun checkForPadding() {
+ val height = dipToPix(52f).toInt()
+ recyclerView.setPadding(0, 0, 0, height)
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ super.onCreateOptionsMenu(menu, inflater)
+ inflater.inflate(R.menu.menu_genre_detail, menu)
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ return GenreMenuHelper.handleMenuClick(requireActivity(), genre, item)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/genre/GenreDetailsViewModel.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/genres/GenreDetailsViewModel.kt
similarity index 86%
rename from app/src/main/java/io/github/muntashirakon/music/activities/genre/GenreDetailsViewModel.kt
rename to app/src/main/java/io/github/muntashirakon/music/fragments/genres/GenreDetailsViewModel.kt
index 4d56466cc..1b1331f62 100644
--- a/app/src/main/java/io/github/muntashirakon/music/activities/genre/GenreDetailsViewModel.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/genres/GenreDetailsViewModel.kt
@@ -1,4 +1,4 @@
-package io.github.muntashirakon.music.activities.genre
+package io.github.muntashirakon.music.fragments.genres
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
@@ -7,13 +7,13 @@ import androidx.lifecycle.viewModelScope
import io.github.muntashirakon.music.interfaces.MusicServiceEventListener
import io.github.muntashirakon.music.model.Genre
import io.github.muntashirakon.music.model.Song
-import io.github.muntashirakon.music.providers.RepositoryImpl
+import io.github.muntashirakon.music.repository.RealRepository
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class GenreDetailsViewModel(
- private val repository: RepositoryImpl,
+ private val realRepository: RealRepository,
private val genre: Genre
) : ViewModel(), MusicServiceEventListener {
@@ -31,7 +31,7 @@ class GenreDetailsViewModel(
}
private fun loadGenreSongs(genre: Genre) = viewModelScope.launch {
- val songs = repository.getGenre(genre.id)
+ val songs = realRepository.getGenre(genre.id)
withContext(Main) { _playListSongs.postValue(songs) }
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/genres/GenresFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/genres/GenresFragment.kt
index b97093312..a4f623639 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/genres/GenresFragment.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/genres/GenresFragment.kt
@@ -32,14 +32,12 @@ class GenresFragment : AbsRecyclerViewFragment
- if (genres.isNotEmpty()) {
- adapter?.swapDataSet(genres)
- } else {
- adapter?.swapDataSet(listOf())
- }
- })
+ libraryViewModel.genresLiveData.observe(viewLifecycleOwner, Observer {
+ if (it.isNotEmpty())
+ adapter?.swapDataSet(it)
+ else
+ adapter?.swapDataSet(listOf())
+ })
}
@@ -49,7 +47,7 @@ class GenresFragment : AbsRecyclerViewFragment()
private val libraryViewModel: LibraryViewModel by sharedViewModel()
private val displayMetrics: DisplayMetrics
@@ -60,9 +62,7 @@ class BannerHomeFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
-
setStatusBarColorAuto(view)
-
bannerImage?.setOnClickListener {
val options = ActivityOptions.makeSceneTransitionAnimation(
mainActivity,
@@ -73,22 +73,33 @@ class BannerHomeFragment :
}
lastAdded.setOnClickListener {
- NavigationUtil.goToPlaylistNew(requireActivity(), LastAddedPlaylist(requireActivity()))
+ findActivityNavController(R.id.fragment_container).navigate(
+ R.id.playlistDetailsFragment,
+ bundleOf(EXTRA_PLAYLIST to LastAddedPlaylist())
+ )
}
topPlayed.setOnClickListener {
- NavigationUtil.goToPlaylistNew(
- requireActivity(),
- MyTopTracksPlaylist(requireActivity())
+ findActivityNavController(R.id.fragment_container).navigate(
+ R.id.playlistDetailsFragment,
+ bundleOf(EXTRA_PLAYLIST to TopTracksPlaylist())
)
}
actionShuffle.setOnClickListener {
- MusicPlayerRemote.openAndShuffleQueue(SongLoader.getAllSongs(requireActivity()), true)
+ lifecycleScope.launch {
+ MusicPlayerRemote.openAndShuffleQueue(
+ repository.allSongs(),
+ true
+ )
+ }
}
history.setOnClickListener {
- NavigationUtil.goToPlaylistNew(requireActivity(), HistoryPlaylist(requireActivity()))
+ requireActivity().findNavController(R.id.fragment_container).navigate(
+ R.id.playlistDetailsFragment,
+ bundleOf(EXTRA_PLAYLIST to HistoryPlaylist())
+ )
}
userImage.setOnClickListener {
@@ -101,16 +112,15 @@ class BannerHomeFragment :
}
titleWelcome?.text = String.format("%s", PreferenceUtil.userName)
- val homeAdapter = HomeAdapter(mainActivity, displayMetrics)
+ val homeAdapter = HomeAdapter(mainActivity)
recyclerView.apply {
layoutManager = LinearLayoutManager(mainActivity)
adapter = homeAdapter
}
- libraryViewModel.homeLiveData
- .observe(viewLifecycleOwner, Observer { sections ->
- homeAdapter.swapData(sections)
- })
+ libraryViewModel.homeLiveData.observe(viewLifecycleOwner, Observer {
+ homeAdapter.swapData(it)
+ })
loadProfile()
}
@@ -133,8 +143,8 @@ class BannerHomeFragment :
const val TAG: String = "BannerHomeFragment"
@JvmStatic
- fun newInstance(): BannerHomeFragment {
- return BannerHomeFragment()
+ fun newInstance(): HomeFragment {
+ return HomeFragment()
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/library/LibraryFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/library/LibraryFragment.kt
new file mode 100644
index 000000000..7243bb12f
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/library/LibraryFragment.kt
@@ -0,0 +1,78 @@
+package io.github.muntashirakon.music.fragments.library
+
+import android.os.Bundle
+import android.view.Menu
+import android.view.MenuInflater
+import android.view.MenuItem
+import androidx.navigation.fragment.findNavController
+import androidx.navigation.ui.NavigationUI
+import code.name.monkey.appthemehelper.common.ATHToolbarActivity.getToolbarBackgroundColor
+import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
+import com.google.android.material.appbar.AppBarLayout
+import io.github.muntashirakon.music.R
+import io.github.muntashirakon.music.extensions.findNavController
+import io.github.muntashirakon.music.fragments.base.AbsMainActivityFragment
+import kotlinx.android.synthetic.main.fragment_library.*
+
+class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ setHasOptionsMenu(true)
+ mainActivity.hideBottomBarVisibility(true)
+ mainActivity.setSupportActionBar(toolbar)
+ mainActivity.supportActionBar?.title = null
+ toolbar.setNavigationOnClickListener {
+ findNavController().navigate(
+ R.id.searchFragment,
+ null,
+ navOptions
+ )
+ }
+ setupNavigationController()
+ }
+
+ private fun setupNavigationController() {
+ val navController = findNavController(R.id.fragment_container)
+ NavigationUI.setupWithNavController(mainActivity.getBottomNavigationView(), navController)
+ }
+
+ override fun onPrepareOptionsMenu(menu: Menu) {
+ super.onPrepareOptionsMenu(menu)
+ ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), toolbar)
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ super.onCreateOptionsMenu(menu, inflater)
+ inflater.inflate(R.menu.menu_main, menu)
+ ToolbarContentTintHelper.handleOnCreateOptionsMenu(
+ requireContext(),
+ toolbar,
+ menu,
+ getToolbarBackgroundColor(toolbar)
+ )
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ when (item.itemId) {
+ R.id.action_settings -> findNavController().navigate(
+ R.id.settingsActivity,
+ null,
+ navOptions
+ )
+ }
+ return super.onOptionsItemSelected(item)
+ }
+
+ fun addOnAppBarOffsetChangedListener(changedListener: AppBarLayout.OnOffsetChangedListener) {
+ appBarLayout.addOnOffsetChangedListener(changedListener)
+ }
+
+ fun removeOnAppBarOffsetChangedListener(changedListener: AppBarLayout.OnOffsetChangedListener) {
+ appBarLayout.removeOnOffsetChangedListener(changedListener)
+ }
+
+ fun getTotalAppBarScrollingRange(): Int {
+ return 0
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/player/NowPlayingPlayerFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/player/NowPlayingPlayerFragment.kt
index a86757726..0f7a6c1a7 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/player/NowPlayingPlayerFragment.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/player/NowPlayingPlayerFragment.kt
@@ -4,7 +4,7 @@ import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.extensions.navController
+import io.github.muntashirakon.music.extensions.findNavController
import io.github.muntashirakon.music.fragments.NowPlayingScreen.*
import io.github.muntashirakon.music.util.PreferenceUtil
@@ -15,7 +15,7 @@ class NowPlayingPlayerFragment : Fragment(R.layout.fragment_now_playing_player)
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
- val navController = navController(R.id.playerFragmentContainer)
+ val navController = findNavController(R.id.playerFragmentContainer)
updateNowPlaying(navController)
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/player/PlayerAlbumCoverFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/player/PlayerAlbumCoverFragment.kt
index de479a092..07869bdbb 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/player/PlayerAlbumCoverFragment.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/player/PlayerAlbumCoverFragment.kt
@@ -18,6 +18,7 @@ import kotlinx.android.synthetic.main.fragment_player_album_cover.*
class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_player_album_cover),
ViewPager.OnPageChangeListener {
+
private var callbacks: Callbacks? = null
private var currentPosition: Int = 0
private val colorReceiver = object : AlbumCoverFragment.ColorReceiver {
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/player/full/FullPlayerFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/player/full/FullPlayerFragment.kt
index cf14b3b54..35085a08a 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/player/full/FullPlayerFragment.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/player/full/FullPlayerFragment.kt
@@ -1,6 +1,5 @@
package io.github.muntashirakon.music.fragments.player.full
-import android.app.ActivityOptions
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
@@ -8,31 +7,36 @@ import android.view.View
import android.widget.FrameLayout
import android.widget.TextView
import androidx.appcompat.widget.Toolbar
+import androidx.core.os.bundleOf
+import androidx.lifecycle.lifecycleScope
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
+import com.bumptech.glide.Glide
+import io.github.muntashirakon.music.EXTRA_ARTIST_ID
import io.github.muntashirakon.music.R
+import io.github.muntashirakon.music.extensions.findActivityNavController
import io.github.muntashirakon.music.extensions.hide
import io.github.muntashirakon.music.extensions.show
+import io.github.muntashirakon.music.extensions.whichFragment
import io.github.muntashirakon.music.fragments.base.AbsPlayerFragment
import io.github.muntashirakon.music.fragments.player.PlayerAlbumCoverFragment
import io.github.muntashirakon.music.glide.ArtistGlideRequest
import io.github.muntashirakon.music.glide.RetroMusicColoredTarget
import io.github.muntashirakon.music.helper.MusicPlayerRemote
import io.github.muntashirakon.music.helper.MusicProgressViewUpdateHelper
-import io.github.muntashirakon.music.loaders.ArtistLoader
import io.github.muntashirakon.music.model.Song
import io.github.muntashirakon.music.model.lyrics.AbsSynchronizedLyrics
import io.github.muntashirakon.music.model.lyrics.Lyrics
-import io.github.muntashirakon.music.util.NavigationUtil
+import io.github.muntashirakon.music.repository.ArtistRepository
import io.github.muntashirakon.music.util.color.MediaNotificationProcessor
-import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_full.*
-import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
+import org.koin.android.ext.android.inject
class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full),
MusicProgressViewUpdateHelper.Callback {
+ private val artistRepository by inject()
private lateinit var lyricsLayout: FrameLayout
private lateinit var lyricsLine1: TextView
private lateinit var lyricsLine2: TextView
@@ -150,30 +154,20 @@ class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full),
private fun setupArtist() {
artistImage.setOnClickListener {
- val transitionName =
- "${getString(R.string.transition_artist_image)}_${MusicPlayerRemote.currentSong.artistId}"
- val activityOptions =
- ActivityOptions.makeSceneTransitionAnimation(
- requireActivity(),
- artistImage,
- transitionName
+ mainActivity.collapsePanel()
+ findActivityNavController(R.id.fragment_container)
+ .navigate(
+ R.id.artistDetailsFragment,
+ bundleOf(EXTRA_ARTIST_ID to MusicPlayerRemote.currentSong.artistId)
)
- NavigationUtil.goToArtistOptions(
- requireActivity(),
- MusicPlayerRemote.currentSong.artistId,
- activityOptions
- )
}
}
private fun setUpSubFragments() {
- controlsFragment =
- childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as FullPlaybackControlsFragment
-
- val playerAlbumCoverFragment =
- childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
- playerAlbumCoverFragment.setCallbacks(this)
- playerAlbumCoverFragment.removeSlideEffect()
+ controlsFragment = whichFragment(R.id.playbackControlsFragment)
+ val coverFragment: PlayerAlbumCoverFragment = whichFragment(R.id.playerAlbumCoverFragment)
+ coverFragment.setCallbacks(this)
+ coverFragment.removeSlideEffect()
}
override fun onShow() {
@@ -228,9 +222,8 @@ class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full),
}
private fun updateArtistImage() {
- CoroutineScope(Dispatchers.IO).launch {
- val artist =
- ArtistLoader.getArtist(requireContext(), MusicPlayerRemote.currentSong.artistId)
+ lifecycleScope.launch {
+ val artist = artistRepository.artist(MusicPlayerRemote.currentSong.artistId)
withContext(Dispatchers.Main) {
ArtistGlideRequest.Builder.from(Glide.with(requireContext()), artist)
.generatePalette(requireContext())
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/player/normal/PlayerPlaybackControlsFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/player/normal/PlayerPlaybackControlsFragment.kt
index cee4d785b..d1f68f4fd 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/player/normal/PlayerPlaybackControlsFragment.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/player/normal/PlayerPlaybackControlsFragment.kt
@@ -52,7 +52,7 @@ class PlayerPlaybackControlsFragment :
showBonceAnimation(playPauseButton)
}
title.isSelected = true
-
+ text.isSelected = true
}
override fun setColor(color: MediaNotificationProcessor) {
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/playlist/PlaylistDetailActivity.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/playlists/PlaylistDetailsFragment.kt
similarity index 55%
rename from app/src/main/java/io/github/muntashirakon/music/activities/playlist/PlaylistDetailActivity.kt
rename to app/src/main/java/io/github/muntashirakon/music/fragments/playlists/PlaylistDetailsFragment.kt
index 42039753d..26b27d5bf 100644
--- a/app/src/main/java/io/github/muntashirakon/music/activities/playlist/PlaylistDetailActivity.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/playlists/PlaylistDetailsFragment.kt
@@ -1,95 +1,81 @@
-package io.github.muntashirakon.music.activities.playlist
+package io.github.muntashirakon.music.fragments.playlists
import android.os.Bundle
import android.view.Menu
+import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.lifecycle.Observer
+import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
-import code.name.monkey.appthemehelper.util.ATHUtil
-
-import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.activities.base.AbsSlidingMusicPanelActivity
-import io.github.muntashirakon.music.adapter.song.OrderablePlaylistSongAdapter
-import io.github.muntashirakon.music.adapter.song.PlaylistSongAdapter
-import io.github.muntashirakon.music.adapter.song.SongAdapter
-import io.github.muntashirakon.music.extensions.applyToolbar
-import io.github.muntashirakon.music.extensions.extraNotNull
-import io.github.muntashirakon.music.helper.menu.PlaylistMenuHelper
-import io.github.muntashirakon.music.interfaces.CabHolder
-import io.github.muntashirakon.music.model.AbsCustomPlaylist
-import io.github.muntashirakon.music.model.Playlist
-import io.github.muntashirakon.music.model.Song
-import io.github.muntashirakon.music.util.DensityUtil
-import io.github.muntashirakon.music.util.PlaylistsUtil
-import io.github.muntashirakon.music.util.RetroColorUtil
-import com.afollestad.materialcab.MaterialCab
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
-import kotlinx.android.synthetic.main.activity_playlist_detail.*
+import io.github.muntashirakon.music.R
+import io.github.muntashirakon.music.adapter.song.OrderablePlaylistSongAdapter
+import io.github.muntashirakon.music.adapter.song.SongAdapter
+import io.github.muntashirakon.music.extensions.dipToPix
+import io.github.muntashirakon.music.fragments.base.AbsMainActivityFragment
+import io.github.muntashirakon.music.helper.menu.PlaylistMenuHelper
+import io.github.muntashirakon.music.model.AbsCustomPlaylist
+import io.github.muntashirakon.music.model.Playlist
+import io.github.muntashirakon.music.model.Song
+import io.github.muntashirakon.music.util.PlaylistsUtil
+import kotlinx.android.synthetic.main.fragment_playlist_detail.*
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
-
-class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder {
-
-
+class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_detail) {
+ private val arguments by navArgs()
private val viewModel: PlaylistDetailsViewModel by viewModel {
- parametersOf(extraNotNull(EXTRA_PLAYLIST).value)
+ parametersOf(arguments.extraPlaylist)
}
+
private lateinit var playlist: Playlist
- private var cab: MaterialCab? = null
private lateinit var adapter: SongAdapter
+
private var wrappedAdapter: RecyclerView.Adapter<*>? = null
private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null
- override fun onCreate(savedInstanceState: Bundle?) {
- setDrawUnderStatusBar()
- super.onCreate(savedInstanceState)
- setStatusbarColorAuto()
- setNavigationbarColorAuto()
- setTaskDescriptionColorAuto()
- setLightNavigationBar(true)
- setBottomBarVisibility(View.GONE)
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ setHasOptionsMenu(true)
+ mainActivity.addMusicServiceEventListener(viewModel)
+ mainActivity.setSupportActionBar(toolbar)
+ mainActivity.hideBottomBarVisibility(false)
- playlist = extraNotNull(EXTRA_PLAYLIST).value
+ playlist = arguments.extraPlaylist
- setUpToolBar()
setUpRecyclerView()
- viewModel.getSongs().observe(this, Observer {
+ viewModel.getSongs().observe(viewLifecycleOwner, Observer {
songs(it)
})
- viewModel.getPlaylist().observe(this, Observer {
+ viewModel.getPlaylist().observe(viewLifecycleOwner, Observer {
playlist = it
- supportActionBar?.title = it.name
+ toolbar.title = it.name
})
- addMusicServiceEventListener(viewModel)
- }
-
- override fun createContentView(): View {
- return wrapSlidingMusicPanel(R.layout.activity_playlist_detail)
}
private fun setUpRecyclerView() {
- recyclerView.layoutManager = LinearLayoutManager(this)
+ recyclerView.layoutManager = LinearLayoutManager(requireContext())
if (playlist is AbsCustomPlaylist) {
- adapter = PlaylistSongAdapter(this, ArrayList(), R.layout.item_list, this)
+ adapter = SongAdapter(requireActivity(), ArrayList(), R.layout.item_list, null)
recyclerView.adapter = adapter
} else {
recyclerViewDragDropManager = RecyclerViewDragDropManager()
val animator = RefactoredDefaultItemAnimator()
- adapter = OrderablePlaylistSongAdapter(this,
+ adapter = OrderablePlaylistSongAdapter(
+ requireActivity(),
ArrayList(),
R.layout.item_list,
- this,
+ null,
object : OrderablePlaylistSongAdapter.OnMoveItemListener {
override fun onMoveItem(fromPosition: Int, toPosition: Int) {
if (PlaylistsUtil.moveItem(
- this@PlaylistDetailActivity,
+ requireContext(),
playlist.id,
fromPosition,
toPosition
@@ -116,58 +102,21 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder {
})
}
- private fun setUpToolBar() {
- applyToolbar(toolbar)
- title = playlist.name
- }
-
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
- menuInflater.inflate(
- if (playlist is AbsCustomPlaylist) R.menu.menu_smart_playlist_detail
- else R.menu.menu_playlist_detail, menu
- )
- return super.onCreateOptionsMenu(menu)
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ super.onCreateOptionsMenu(menu, inflater)
+ val menuRes = if (playlist is AbsCustomPlaylist)
+ R.menu.menu_smart_playlist_detail
+ else R.menu.menu_playlist_detail
+ inflater.inflate(menuRes, menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
- when (item.itemId) {
- android.R.id.home -> {
- onBackPressed()
- return true
- }
- }
- return PlaylistMenuHelper.handleMenuClick(this, playlist, item)
- }
-
- override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
- if (cab != null && cab!!.isActive) {
- cab!!.finish()
- }
- cab = MaterialCab(this, R.id.cab_stub).setMenu(menuRes)
- .setCloseDrawableRes(R.drawable.ic_close)
- .setBackgroundColor(
- RetroColorUtil.shiftBackgroundColorForLightText(
- ATHUtil.resolveColor(
- this,
- R.attr.colorSurface
- )
- )
- ).start(callback)
- return cab!!
- }
-
- override fun onBackPressed() {
- if (cab != null && cab!!.isActive) {
- cab!!.finish()
- } else {
- recyclerView!!.stopScroll()
- super.onBackPressed()
- }
+ return PlaylistMenuHelper.handleMenuClick(requireActivity(), playlist, item)
}
private fun checkForPadding() {
- val height = DensityUtil.dip2px(this, 52f)
- recyclerView.setPadding(0, 0, 0, (height))
+ val height = dipToPix(52f)
+ recyclerView.setPadding(0, 0, 0, height.toInt())
}
private fun checkIsEmpty() {
@@ -181,7 +130,7 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder {
return String(Character.toChars(unicode))
}
- public override fun onPause() {
+ override fun onPause() {
if (recyclerViewDragDropManager != null) {
recyclerViewDragDropManager!!.cancelDrag()
}
@@ -206,7 +155,7 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder {
super.onDestroy()
}
- fun showEmptyView() {
+ private fun showEmptyView() {
empty.visibility = View.VISIBLE
emptyText.visibility = View.VISIBLE
}
@@ -219,7 +168,4 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder {
}
}
- companion object {
- var EXTRA_PLAYLIST = "extra_playlist"
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/playlist/PlaylistDetailsViewModel.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/playlists/PlaylistDetailsViewModel.kt
similarity index 83%
rename from app/src/main/java/io/github/muntashirakon/music/activities/playlist/PlaylistDetailsViewModel.kt
rename to app/src/main/java/io/github/muntashirakon/music/fragments/playlists/PlaylistDetailsViewModel.kt
index 830388fea..253208a78 100644
--- a/app/src/main/java/io/github/muntashirakon/music/activities/playlist/PlaylistDetailsViewModel.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/playlists/PlaylistDetailsViewModel.kt
@@ -1,4 +1,4 @@
-package io.github.muntashirakon.music.activities.playlist
+package io.github.muntashirakon.music.fragments.playlists
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
@@ -6,22 +6,20 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import io.github.muntashirakon.music.App
import io.github.muntashirakon.music.interfaces.MusicServiceEventListener
-import io.github.muntashirakon.music.loaders.PlaylistLoader
import io.github.muntashirakon.music.model.AbsCustomPlaylist
import io.github.muntashirakon.music.model.Playlist
import io.github.muntashirakon.music.model.Song
-import io.github.muntashirakon.music.providers.RepositoryImpl
+import io.github.muntashirakon.music.repository.RealRepository
import io.github.muntashirakon.music.util.PlaylistsUtil
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class PlaylistDetailsViewModel(
- private val repository: RepositoryImpl,
+ private val realRepository: RealRepository,
private var playlist: Playlist
) : ViewModel(), MusicServiceEventListener {
private val _playListSongs = MutableLiveData>()
-
private val _playlist = MutableLiveData().apply {
postValue(playlist)
}
@@ -35,7 +33,7 @@ class PlaylistDetailsViewModel(
}
private fun loadPlaylistSongs(playlist: Playlist) = viewModelScope.launch {
- val songs = repository.getPlaylistSongs(playlist)
+ val songs = realRepository.getPlaylistSongs(playlist)
withContext(Main) { _playListSongs.postValue(songs) }
}
@@ -50,8 +48,10 @@ class PlaylistDetailsViewModel(
val playlistName =
PlaylistsUtil.getNameForPlaylist(App.getContext(), playlist.id.toLong())
if (playlistName != playlist.name) {
- playlist = PlaylistLoader.getPlaylist(App.getContext(), playlist.id)
- _playlist.postValue(playlist)
+ viewModelScope.launch {
+ playlist = realRepository.playlist(playlist.id)
+ _playlist.postValue(playlist)
+ }
}
}
loadPlaylistSongs(playlist)
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/playlists/PlaylistsFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/playlists/PlaylistsFragment.kt
index a88d95468..10bc589d6 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/playlists/PlaylistsFragment.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/playlists/PlaylistsFragment.kt
@@ -1,8 +1,6 @@
package io.github.muntashirakon.music.fragments.playlists
import android.os.Bundle
-import android.view.Menu
-import android.view.MenuInflater
import android.view.View
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
@@ -12,7 +10,7 @@ import io.github.muntashirakon.music.fragments.base.AbsRecyclerViewFragment
import io.github.muntashirakon.music.interfaces.MainActivityFragmentCallbacks
class PlaylistsFragment :
- AbsRecyclerViewFragment() ,
+ AbsRecyclerViewFragment(),
MainActivityFragmentCallbacks {
override fun handleBackPress(): Boolean {
@@ -21,12 +19,11 @@ class PlaylistsFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- libraryViewModel.playlisitsLiveData.observe(viewLifecycleOwner, Observer { playlists ->
- if (playlists.isNotEmpty()) {
- adapter?.swapDataSet(playlists)
- } else {
+ libraryViewModel.playlisitsLiveData.observe(viewLifecycleOwner, Observer {
+ if (it.isNotEmpty())
+ adapter?.swapDataSet(it)
+ else
adapter?.swapDataSet(listOf())
- }
})
}
@@ -39,26 +36,14 @@ class PlaylistsFragment :
override fun createAdapter(): PlaylistAdapter {
return PlaylistAdapter(
- mainActivity,
+ requireActivity(),
ArrayList(),
R.layout.item_list,
- mainActivity
+ null
)
}
- override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
- super.onCreateOptionsMenu(menu, inflater)
- menu.apply {
- removeItem(R.id.action_sort_order)
- removeItem(R.id.action_grid_size)
- }
- }
-
companion object {
- @JvmField
- val TAG: String = PlaylistsFragment::class.java.simpleName
-
- @JvmStatic
fun newInstance(): PlaylistsFragment {
return PlaylistsFragment()
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/search/SearchFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/search/SearchFragment.kt
new file mode 100644
index 000000000..8db443002
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/search/SearchFragment.kt
@@ -0,0 +1,143 @@
+package io.github.muntashirakon.music.fragments.search
+
+import android.content.ActivityNotFoundException
+import android.content.Intent
+import android.os.Bundle
+import android.speech.RecognizerIntent
+import android.text.Editable
+import android.text.TextWatcher
+import android.view.View
+import android.view.inputmethod.InputMethodManager
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat.getSystemService
+import androidx.core.view.isGone
+import androidx.core.view.isVisible
+import androidx.lifecycle.Observer
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import androidx.transition.TransitionManager
+import com.google.android.material.textfield.TextInputEditText
+import io.github.muntashirakon.music.R
+import io.github.muntashirakon.music.adapter.SearchAdapter
+import io.github.muntashirakon.music.extensions.accentColor
+import io.github.muntashirakon.music.extensions.showToast
+import io.github.muntashirakon.music.fragments.base.AbsMainActivityFragment
+import kotlinx.android.synthetic.main.fragment_search.*
+import org.koin.android.ext.android.inject
+import java.util.*
+import kotlin.collections.ArrayList
+
+class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWatcher {
+ companion object {
+ const val QUERY = "query"
+ const val REQ_CODE_SPEECH_INPUT = 9001
+ }
+
+ private val viewModel: SearchViewModel by inject()
+ private lateinit var searchAdapter: SearchAdapter
+ private var query: String? = null
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ mainActivity.setSupportActionBar(toolbar)
+ mainActivity.hideBottomBarVisibility(false)
+
+ setupRecyclerView()
+ keyboardPopup.accentColor()
+ searchView.addTextChangedListener(this)
+ voiceSearch.setOnClickListener { startMicSearch() }
+ clearText.setOnClickListener { searchView.clearText() }
+ keyboardPopup.setOnClickListener {
+ val inputManager =
+ getSystemService(
+ requireContext(),
+ InputMethodManager::class.java
+ )
+ inputManager?.showSoftInput(searchView, InputMethodManager.SHOW_IMPLICIT)
+ }
+
+ if (savedInstanceState != null) {
+ query = savedInstanceState.getString(QUERY)
+ }
+
+ viewModel.getSearchResult().observe(viewLifecycleOwner, Observer {
+ showData(it)
+ })
+ }
+
+ private fun showData(data: MutableList) {
+ if (data.isNotEmpty()) {
+ searchAdapter.swapDataSet(data)
+ } else {
+ searchAdapter.swapDataSet(ArrayList())
+ }
+ }
+
+
+ private fun setupRecyclerView() {
+ searchAdapter = SearchAdapter(requireActivity() as AppCompatActivity, emptyList())
+ searchAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
+ override fun onChanged() {
+ super.onChanged()
+ empty.isVisible = searchAdapter.itemCount < 1
+ }
+ })
+ recyclerView.apply {
+ layoutManager = LinearLayoutManager(requireContext())
+ adapter = searchAdapter
+ addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+ super.onScrolled(recyclerView, dx, dy)
+ if (dy > 0) {
+ keyboardPopup.shrink()
+ } else if (dy < 0) {
+ keyboardPopup.extend()
+ }
+ }
+ })
+ }
+ }
+
+ override fun afterTextChanged(newText: Editable?) {
+ search(newText.toString())
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+
+ }
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+
+ }
+
+ private fun search(query: String) {
+ this.query = query
+ TransitionManager.beginDelayedTransition(appBarLayout)
+ voiceSearch.isGone = query.isNotEmpty()
+ clearText.isVisible = query.isNotEmpty()
+ viewModel.search(query)
+ }
+
+ private fun startMicSearch() {
+ val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
+ intent.putExtra(
+ RecognizerIntent.EXTRA_LANGUAGE_MODEL,
+ RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
+ )
+ intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault())
+ intent.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.speech_prompt))
+ try {
+ startActivityForResult(
+ intent,
+ REQ_CODE_SPEECH_INPUT
+ )
+ } catch (e: ActivityNotFoundException) {
+ e.printStackTrace()
+ showToast(getString(R.string.speech_not_supported))
+ }
+ }
+}
+
+fun TextInputEditText.clearText() {
+ text = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/search/SearchViewModel.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/search/SearchViewModel.kt
similarity index 69%
rename from app/src/main/java/io/github/muntashirakon/music/activities/search/SearchViewModel.kt
rename to app/src/main/java/io/github/muntashirakon/music/fragments/search/SearchViewModel.kt
index 9431b638c..fdf8a287a 100644
--- a/app/src/main/java/io/github/muntashirakon/music/activities/search/SearchViewModel.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/search/SearchViewModel.kt
@@ -1,22 +1,22 @@
-package io.github.muntashirakon.music.activities.search
+package io.github.muntashirakon.music.fragments.search
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import io.github.muntashirakon.music.providers.RepositoryImpl
+import io.github.muntashirakon.music.repository.RealRepository
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
-class SearchViewModel(private val repository: RepositoryImpl) : ViewModel() {
+class SearchViewModel(private val realRepository: RealRepository) : ViewModel() {
private val results = MutableLiveData>()
fun getSearchResult(): LiveData> = results
fun search(query: String?) = viewModelScope.launch(IO) {
- val result = repository.search(query)
+ val result = realRepository.search(query)
withContext(Main) { results.postValue(result) }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/settings/MainSettingsFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/settings/MainSettingsFragment.kt
index cd65d5e7b..603773f90 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/settings/MainSettingsFragment.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/settings/MainSettingsFragment.kt
@@ -14,17 +14,13 @@
package io.github.muntashirakon.music.fragments.settings
-import android.content.res.ColorStateList
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.annotation.StringRes
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.activities.SettingsActivity
-import io.github.muntashirakon.music.util.NavigationUtil
import kotlinx.android.synthetic.main.fragment_main_settings.*
class MainSettingsFragment : Fragment(), View.OnClickListener {
@@ -60,12 +56,4 @@ class MainSettingsFragment : Fragment(), View.OnClickListener {
otherSettings.setOnClickListener(this)
aboutSettings.setOnClickListener(this)
}
-
- companion object {
-
- }
-
- private fun inflateFragment(fragment: Fragment, @StringRes title: Int) {
- (requireActivity() as SettingsActivity).setupFragment(fragment, title)
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/songs/SongsFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/songs/SongsFragment.kt
index 47fbff0a9..f33ca639f 100644
--- a/app/src/main/java/io/github/muntashirakon/music/fragments/songs/SongsFragment.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/fragments/songs/SongsFragment.kt
@@ -1,12 +1,11 @@
package io.github.muntashirakon.music.fragments.songs
import android.os.Bundle
-import android.view.*
+import android.view.View
import androidx.annotation.LayoutRes
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.adapter.song.ShuffleButtonSongAdapter
import io.github.muntashirakon.music.adapter.song.SongAdapter
import io.github.muntashirakon.music.fragments.ReloadType
import io.github.muntashirakon.music.fragments.base.AbsRecyclerViewCustomGridSizeFragment
@@ -24,11 +23,10 @@ class SongsFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
libraryViewModel.songsLiveData.observe(viewLifecycleOwner, Observer {
- if (it.isNotEmpty()) {
+ if (it.isNotEmpty())
adapter?.swapDataSet(it)
- } else {
+ else
adapter?.swapDataSet(listOf())
- }
})
}
@@ -36,26 +34,16 @@ class SongsFragment :
get() = R.string.no_songs
override fun createLayoutManager(): GridLayoutManager {
- return GridLayoutManager(requireActivity(), getGridSize()).apply {
- spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
- override fun getSpanSize(position: Int): Int {
- return if (position == 0) {
- getGridSize()
- } else {
- 1
- }
- }
- }
- }
+ return GridLayoutManager(requireActivity(), getGridSize())
}
override fun createAdapter(): SongAdapter {
val dataSet = if (adapter == null) mutableListOf() else adapter!!.dataSet
- return ShuffleButtonSongAdapter(
- mainActivity,
+ return SongAdapter(
+ requireActivity(),
dataSet,
- itemLayoutRes(),
- mainActivity
+ R.layout.item_list,
+ null
)
}
@@ -109,72 +97,4 @@ class SongsFragment :
return SongsFragment()
}
}
-
- override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
- super.onCreateOptionsMenu(menu, inflater)
- setUpGridSizeMenu(menu.findItem(R.id.action_grid_size).subMenu)
- }
-
- private fun setUpGridSizeMenu(
-
- gridSizeMenu: SubMenu
- ) {
- println(getGridSize())
- when (getGridSize()) {
- 1 -> gridSizeMenu.findItem(R.id.action_grid_size_1).isChecked = true
- 2 -> gridSizeMenu.findItem(R.id.action_grid_size_2).isChecked = true
- 3 -> gridSizeMenu.findItem(R.id.action_grid_size_3).isChecked = true
- 4 -> gridSizeMenu.findItem(R.id.action_grid_size_4).isChecked = true
- 5 -> gridSizeMenu.findItem(R.id.action_grid_size_5).isChecked = true
- 6 -> gridSizeMenu.findItem(R.id.action_grid_size_6).isChecked = true
- 7 -> gridSizeMenu.findItem(R.id.action_grid_size_7).isChecked = true
- 8 -> gridSizeMenu.findItem(R.id.action_grid_size_8).isChecked = true
- }
- val maxGridSize = maxGridSize
- if (maxGridSize < 8) {
- gridSizeMenu.findItem(R.id.action_grid_size_8).isVisible = false
- }
- if (maxGridSize < 7) {
- gridSizeMenu.findItem(R.id.action_grid_size_7).isVisible = false
- }
- if (maxGridSize < 6) {
- gridSizeMenu.findItem(R.id.action_grid_size_6).isVisible = false
- }
- if (maxGridSize < 5) {
- gridSizeMenu.findItem(R.id.action_grid_size_5).isVisible = false
- }
- if (maxGridSize < 4) {
- gridSizeMenu.findItem(R.id.action_grid_size_4).isVisible = false
- }
- if (maxGridSize < 3) {
- gridSizeMenu.findItem(R.id.action_grid_size_3).isVisible = false
- }
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- if (handleGridSizeMenuItem(item)) return true
- return super.onOptionsItemSelected(item)
- }
-
- fun handleGridSizeMenuItem(
- item: MenuItem
- ): Boolean {
- var gridSize = 0
- when (item.itemId) {
- R.id.action_grid_size_1 -> gridSize = 1
- R.id.action_grid_size_2 -> gridSize = 2
- R.id.action_grid_size_3 -> gridSize = 3
- R.id.action_grid_size_4 -> gridSize = 4
- R.id.action_grid_size_5 -> gridSize = 5
- R.id.action_grid_size_6 -> gridSize = 6
- R.id.action_grid_size_7 -> gridSize = 7
- R.id.action_grid_size_8 -> gridSize = 8
- }
- if (gridSize > 0) {
- item.isChecked = true
- setAndSaveGridSize(gridSize)
- return true
- }
- return false
- }
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/glide/AlbumGlideRequest.java b/app/src/main/java/io/github/muntashirakon/music/glide/AlbumGlideRequest.java
index 1a154ea10..1c3c04336 100644
--- a/app/src/main/java/io/github/muntashirakon/music/glide/AlbumGlideRequest.java
+++ b/app/src/main/java/io/github/muntashirakon/music/glide/AlbumGlideRequest.java
@@ -34,7 +34,7 @@ public class AlbumGlideRequest {
if (ignoreMediaStore) {
return requestManager.load(new AudioFileCover(song.getData()));
} else {
- return requestManager.loadFromMediaStore(MusicUtil.getMediaStoreAlbumCoverUri(song.getAlbumId()));
+ return requestManager.loadFromMediaStore(MusicUtil.INSTANCE.getMediaStoreAlbumCoverUri(song.getAlbumId()));
}
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/glide/SongGlideRequest.java b/app/src/main/java/io/github/muntashirakon/music/glide/SongGlideRequest.java
index 3f8e3855d..e8285284a 100644
--- a/app/src/main/java/io/github/muntashirakon/music/glide/SongGlideRequest.java
+++ b/app/src/main/java/io/github/muntashirakon/music/glide/SongGlideRequest.java
@@ -52,7 +52,7 @@ public class SongGlideRequest {
if (ignoreMediaStore) {
return requestManager.load(new AudioFileCover(song.getData()));
} else {
- return requestManager.loadFromMediaStore(MusicUtil.getMediaStoreAlbumCoverUri(song.getAlbumId()));
+ return requestManager.loadFromMediaStore(MusicUtil.INSTANCE.getMediaStoreAlbumCoverUri(song.getAlbumId()));
}
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/helper/M3UWriter.kt b/app/src/main/java/io/github/muntashirakon/music/helper/M3UWriter.kt
index 611f3d5d0..3f79fc866 100644
--- a/app/src/main/java/io/github/muntashirakon/music/helper/M3UWriter.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/helper/M3UWriter.kt
@@ -30,7 +30,7 @@ object M3UWriter : M3UConstants {
): File? {
if (!dir.exists()) dir.mkdirs()
val file = File(dir, playlist.name + "." + M3UConstants.EXTENSION)
- val songs = playlist.getSongs(context)
+ val songs = playlist.getSongs()
if (songs.size > 0) {
val bw = BufferedWriter(FileWriter(file))
bw.write(M3UConstants.HEADER)
diff --git a/app/src/main/java/io/github/muntashirakon/music/helper/MusicPlayerRemote.kt b/app/src/main/java/io/github/muntashirakon/music/helper/MusicPlayerRemote.kt
index bbc63604d..7cc9e175f 100644
--- a/app/src/main/java/io/github/muntashirakon/music/helper/MusicPlayerRemote.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/helper/MusicPlayerRemote.kt
@@ -23,23 +23,26 @@ import android.os.Build
import android.os.Environment
import android.os.IBinder
import android.provider.DocumentsContract
-import android.provider.MediaStore
import android.widget.Toast
import androidx.core.content.ContextCompat
import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.loaders.SongLoader
import io.github.muntashirakon.music.model.Song
+import io.github.muntashirakon.music.repository.SongRepository
import io.github.muntashirakon.music.service.MusicService
-
import io.github.muntashirakon.music.util.PreferenceUtil
+import org.koin.core.KoinComponent
+import org.koin.core.inject
import java.io.File
import java.util.*
-object MusicPlayerRemote {
+object MusicPlayerRemote : KoinComponent {
val TAG: String = MusicPlayerRemote::class.java.simpleName
private val mConnectionMap = WeakHashMap()
var musicService: MusicService? = null
+ private val songRepository by inject()
+
+
@JvmStatic
val isPlaying: Boolean
get() = musicService != null && musicService!!.isPlaying
@@ -413,24 +416,17 @@ object MusicPlayerRemote {
songId = uri.lastPathSegment
}
if (songId != null) {
- songs = SongLoader.getSongs(
- SongLoader.makeSongCursor(
- musicService!!,
- MediaStore.Audio.AudioColumns._ID + "=?",
- arrayOf(songId)
- )
- )
+ songs = songRepository.songs(songId)
}
}
}
if (songs == null) {
var songFile: File? = null
if (uri.authority != null && uri.authority == "com.android.externalstorage.documents") {
- songFile =
- File(
- Environment.getExternalStorageDirectory(),
- uri.path?.split(":".toRegex(), 2)?.get(1)
- )
+ songFile = File(
+ Environment.getExternalStorageDirectory(),
+ uri.path?.split(":".toRegex(), 2)?.get(1)
+ )
}
if (songFile == null) {
val path = getFilePathFromUri(musicService!!, uri)
@@ -441,13 +437,7 @@ object MusicPlayerRemote {
songFile = File(uri.path)
}
if (songFile != null) {
- songs = SongLoader.getSongs(
- SongLoader.makeSongCursor(
- musicService!!,
- MediaStore.Audio.AudioColumns.DATA + "=?",
- arrayOf(songFile.absolutePath)
- )
- )
+ songs = songRepository.songsByFilePath(songFile.absolutePath)
}
}
if (songs != null && songs.isNotEmpty()) {
diff --git a/app/src/main/java/io/github/muntashirakon/music/helper/SearchQueryHelper.kt b/app/src/main/java/io/github/muntashirakon/music/helper/SearchQueryHelper.kt
index faa466aba..0ccef5cf7 100644
--- a/app/src/main/java/io/github/muntashirakon/music/helper/SearchQueryHelper.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/helper/SearchQueryHelper.kt
@@ -18,29 +18,31 @@ import android.app.SearchManager
import android.content.Context
import android.os.Bundle
import android.provider.MediaStore
-import io.github.muntashirakon.music.loaders.SongLoader
import io.github.muntashirakon.music.model.Song
+import io.github.muntashirakon.music.repository.RealSongRepository
+import org.koin.core.KoinComponent
+import org.koin.core.inject
import java.util.*
-object SearchQueryHelper {
+object SearchQueryHelper : KoinComponent {
private const val TITLE_SELECTION = "lower(" + MediaStore.Audio.AudioColumns.TITLE + ") = ?"
private const val ALBUM_SELECTION = "lower(" + MediaStore.Audio.AudioColumns.ALBUM + ") = ?"
private const val ARTIST_SELECTION = "lower(" + MediaStore.Audio.AudioColumns.ARTIST + ") = ?"
private const val AND = " AND "
+ private val songRepository by inject()
var songs = ArrayList()
@JvmStatic
- fun getSongs(context: Context, extras: Bundle): ArrayList {
+ fun getSongs(context: Context, extras: Bundle): List {
val query = extras.getString(SearchManager.QUERY, null)
val artistName = extras.getString(MediaStore.EXTRA_MEDIA_ARTIST, null)
val albumName = extras.getString(MediaStore.EXTRA_MEDIA_ALBUM, null)
val titleName = extras.getString(MediaStore.EXTRA_MEDIA_TITLE, null)
- var songs = ArrayList()
+ var songs = listOf()
if (artistName != null && albumName != null && titleName != null) {
- songs = SongLoader.getSongs(
- SongLoader.makeSongCursor(
- context,
+ songs = songRepository.songs(
+ songRepository.makeSongCursor(
ARTIST_SELECTION + AND + ALBUM_SELECTION + AND + TITLE_SELECTION,
arrayOf(
artistName.toLowerCase(),
@@ -54,9 +56,8 @@ object SearchQueryHelper {
return songs
}
if (artistName != null && titleName != null) {
- songs = SongLoader.getSongs(
- SongLoader.makeSongCursor(
- context,
+ songs = songRepository.songs(
+ songRepository.makeSongCursor(
ARTIST_SELECTION + AND + TITLE_SELECTION,
arrayOf(artistName.toLowerCase(), titleName.toLowerCase())
)
@@ -66,9 +67,8 @@ object SearchQueryHelper {
return songs
}
if (albumName != null && titleName != null) {
- songs = SongLoader.getSongs(
- SongLoader.makeSongCursor(
- context,
+ songs = songRepository.songs(
+ songRepository.makeSongCursor(
ALBUM_SELECTION + AND + TITLE_SELECTION,
arrayOf(albumName.toLowerCase(), titleName.toLowerCase())
)
@@ -78,9 +78,8 @@ object SearchQueryHelper {
return songs
}
if (artistName != null) {
- songs = SongLoader.getSongs(
- SongLoader.makeSongCursor(
- context,
+ songs = songRepository.songs(
+ songRepository.makeSongCursor(
ARTIST_SELECTION,
arrayOf(artistName.toLowerCase())
)
@@ -90,9 +89,8 @@ object SearchQueryHelper {
return songs
}
if (albumName != null) {
- songs = SongLoader.getSongs(
- SongLoader.makeSongCursor(
- context,
+ songs = songRepository.songs(
+ songRepository.makeSongCursor(
ALBUM_SELECTION,
arrayOf(albumName.toLowerCase())
)
@@ -102,9 +100,8 @@ object SearchQueryHelper {
return songs
}
if (titleName != null) {
- songs = SongLoader.getSongs(
- SongLoader.makeSongCursor(
- context,
+ songs = songRepository.songs(
+ songRepository.makeSongCursor(
TITLE_SELECTION,
arrayOf(titleName.toLowerCase())
)
@@ -113,21 +110,18 @@ object SearchQueryHelper {
if (songs.isNotEmpty()) {
return songs
}
- songs =
- SongLoader.getSongs(
- SongLoader.makeSongCursor(
- context,
- ARTIST_SELECTION,
- arrayOf(query.toLowerCase())
- )
+ songs = songRepository.songs(
+ songRepository.makeSongCursor(
+ ARTIST_SELECTION,
+ arrayOf(query.toLowerCase())
)
+ )
if (songs.isNotEmpty()) {
return songs
}
- songs = SongLoader.getSongs(
- SongLoader.makeSongCursor(
- context,
+ songs = songRepository.songs(
+ songRepository.makeSongCursor(
ALBUM_SELECTION,
arrayOf(query.toLowerCase())
)
@@ -135,9 +129,8 @@ object SearchQueryHelper {
if (songs.isNotEmpty()) {
return songs
}
- songs = SongLoader.getSongs(
- SongLoader.makeSongCursor(
- context,
+ songs = songRepository.songs(
+ songRepository.makeSongCursor(
TITLE_SELECTION,
arrayOf(query.toLowerCase())
)
diff --git a/app/src/main/java/io/github/muntashirakon/music/helper/menu/GenreMenuHelper.kt b/app/src/main/java/io/github/muntashirakon/music/helper/menu/GenreMenuHelper.kt
index 2a7144068..fc3b94708 100644
--- a/app/src/main/java/io/github/muntashirakon/music/helper/menu/GenreMenuHelper.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/helper/menu/GenreMenuHelper.kt
@@ -14,43 +14,43 @@
package io.github.muntashirakon.music.helper.menu
-import android.app.Activity
import android.view.MenuItem
-import androidx.appcompat.app.AppCompatActivity
-
+import androidx.fragment.app.FragmentActivity
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.dialogs.AddToPlaylistDialog
import io.github.muntashirakon.music.helper.MusicPlayerRemote
-import io.github.muntashirakon.music.loaders.GenreLoader
import io.github.muntashirakon.music.model.Genre
import io.github.muntashirakon.music.model.Song
-import java.util.*
+import io.github.muntashirakon.music.repository.GenreRepository
+import org.koin.core.KoinComponent
+import org.koin.core.inject
-object GenreMenuHelper {
- fun handleMenuClick(activity: AppCompatActivity, genre: Genre, item: MenuItem): Boolean {
+object GenreMenuHelper : KoinComponent {
+ private val genreRepository by inject()
+ fun handleMenuClick(activity: FragmentActivity, genre: Genre, item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_play -> {
- MusicPlayerRemote.openQueue(getGenreSongs(activity, genre), 0, true)
+ MusicPlayerRemote.openQueue(getGenreSongs(genre), 0, true)
return true
}
R.id.action_play_next -> {
- MusicPlayerRemote.playNext(getGenreSongs(activity, genre))
+ MusicPlayerRemote.playNext(getGenreSongs(genre))
return true
}
R.id.action_add_to_playlist -> {
- AddToPlaylistDialog.create(getGenreSongs(activity, genre))
+ AddToPlaylistDialog.create(getGenreSongs(genre))
.show(activity.supportFragmentManager, "ADD_PLAYLIST")
return true
}
R.id.action_add_to_current_playing -> {
- MusicPlayerRemote.enqueue(getGenreSongs(activity, genre))
+ MusicPlayerRemote.enqueue(getGenreSongs(genre))
return true
}
}
return false
}
- private fun getGenreSongs(activity: Activity, genre: Genre): ArrayList {
- return GenreLoader.getSongs(activity, genre.id)
+ private fun getGenreSongs(genre: Genre): List {
+ return genreRepository.songs(genre.id)
}
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/helper/menu/PlaylistMenuHelper.kt b/app/src/main/java/io/github/muntashirakon/music/helper/menu/PlaylistMenuHelper.kt
index 980321547..5afc4541e 100644
--- a/app/src/main/java/io/github/muntashirakon/music/helper/menu/PlaylistMenuHelper.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/helper/menu/PlaylistMenuHelper.kt
@@ -19,26 +19,24 @@ import android.app.Activity
import android.content.Context
import android.view.MenuItem
import android.widget.Toast
-import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.FragmentActivity
import io.github.muntashirakon.music.App
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.dialogs.AddToPlaylistDialog
import io.github.muntashirakon.music.dialogs.DeletePlaylistDialog
import io.github.muntashirakon.music.dialogs.RenamePlaylistDialog
import io.github.muntashirakon.music.helper.MusicPlayerRemote
-import io.github.muntashirakon.music.loaders.PlaylistSongsLoader
import io.github.muntashirakon.music.misc.WeakContextAsyncTask
import io.github.muntashirakon.music.model.AbsCustomPlaylist
import io.github.muntashirakon.music.model.Playlist
import io.github.muntashirakon.music.model.Song
import io.github.muntashirakon.music.util.PlaylistsUtil
-import java.util.*
object PlaylistMenuHelper {
fun handleMenuClick(
- activity: AppCompatActivity,
+ activity: FragmentActivity,
playlist: Playlist, item: MenuItem
): Boolean {
when (item.itemId) {
@@ -80,11 +78,11 @@ object PlaylistMenuHelper {
private fun getPlaylistSongs(
activity: Activity,
playlist: Playlist
- ): ArrayList {
+ ): List {
return if (playlist is AbsCustomPlaylist) {
- playlist.getSongs(activity)
+ playlist.songs()
} else {
- PlaylistSongsLoader.getPlaylistSongList(activity, playlist)
+ playlist.getSongs()
}
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/helper/menu/SongMenuHelper.kt b/app/src/main/java/io/github/muntashirakon/music/helper/menu/SongMenuHelper.kt
index 7d7427194..67834a943 100644
--- a/app/src/main/java/io/github/muntashirakon/music/helper/menu/SongMenuHelper.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/helper/menu/SongMenuHelper.kt
@@ -18,8 +18,11 @@ import android.content.Intent
import android.view.MenuItem
import android.view.View
import android.widget.PopupMenu
-import androidx.appcompat.app.AppCompatActivity
+import androidx.core.os.bundleOf
import androidx.fragment.app.FragmentActivity
+import androidx.navigation.findNavController
+import io.github.muntashirakon.music.EXTRA_ALBUM_ID
+import io.github.muntashirakon.music.EXTRA_ARTIST_ID
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.activities.tageditor.AbsTagEditorActivity
import io.github.muntashirakon.music.activities.tageditor.SongTagEditorActivity
@@ -30,7 +33,6 @@ import io.github.muntashirakon.music.helper.MusicPlayerRemote
import io.github.muntashirakon.music.interfaces.PaletteColorHolder
import io.github.muntashirakon.music.model.Song
import io.github.muntashirakon.music.util.MusicUtil
-import io.github.muntashirakon.music.util.NavigationUtil
import io.github.muntashirakon.music.util.RingtoneManager
object SongMenuHelper {
@@ -89,18 +91,24 @@ object SongMenuHelper {
return true
}
R.id.action_go_to_album -> {
- NavigationUtil.goToAlbum(activity, song.albumId)
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.albumDetailsFragment,
+ bundleOf(EXTRA_ALBUM_ID to song.albumId)
+ )
return true
}
R.id.action_go_to_artist -> {
- NavigationUtil.goToArtist(activity, song.artistId)
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.artistDetailsFragment,
+ bundleOf(EXTRA_ARTIST_ID to song.artistId)
+ )
return true
}
}
return false
}
- abstract class OnClickSongMenu protected constructor(private val activity: AppCompatActivity) :
+ abstract class OnClickSongMenu(private val activity: FragmentActivity) :
View.OnClickListener, PopupMenu.OnMenuItemClickListener {
open val menuRes: Int
diff --git a/app/src/main/java/io/github/muntashirakon/music/helper/menu/SongsMenuHelper.kt b/app/src/main/java/io/github/muntashirakon/music/helper/menu/SongsMenuHelper.kt
index 4e7f3a2d1..ad3821f74 100644
--- a/app/src/main/java/io/github/muntashirakon/music/helper/menu/SongsMenuHelper.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/helper/menu/SongsMenuHelper.kt
@@ -15,19 +15,17 @@
package io.github.muntashirakon.music.helper.menu
import androidx.fragment.app.FragmentActivity
-
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.dialogs.AddToPlaylistDialog
import io.github.muntashirakon.music.dialogs.DeleteSongsDialog
import io.github.muntashirakon.music.helper.MusicPlayerRemote
import io.github.muntashirakon.music.model.Song
-import java.util.*
object SongsMenuHelper {
fun handleMenuClick(
activity: FragmentActivity,
- songs: ArrayList,
+ songs: List,
menuItemId: Int
): Boolean {
when (menuItemId) {
diff --git a/app/src/main/java/io/github/muntashirakon/music/interfaces/Callbacks.kt b/app/src/main/java/io/github/muntashirakon/music/interfaces/Callbacks.kt
new file mode 100644
index 000000000..17924914e
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/interfaces/Callbacks.kt
@@ -0,0 +1,13 @@
+package io.github.muntashirakon.music.interfaces
+
+import android.view.MenuItem
+import android.view.View
+import java.io.File
+
+interface Callbacks {
+ fun onFileSelected(file: File)
+
+ fun onFileMenuClicked(file: File, view: View)
+
+ fun onMultipleItemAction(item: MenuItem, files: ArrayList)
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/loaders/ArtistLoader.kt b/app/src/main/java/io/github/muntashirakon/music/loaders/ArtistLoader.kt
deleted file mode 100644
index 630a9011e..000000000
--- a/app/src/main/java/io/github/muntashirakon/music/loaders/ArtistLoader.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package io.github.muntashirakon.music.loaders
-
-import android.content.Context
-import android.provider.MediaStore.Audio.AudioColumns
-import io.github.muntashirakon.music.model.Album
-import io.github.muntashirakon.music.model.Artist
-import io.github.muntashirakon.music.util.PreferenceUtil
-
-object ArtistLoader {
- private fun getSongLoaderSortOrder(): String {
- return PreferenceUtil.artistSortOrder + ", " +
- PreferenceUtil.artistAlbumSortOrder + ", " +
- PreferenceUtil.artistSongSortOrder
- }
-
- fun getAllArtists(context: Context): ArrayList {
- val songs = SongLoader.getSongs(
- SongLoader.makeSongCursor(
- context,
- null, null,
- getSongLoaderSortOrder()
- )
- )
- return splitIntoArtists(AlbumLoader.splitIntoAlbums(songs))
- }
-
- fun getArtists(context: Context, query: String): ArrayList {
- val songs = SongLoader.getSongs(
- SongLoader.makeSongCursor(
- context,
- AudioColumns.ARTIST + " LIKE ?",
- arrayOf("%$query%"),
- getSongLoaderSortOrder()
- )
- )
- return splitIntoArtists(AlbumLoader.splitIntoAlbums(songs))
- }
-
- fun splitIntoArtists(albums: ArrayList?): ArrayList {
- val artists = ArrayList()
- if (albums != null) {
- for (album in albums) {
- getOrCreateArtist(artists, album.artistId).albums!!.add(album)
- }
- }
- return artists
- }
-
- private fun getOrCreateArtist(artists: ArrayList, artistId: Int): Artist {
- for (artist in artists) {
- if (artist.albums!!.isNotEmpty() && artist.albums[0].songs!!.isNotEmpty() && artist.albums[0].songs!![0].artistId == artistId) {
- return artist
- }
- }
- val album = Artist()
- artists.add(album)
- return album
- }
-
- @JvmStatic
- fun getArtist(context: Context, artistId: Int): Artist {
- val songs = SongLoader.getSongs(
- SongLoader.makeSongCursor(
- context,
- AudioColumns.ARTIST_ID + "=?",
- arrayOf(artistId.toString()),
- getSongLoaderSortOrder()
- )
- )
- return Artist(AlbumLoader.splitIntoAlbums(songs))
- }
-}
diff --git a/app/src/main/java/io/github/muntashirakon/music/loaders/PlaylistLoader.kt b/app/src/main/java/io/github/muntashirakon/music/loaders/PlaylistLoader.kt
deleted file mode 100644
index 69e44f7de..000000000
--- a/app/src/main/java/io/github/muntashirakon/music/loaders/PlaylistLoader.kt
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package io.github.muntashirakon.music.loaders
-
-import android.content.Context
-import android.database.Cursor
-import android.provider.BaseColumns
-import android.provider.MediaStore
-import android.provider.MediaStore.Audio.PlaylistsColumns
-import io.github.muntashirakon.music.R
-import io.github.muntashirakon.music.model.Playlist
-import java.util.*
-
-/**
- * Created by hemanths on 16/08/17.
- */
-
-object PlaylistLoader {
-
- private fun getPlaylist(
- cursor: Cursor?
- ): Playlist {
- var playlist = Playlist()
-
- if (cursor != null && cursor.moveToFirst()) {
- playlist = getPlaylistFromCursorImpl(cursor)
- }
- cursor?.close()
- return playlist
- }
-
- fun searchPlaylist(context: Context, searchString: String): List {
- return getAllPlaylists(
- makePlaylistCursor(
- context, PlaylistsColumns.NAME + "=?", arrayOf(searchString)
- )
- )
- }
-
- fun getPlaylist(
- context: Context,
- playlistName: String
- ): Playlist {
- return getPlaylist(
- makePlaylistCursor(
- context,
- PlaylistsColumns.NAME + "=?",
- arrayOf(playlistName)
- )
- )
- }
-
- fun getAllPlaylists(context: Context): ArrayList {
- return getAllPlaylists(makePlaylistCursor(context, null, null))
- }
-
- fun getFavoritePlaylist(context: Context): ArrayList {
- return getAllPlaylists(
- makePlaylistCursor(
- context,
- PlaylistsColumns.NAME + "=?",
- arrayOf(context.getString(R.string.favorites))
- )
- )
- }
-
- fun getAllPlaylists(cursor: Cursor?): ArrayList {
- val playlists = ArrayList()
-
- if (cursor != null && cursor.moveToFirst()) {
- do {
- playlists.add(getPlaylistFromCursorImpl(cursor))
- } while (cursor.moveToNext())
- }
- cursor?.close()
- return playlists
- }
-
- fun deletePlaylists(context: Context, playlistId: Long) {
- val localUri = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI
- val localStringBuilder = StringBuilder()
- localStringBuilder.append("_id IN (")
- localStringBuilder.append(playlistId)
- localStringBuilder.append(")")
- context.contentResolver.delete(localUri, localStringBuilder.toString(), null)
- }
-
- private fun makePlaylistCursor(
- context: Context,
- selection: String?,
- values: Array?
- ): Cursor? {
- try {
- return context.contentResolver.query(
- MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
- arrayOf(
- BaseColumns._ID, /* 0 */
- PlaylistsColumns.NAME /* 1 */
- ),
- selection,
- values,
- MediaStore.Audio.Playlists.DEFAULT_SORT_ORDER
- )
- } catch (e: SecurityException) {
- return null
- }
- }
-
- fun getPlaylist(
- context: Context,
- playlistId: Int
- ): Playlist {
- return getPlaylist(
- makePlaylistCursor(
- context,
- BaseColumns._ID + "=?",
- arrayOf(playlistId.toString())
- )
- )
- }
-
- private fun getPlaylistFromCursorImpl(
- cursor: Cursor
- ): Playlist {
- val id = cursor.getInt(0)
- val name = cursor.getString(1)
- return Playlist(id, name)
- }
-}
diff --git a/app/src/main/java/io/github/muntashirakon/music/lyrics/LrcView.java b/app/src/main/java/io/github/muntashirakon/music/lyrics/LrcView.java
index d4c0f7c34..e065d2f62 100644
--- a/app/src/main/java/io/github/muntashirakon/music/lyrics/LrcView.java
+++ b/app/src/main/java/io/github/muntashirakon/music/lyrics/LrcView.java
@@ -89,11 +89,6 @@ public class LrcView extends View {
}
}
};
-
- public LrcView(Context context) {
- this(context, null);
- }
-
/**
* 手势监听器
*/
@@ -151,6 +146,10 @@ public class LrcView extends View {
}
};
+ public LrcView(Context context) {
+ this(context, null);
+ }
+
public LrcView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/AbsCustomPlaylist.java b/app/src/main/java/io/github/muntashirakon/music/model/AbsCustomPlaylist.java
deleted file mode 100644
index 83024a0a5..000000000
--- a/app/src/main/java/io/github/muntashirakon/music/model/AbsCustomPlaylist.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package io.github.muntashirakon.music.model;
-
-import android.content.Context;
-import android.os.Parcel;
-
-import androidx.annotation.NonNull;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-
-/**
- * @author Karim Abou Zeid (kabouzeid)
- */
-
-public abstract class AbsCustomPlaylist extends Playlist {
-
- public AbsCustomPlaylist(int id, String name) {
- super(id, name);
- }
-
- public AbsCustomPlaylist() {
- }
-
- public AbsCustomPlaylist(Parcel in) {
- super(in);
- }
-
- @NonNull
- public abstract ArrayList getSongs(@NotNull Context context);
-}
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/AbsCustomPlaylist.kt b/app/src/main/java/io/github/muntashirakon/music/model/AbsCustomPlaylist.kt
new file mode 100644
index 000000000..9db83c837
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/model/AbsCustomPlaylist.kt
@@ -0,0 +1,21 @@
+package io.github.muntashirakon.music.model
+
+import io.github.muntashirakon.music.repository.LastAddedRepository
+import io.github.muntashirakon.music.repository.SongRepository
+import io.github.muntashirakon.music.repository.TopPlayedRepository
+import org.koin.core.KoinComponent
+import org.koin.core.inject
+
+abstract class AbsCustomPlaylist(
+ id: Int = -1,
+ name: String = ""
+) : Playlist(id, name), KoinComponent {
+
+ abstract fun songs(): List
+
+ protected val songRepository by inject()
+
+ protected val topPlayedRepository by inject()
+
+ protected val lastAddedRepository by inject()
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/Album.kt b/app/src/main/java/io/github/muntashirakon/music/model/Album.kt
index 3b3b18a1e..0f83eb21b 100644
--- a/app/src/main/java/io/github/muntashirakon/music/model/Album.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/model/Album.kt
@@ -41,6 +41,9 @@ class Album {
val songCount: Int
get() = songs!!.size
+ val albumArtist: String?
+ get() = safeGetFirstSong().albumArtist
+
constructor(songs: ArrayList) {
this.songs = songs
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/Artist.kt b/app/src/main/java/io/github/muntashirakon/music/model/Artist.kt
index 41959691f..f78f60deb 100644
--- a/app/src/main/java/io/github/muntashirakon/music/model/Artist.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/model/Artist.kt
@@ -25,10 +25,10 @@ class Artist {
val name: String
get() {
- val name = safeGetFirstAlbum().artistName
+ val name = safeGetFirstAlbum().safeGetFirstSong().albumArtist
return if (MusicUtil.isArtistNameUnknown(name)) {
UNKNOWN_ARTIST_DISPLAY_NAME
- } else name!!
+ } else safeGetFirstAlbum().safeGetFirstSong().artistName
}
val songCount: Int
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/CategoryInfo.java b/app/src/main/java/io/github/muntashirakon/music/model/CategoryInfo.java
index 75e730723..76e39dba0 100644
--- a/app/src/main/java/io/github/muntashirakon/music/model/CategoryInfo.java
+++ b/app/src/main/java/io/github/muntashirakon/music/model/CategoryInfo.java
@@ -59,9 +59,9 @@ public class CategoryInfo implements Parcelable {
}
public enum Category {
- Home(R.id.action_home, R.string.home, R.drawable.asld_home),
- Songs(R.id.action_song, R.string.songs, R.drawable.asld_music_note),
- Albums(R.id.action_album, R.string.albums, R.drawable.asld_album),
+ Home(R.id.action_home, R.string.for_you, R.drawable.ic_face),
+ Songs(R.id.action_song, R.string.songs, R.drawable.ic_audiotrack),
+ Albums(R.id.action_album, R.string.albums, R.drawable.ic_album),
Artists(R.id.action_artist, R.string.artists, R.drawable.ic_artist),
Playlists(R.id.action_playlist, R.string.playlists, R.drawable.ic_playlist_play),
Genres(R.id.action_genre, R.string.genres, R.drawable.ic_guitar),
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/Home.kt b/app/src/main/java/io/github/muntashirakon/music/model/Home.kt
index 7420a4a7c..86a9c3647 100644
--- a/app/src/main/java/io/github/muntashirakon/music/model/Home.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/model/Home.kt
@@ -14,13 +14,10 @@
package io.github.muntashirakon.music.model
-import androidx.annotation.DrawableRes
-import io.github.muntashirakon.music.adapter.HomeAdapter.Companion.HomeSection
+import io.github.muntashirakon.music.HomeSection
class Home(
- val arrayList: List<*>,
+ val arrayList: List,
@HomeSection
- val homeSection: Int,
- @DrawableRes
- val icon: Int
+ val homeSection: Int
)
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/Playlist.java b/app/src/main/java/io/github/muntashirakon/music/model/Playlist.java
deleted file mode 100644
index c7bb84a23..000000000
--- a/app/src/main/java/io/github/muntashirakon/music/model/Playlist.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package io.github.muntashirakon.music.model;
-
-import android.content.Context;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import androidx.annotation.NonNull;
-
-import java.util.ArrayList;
-
-import io.github.muntashirakon.music.loaders.PlaylistSongsLoader;
-import io.github.muntashirakon.music.util.MusicUtil;
-
-
-public class Playlist implements Parcelable {
-
- public static final Creator CREATOR = new Creator() {
- public Playlist createFromParcel(Parcel source) {
- return new Playlist(source);
- }
-
- public Playlist[] newArray(int size) {
- return new Playlist[size];
- }
- };
-
- public final int id;
-
- public final String name;
-
- public Playlist(final int id, final String name) {
- this.id = id;
- this.name = name;
- }
-
- public Playlist() {
- this.id = -1;
- this.name = "";
- }
-
- protected Playlist(Parcel in) {
- this.id = in.readInt();
- this.name = in.readString();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- Playlist playlist = (Playlist) o;
-
- if (id != playlist.id) {
- return false;
- }
- return name != null ? name.equals(playlist.name) : playlist.name == null;
-
- }
-
- @NonNull
- public ArrayList getSongs(@NonNull Context context) {
- // this default implementation covers static playlists
- return PlaylistSongsLoader.INSTANCE.getPlaylistSongList(context, id);
- }
-
- @Override
- public int hashCode() {
- int result = id;
- result = 31 * result + (name != null ? name.hashCode() : 0);
- return result;
- }
-
- @Override
- public String toString() {
- return "Playlist{" +
- "id=" + id +
- ", name='" + name + '\'' +
- '}';
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(this.id);
- dest.writeString(this.name);
- }
-
- @NonNull
- public String getInfoString(@NonNull Context context) {
- int songCount = getSongs(context).size();
- String songCountString = MusicUtil.getSongCountString(context, songCount);
-
- return MusicUtil.buildInfoString(
- songCountString,
- ""
- );
- }
-}
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/Playlist.kt b/app/src/main/java/io/github/muntashirakon/music/model/Playlist.kt
new file mode 100644
index 000000000..26f2abb66
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/model/Playlist.kt
@@ -0,0 +1,30 @@
+package io.github.muntashirakon.music.model
+
+import android.content.Context
+import android.os.Parcelable
+import io.github.muntashirakon.music.repository.RealPlaylistRepository
+import io.github.muntashirakon.music.util.MusicUtil
+import kotlinx.android.parcel.Parcelize
+import org.koin.core.KoinComponent
+import org.koin.core.get
+
+@Parcelize
+open class Playlist(
+ val id: Int = -1,
+ val name: String = ""
+) : Parcelable, KoinComponent {
+
+ // this default implementation covers static playlists
+ fun getSongs(): List {
+ return RealPlaylistRepository(get()).playlistSongs(id)
+ }
+
+ open fun getInfoString(context: Context): String {
+ val songCount = getSongs().size
+ val songCountString = MusicUtil.getSongCountString(context, songCount)
+ return MusicUtil.buildInfoString(
+ songCountString,
+ ""
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/PlaylistSong.java b/app/src/main/java/io/github/muntashirakon/music/model/PlaylistSong.java
index 645bda7f3..d2fc8f9c7 100644
--- a/app/src/main/java/io/github/muntashirakon/music/model/PlaylistSong.java
+++ b/app/src/main/java/io/github/muntashirakon/music/model/PlaylistSong.java
@@ -41,9 +41,9 @@ public class PlaylistSong extends Song {
@NotNull String artistName,
int playlistId,
int idInPlayList,
- @NotNull String composer) {
- super(id, title, trackNumber, year, duration, data, dateModified, albumId, albumName, artistId, artistName,
- composer);
+ @NotNull String composer,
+ String albumArtist) {
+ super(id, title, trackNumber, year, duration, data, dateModified, albumId, albumName, artistId, artistName, composer, albumArtist);
this.playlistId = playlistId;
this.idInPlayList = idInPlayList;
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/Song.kt b/app/src/main/java/io/github/muntashirakon/music/model/Song.kt
index 66b8e77ce..85697fd4a 100644
--- a/app/src/main/java/io/github/muntashirakon/music/model/Song.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/model/Song.kt
@@ -29,7 +29,8 @@ open class Song(
val albumName: String,
val artistId: Int,
val artistName: String,
- val composer: String?
+ val composer: String?,
+ val albumArtist: String?
) : Parcelable {
@@ -48,6 +49,7 @@ open class Song(
"",
-1,
"",
+ "",
""
)
}
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/AbsSmartPlaylist.java b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/AbsSmartPlaylist.java
deleted file mode 100644
index 69baac8b9..000000000
--- a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/AbsSmartPlaylist.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package io.github.muntashirakon.music.model.smartplaylist;
-
-import android.content.Context;
-import android.os.Parcel;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.Nullable;
-
-import io.github.muntashirakon.music.R;
-import io.github.muntashirakon.music.model.AbsCustomPlaylist;
-
-
-public abstract class AbsSmartPlaylist extends AbsCustomPlaylist {
-
- @DrawableRes
- public final int iconRes;
-
- public AbsSmartPlaylist(final String name, final int iconRes) {
- super(-Math.abs(31 * name.hashCode() + (iconRes * name.hashCode() * 31 * 31)), name);
- this.iconRes = iconRes;
- }
-
- public AbsSmartPlaylist() {
- super();
- this.iconRes = R.drawable.ic_queue_music;
- }
-
- protected AbsSmartPlaylist(Parcel in) {
- super(in);
- this.iconRes = in.readInt();
- }
-
- public abstract void clear(Context context);
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public boolean equals(@Nullable final Object obj) {
- if (super.equals(obj)) {
- if (getClass() != obj.getClass()) {
- return false;
- }
- final AbsSmartPlaylist other = (AbsSmartPlaylist) obj;
- return iconRes == other.iconRes;
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + iconRes;
- return result;
- }
-
- public boolean isClearable() {
- return true;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
- dest.writeInt(this.iconRes);
- }
-}
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/AbsSmartPlaylist.kt b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/AbsSmartPlaylist.kt
new file mode 100644
index 000000000..2202d95a1
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/AbsSmartPlaylist.kt
@@ -0,0 +1,10 @@
+package io.github.muntashirakon.music.model.smartplaylist
+
+import androidx.annotation.DrawableRes
+import io.github.muntashirakon.music.R
+import io.github.muntashirakon.music.model.AbsCustomPlaylist
+
+abstract class AbsSmartPlaylist(
+ name: String = "",
+ @DrawableRes val iconRes: Int = R.drawable.ic_queue_music
+) : AbsCustomPlaylist(-Math.abs(31 * name.hashCode() + iconRes * name.hashCode() * 31 * 31), name)
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/HistoryPlaylist.java b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/HistoryPlaylist.java
deleted file mode 100644
index c487b6ef8..000000000
--- a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/HistoryPlaylist.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package io.github.muntashirakon.music.model.smartplaylist;
-
-import android.content.Context;
-import android.os.Parcel;
-
-import androidx.annotation.NonNull;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-
-import io.github.muntashirakon.music.R;
-import io.github.muntashirakon.music.loaders.TopAndRecentlyPlayedTracksLoader;
-import io.github.muntashirakon.music.model.Song;
-import io.github.muntashirakon.music.providers.HistoryStore;
-
-/**
- * @author Karim Abou Zeid (kabouzeid)
- */
-public class HistoryPlaylist extends AbsSmartPlaylist {
-
- public static final Creator CREATOR = new Creator() {
- public HistoryPlaylist createFromParcel(Parcel source) {
- return new HistoryPlaylist(source);
- }
-
- public HistoryPlaylist[] newArray(int size) {
- return new HistoryPlaylist[size];
- }
- };
-
- public HistoryPlaylist(@NonNull Context context) {
- super(context.getString(R.string.history), R.drawable.ic_history);
- }
-
- protected HistoryPlaylist(Parcel in) {
- super(in);
- }
-
- @Override
- public void clear(@NonNull Context context) {
- HistoryStore.getInstance(context).clear();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @NonNull
- @Override
- public ArrayList getSongs(@NotNull @NonNull Context context) {
- return TopAndRecentlyPlayedTracksLoader.INSTANCE.getRecentlyPlayedTracks(context);
- }
-}
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/HistoryPlaylist.kt b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/HistoryPlaylist.kt
new file mode 100644
index 000000000..56e473dac
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/HistoryPlaylist.kt
@@ -0,0 +1,19 @@
+package io.github.muntashirakon.music.model.smartplaylist
+
+import io.github.muntashirakon.music.App
+import io.github.muntashirakon.music.R
+import io.github.muntashirakon.music.model.Song
+import kotlinx.android.parcel.Parcelize
+import org.koin.core.KoinComponent
+
+@Parcelize
+class HistoryPlaylist :
+ AbsSmartPlaylist(
+ App.getContext().getString(R.string.history),
+ R.drawable.ic_history
+ ),
+ KoinComponent {
+ override fun songs(): List {
+ return topPlayedRepository.recentlyPlayedTracks()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/LastAddedPlaylist.java b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/LastAddedPlaylist.java
deleted file mode 100644
index 31d3984f7..000000000
--- a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/LastAddedPlaylist.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package io.github.muntashirakon.music.model.smartplaylist;
-
-import android.content.Context;
-import android.os.Parcel;
-
-import androidx.annotation.NonNull;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-
-import io.github.muntashirakon.music.R;
-import io.github.muntashirakon.music.loaders.LastAddedSongsLoader;
-import io.github.muntashirakon.music.model.Song;
-
-
-public class LastAddedPlaylist extends AbsSmartPlaylist {
-
- public static final Creator CREATOR = new Creator() {
- public LastAddedPlaylist createFromParcel(Parcel source) {
- return new LastAddedPlaylist(source);
- }
-
- public LastAddedPlaylist[] newArray(int size) {
- return new LastAddedPlaylist[size];
- }
- };
-
- public LastAddedPlaylist(@NonNull Context context) {
- super(context.getString(R.string.last_added), R.drawable.ic_library_add);
- }
-
- protected LastAddedPlaylist(Parcel in) {
- super(in);
- }
-
- @Override
- public void clear(@NonNull Context context) {
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @NonNull
- @Override
- public ArrayList getSongs(@NotNull @NonNull Context context) {
- return LastAddedSongsLoader.INSTANCE.getLastAddedSongs(context);
- }
-
- @Override
- public boolean isClearable() {
- return false;
- }
-}
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/LastAddedPlaylist.kt b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/LastAddedPlaylist.kt
new file mode 100644
index 000000000..fabd66608
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/LastAddedPlaylist.kt
@@ -0,0 +1,14 @@
+package io.github.muntashirakon.music.model.smartplaylist
+
+import io.github.muntashirakon.music.App
+import io.github.muntashirakon.music.R
+import io.github.muntashirakon.music.model.Song
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+class LastAddedPlaylist :
+ AbsSmartPlaylist(App.getContext().getString(R.string.last_added), R.drawable.ic_library_add) {
+ override fun songs(): List {
+ return lastAddedRepository.recentSongs()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/MyTopTracksPlaylist.java b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/MyTopTracksPlaylist.java
deleted file mode 100644
index fcac697f6..000000000
--- a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/MyTopTracksPlaylist.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package io.github.muntashirakon.music.model.smartplaylist;
-
-import android.content.Context;
-import android.os.Parcel;
-
-import androidx.annotation.NonNull;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-
-import io.github.muntashirakon.music.R;
-import io.github.muntashirakon.music.loaders.TopAndRecentlyPlayedTracksLoader;
-import io.github.muntashirakon.music.model.Song;
-import io.github.muntashirakon.music.providers.SongPlayCountStore;
-
-/**
- * @author Karim Abou Zeid (kabouzeid)
- */
-public class MyTopTracksPlaylist extends AbsSmartPlaylist {
-
- public static final Creator CREATOR = new Creator() {
- public MyTopTracksPlaylist createFromParcel(Parcel source) {
- return new MyTopTracksPlaylist(source);
- }
-
- public MyTopTracksPlaylist[] newArray(int size) {
- return new MyTopTracksPlaylist[size];
- }
- };
-
- public MyTopTracksPlaylist(@NonNull Context context) {
- super(context.getString(R.string.my_top_tracks), R.drawable.ic_trending_up);
- }
-
- protected MyTopTracksPlaylist(Parcel in) {
- super(in);
- }
-
- @Override
- public void clear(@NonNull Context context) {
- SongPlayCountStore.getInstance(context).clear();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @NonNull
- @Override
- public ArrayList getSongs(@NotNull @NonNull Context context) {
- return TopAndRecentlyPlayedTracksLoader.INSTANCE.getTopTracks(context);
- }
-}
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/NotPlayedPlaylist.kt b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/NotPlayedPlaylist.kt
new file mode 100644
index 000000000..5c00a920a
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/NotPlayedPlaylist.kt
@@ -0,0 +1,16 @@
+package io.github.muntashirakon.music.model.smartplaylist
+
+import io.github.muntashirakon.music.App
+import io.github.muntashirakon.music.R
+import io.github.muntashirakon.music.model.Song
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+class NotPlayedPlaylist : AbsSmartPlaylist(
+ App.getContext().getString(R.string.not_recently_played),
+ R.drawable.ic_watch_later
+) {
+ override fun songs(): List {
+ return topPlayedRepository.notRecentlyPlayedTracks()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/NotRecentlyPlayedPlaylist.java b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/NotRecentlyPlayedPlaylist.java
deleted file mode 100644
index 4c37763d7..000000000
--- a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/NotRecentlyPlayedPlaylist.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package io.github.muntashirakon.music.model.smartplaylist;
-
-import android.content.Context;
-import android.os.Parcel;
-
-import androidx.annotation.NonNull;
-
-import java.util.ArrayList;
-
-import io.github.muntashirakon.music.R;
-import io.github.muntashirakon.music.loaders.TopAndRecentlyPlayedTracksLoader;
-import io.github.muntashirakon.music.model.Song;
-import io.github.muntashirakon.music.util.MusicUtil;
-import io.github.muntashirakon.music.util.PreferenceUtil;
-
-/**
- * @author SC (soncaokim)
- */
-public class NotRecentlyPlayedPlaylist extends AbsSmartPlaylist {
-
- public static final Creator CREATOR = new Creator() {
- public NotRecentlyPlayedPlaylist createFromParcel(Parcel source) {
- return new NotRecentlyPlayedPlaylist(source);
- }
-
- public NotRecentlyPlayedPlaylist[] newArray(int size) {
- return new NotRecentlyPlayedPlaylist[size];
- }
- };
-
- public NotRecentlyPlayedPlaylist(@NonNull Context context) {
- super(context.getString(R.string.not_recently_played), R.drawable.ic_watch_later);
- }
-
- protected NotRecentlyPlayedPlaylist(Parcel in) {
- super(in);
- }
-
- @NonNull
- @Override
- public String getInfoString(@NonNull Context context) {
- String cutoff = PreferenceUtil.INSTANCE.getRecentlyPlayedCutoffText(context);
-
- return MusicUtil.buildInfoString(
- cutoff,
- super.getInfoString(context)
- );
- }
-
- @NonNull
- @Override
- public ArrayList getSongs(@NonNull Context context) {
- return TopAndRecentlyPlayedTracksLoader.INSTANCE.getNotRecentlyPlayedTracks(context);
- }
-
- @Override
- public void clear(@NonNull Context context) {
- }
-
- @Override
- public boolean isClearable() {
- return false;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/ShuffleAllPlaylist.java b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/ShuffleAllPlaylist.java
deleted file mode 100644
index 0e84629ca..000000000
--- a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/ShuffleAllPlaylist.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package io.github.muntashirakon.music.model.smartplaylist;
-
-import android.content.Context;
-import android.os.Parcel;
-
-import androidx.annotation.NonNull;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-
-import io.github.muntashirakon.music.R;
-import io.github.muntashirakon.music.loaders.SongLoader;
-import io.github.muntashirakon.music.model.Song;
-
-public class ShuffleAllPlaylist extends AbsSmartPlaylist {
-
- public static final Creator CREATOR = new Creator() {
- public ShuffleAllPlaylist createFromParcel(Parcel source) {
- return new ShuffleAllPlaylist(source);
- }
-
- public ShuffleAllPlaylist[] newArray(int size) {
- return new ShuffleAllPlaylist[size];
- }
- };
-
- public ShuffleAllPlaylist(@NonNull Context context) {
- super(context.getString(R.string.action_shuffle_all), R.drawable.ic_shuffle);
- }
-
- protected ShuffleAllPlaylist(Parcel in) {
- super(in);
- }
-
- @Override
- public void clear(@NonNull Context context) {
- // Shuffle all is not a real "Smart Playlist"
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @NonNull
- @Override
- public ArrayList getSongs(@NotNull Context context) {
- return SongLoader.INSTANCE.getAllSongs(context);
- }
-}
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/ShuffleAllPlaylist.kt b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/ShuffleAllPlaylist.kt
new file mode 100644
index 000000000..a2de672fd
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/ShuffleAllPlaylist.kt
@@ -0,0 +1,16 @@
+package io.github.muntashirakon.music.model.smartplaylist
+
+import io.github.muntashirakon.music.App
+import io.github.muntashirakon.music.R
+import io.github.muntashirakon.music.model.Song
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+class ShuffleAllPlaylist : AbsSmartPlaylist(
+ App.getContext().getString(R.string.action_shuffle_all),
+ R.drawable.ic_shuffle
+) {
+ override fun songs(): List {
+ return songRepository.songs()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/TopTracksPlaylist.kt b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/TopTracksPlaylist.kt
new file mode 100644
index 000000000..1f63ed53f
--- /dev/null
+++ b/app/src/main/java/io/github/muntashirakon/music/model/smartplaylist/TopTracksPlaylist.kt
@@ -0,0 +1,16 @@
+package io.github.muntashirakon.music.model.smartplaylist
+
+import io.github.muntashirakon.music.App
+import io.github.muntashirakon.music.R
+import io.github.muntashirakon.music.model.Song
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+class TopTracksPlaylist : AbsSmartPlaylist(
+ App.getContext().getString(R.string.my_top_tracks),
+ R.drawable.ic_trending_up
+) {
+ override fun songs(): List {
+ return topPlayedRepository.topTracks()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/muntashirakon/music/preferences/BlacklistPreferenceDialog.kt b/app/src/main/java/io/github/muntashirakon/music/preferences/BlacklistPreferenceDialog.kt
index 2e8c3b365..7e7a7b785 100644
--- a/app/src/main/java/io/github/muntashirakon/music/preferences/BlacklistPreferenceDialog.kt
+++ b/app/src/main/java/io/github/muntashirakon/music/preferences/BlacklistPreferenceDialog.kt
@@ -24,6 +24,7 @@ import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
import io.github.muntashirakon.music.App
import io.github.muntashirakon.music.R
import io.github.muntashirakon.music.dialogs.BlacklistFolderChooserDialog
@@ -31,7 +32,6 @@ import io.github.muntashirakon.music.extensions.colorButtons
import io.github.muntashirakon.music.extensions.colorControlNormal
import io.github.muntashirakon.music.extensions.materialDialog
import io.github.muntashirakon.music.providers.BlacklistStore
-import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.File
import java.util.*
@@ -69,7 +69,7 @@ class BlacklistPreferenceDialog : DialogFragment(), BlacklistFolderChooserDialog
chooserDialog?.setCallback(this)
refreshBlacklistData()
return materialDialog(R.string.blacklist)
- .setPositiveButton(android.R.string.ok) { _, _ ->
+ .setPositiveButton(R.string.done) { _, _ ->
dismiss()
}
.setNeutralButton(R.string.clear_action) { _, _ ->
diff --git a/app/src/main/java/io/github/muntashirakon/music/providers/MusicPlaybackQueueStore.java b/app/src/main/java/io/github/muntashirakon/music/providers/MusicPlaybackQueueStore.java
index 01f097383..fb8b119f4 100644
--- a/app/src/main/java/io/github/muntashirakon/music/providers/MusicPlaybackQueueStore.java
+++ b/app/src/main/java/io/github/muntashirakon/music/providers/MusicPlaybackQueueStore.java
@@ -24,11 +24,11 @@ import android.provider.MediaStore.Audio.AudioColumns;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import java.util.ArrayList;
import java.util.List;
-import io.github.muntashirakon.music.loaders.SongLoader;
+import io.github.muntashirakon.music.App;
import io.github.muntashirakon.music.model.Song;
+import io.github.muntashirakon.music.repository.RealSongRepository;
/**
* @author Andrew Neal, modified for Phonograph by Karim Abou Zeid
@@ -43,7 +43,7 @@ public class MusicPlaybackQueueStore extends SQLiteOpenHelper {
public static final String ORIGINAL_PLAYING_QUEUE_TABLE_NAME = "original_playing_queue";
- private static final int VERSION = 10;
+ private static final int VERSION = 12;
@Nullable
private static MusicPlaybackQueueStore sInstance = null;
@@ -76,12 +76,12 @@ public class MusicPlaybackQueueStore extends SQLiteOpenHelper {
}
@NonNull
- public ArrayList getSavedOriginalPlayingQueue() {
+ public List getSavedOriginalPlayingQueue() {
return getQueue(ORIGINAL_PLAYING_QUEUE_TABLE_NAME);
}
@NonNull
- public ArrayList