Crash fixed
This commit is contained in:
parent
9672a8a23d
commit
e455684544
60 changed files with 5987 additions and 5855 deletions
|
@ -108,7 +108,7 @@ dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation project(':appthemehelper')
|
implementation project(':appthemehelper')
|
||||||
implementation 'androidx.multidex:multidex:2.0.1'
|
implementation 'androidx.multidex:multidex:2.0.1'
|
||||||
implementation 'androidx.fragment:fragment:1.2.0-rc01'
|
implementation 'androidx.fragment:fragment:1.2.0-rc02'
|
||||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||||
implementation 'androidx.recyclerview:recyclerview:1.1.0-rc01'
|
implementation 'androidx.recyclerview:recyclerview:1.1.0-rc01'
|
||||||
implementation "androidx.gridlayout:gridlayout:1.0.0"
|
implementation "androidx.gridlayout:gridlayout:1.0.0"
|
||||||
|
@ -118,9 +118,10 @@ dependencies {
|
||||||
implementation 'androidx.preference:preference:1.1.0'
|
implementation 'androidx.preference:preference:1.1.0'
|
||||||
implementation 'androidx.palette:palette-ktx:1.0.0'
|
implementation 'androidx.palette:palette-ktx:1.0.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||||
|
implementation 'androidx.core:core-ktx:1.1.0'
|
||||||
|
|
||||||
implementation 'com.google.android.material:material:1.2.0-alpha01'
|
implementation 'com.google.android.material:material:1.2.0-alpha01'
|
||||||
implementation 'com.google.android.play:core:1.6.3'
|
implementation 'com.google.android.play:core:1.6.4'
|
||||||
|
|
||||||
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
|
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
|
||||||
implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
|
implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
|
||||||
|
|
|
@ -119,13 +119,6 @@
|
||||||
android:name=".activities.SearchActivity"
|
android:name=".activities.SearchActivity"
|
||||||
android:windowSoftInputMode="stateVisible" />
|
android:windowSoftInputMode="stateVisible" />
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".activities.bugreport.ErrorHandlerActivity"
|
|
||||||
android:immersive="true"
|
|
||||||
android:label="@string/error"
|
|
||||||
android:launchMode="singleInstance"
|
|
||||||
android:theme="@style/ErrorHandlingTheme" />
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.LockScreenActivity"
|
android:name=".activities.LockScreenActivity"
|
||||||
android:noHistory="true"
|
android:noHistory="true"
|
||||||
|
|
|
@ -4,13 +4,10 @@ import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.MenuItem
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import androidx.core.app.ShareCompat
|
import androidx.core.app.ShareCompat
|
||||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
import androidx.recyclerview.widget.*
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
|
||||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
|
||||||
import code.name.monkey.retromusic.Constants.APP_INSTAGRAM_LINK
|
import code.name.monkey.retromusic.Constants.APP_INSTAGRAM_LINK
|
||||||
import code.name.monkey.retromusic.Constants.APP_TELEGRAM_LINK
|
import code.name.monkey.retromusic.Constants.APP_TELEGRAM_LINK
|
||||||
import code.name.monkey.retromusic.Constants.APP_TWITTER_LINK
|
import code.name.monkey.retromusic.Constants.APP_TWITTER_LINK
|
||||||
|
@ -24,10 +21,8 @@ import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
||||||
import code.name.monkey.retromusic.adapter.ContributorAdapter
|
import code.name.monkey.retromusic.adapter.ContributorAdapter
|
||||||
import code.name.monkey.retromusic.model.Contributor
|
import code.name.monkey.retromusic.model.Contributor
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import com.afollestad.materialdialogs.*
|
||||||
import com.afollestad.materialdialogs.LayoutMode
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
|
||||||
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
||||||
import com.afollestad.materialdialogs.list.listItems
|
import com.afollestad.materialdialogs.list.listItems
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
|
@ -42,136 +37,132 @@ import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
class AboutActivity : AbsBaseActivity(), View.OnClickListener {
|
class AboutActivity : AbsBaseActivity(), View.OnClickListener {
|
||||||
|
|
||||||
private val assetJsonData: String?
|
private val assetJsonData: String?
|
||||||
get() {
|
get() {
|
||||||
val json: String
|
val json: String
|
||||||
try {
|
try {
|
||||||
val inputStream = assets.open("contributors.json")
|
val inputStream = assets.open("contributors.json")
|
||||||
val size = inputStream.available()
|
val size = inputStream.available()
|
||||||
val buffer = ByteArray(size)
|
val buffer = ByteArray(size)
|
||||||
inputStream.read(buffer)
|
inputStream.read(buffer)
|
||||||
inputStream.close()
|
inputStream.close()
|
||||||
json = String(buffer, StandardCharsets.UTF_8)
|
json = String(buffer, StandardCharsets.UTF_8)
|
||||||
} catch (ex: IOException) {
|
} catch (ex: IOException) {
|
||||||
ex.printStackTrace()
|
ex.printStackTrace()
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return json
|
return json
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_about)
|
setContentView(R.layout.activity_about)
|
||||||
setStatusbarColorAuto()
|
setStatusbarColorAuto()
|
||||||
setNavigationBarColorPrimary()
|
setNavigationBarColorPrimary()
|
||||||
setLightNavigationBar(true)
|
setLightNavigationBar(true)
|
||||||
|
|
||||||
loadContributors()
|
loadContributors()
|
||||||
setSupportActionBar(toolbar)
|
setSupportActionBar(toolbar)
|
||||||
toolbar.apply {
|
toolbar.apply {
|
||||||
setTitleTextColor(ATHUtil.resolveColor(this@AboutActivity, R.attr.colorOnPrimary))
|
setTitleTextColor(ATHUtil.resolveColor(this@AboutActivity, R.attr.colorOnPrimary))
|
||||||
setBackgroundColor(ATHUtil.resolveColor(this@AboutActivity, R.attr.colorPrimary))
|
setBackgroundColor(ATHUtil.resolveColor(this@AboutActivity, R.attr.colorPrimary))
|
||||||
setNavigationOnClickListener { onBackPressed() }
|
setNavigationOnClickListener { onBackPressed() }
|
||||||
ToolbarContentTintHelper.colorBackButton(toolbar)
|
ToolbarContentTintHelper.colorBackButton(toolbar)
|
||||||
}
|
}
|
||||||
version.setSummary(getAppVersion())
|
version.setSummary(getAppVersion())
|
||||||
setUpView()
|
setUpView()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
if (item.itemId == android.R.id.home) {
|
||||||
|
onBackPressed()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
private fun openUrl(url: String) {
|
||||||
if (item.itemId == android.R.id.home) {
|
val i = Intent(Intent.ACTION_VIEW)
|
||||||
onBackPressed()
|
i.data = Uri.parse(url)
|
||||||
return true
|
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
}
|
startActivity(i)
|
||||||
return super.onOptionsItemSelected(item)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun openUrl(url: String) {
|
private fun setUpView() {
|
||||||
val i = Intent(Intent.ACTION_VIEW)
|
appGithub.setOnClickListener(this)
|
||||||
i.data = Uri.parse(url)
|
faqLink.setOnClickListener(this)
|
||||||
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
telegramLink.setOnClickListener(this)
|
||||||
startActivity(i)
|
appRate.setOnClickListener(this)
|
||||||
}
|
appTranslation.setOnClickListener(this)
|
||||||
|
appShare.setOnClickListener(this)
|
||||||
|
donateLink.setOnClickListener(this)
|
||||||
|
instagramLink.setOnClickListener(this)
|
||||||
|
twitterLink.setOnClickListener(this)
|
||||||
|
changelog.setOnClickListener(this)
|
||||||
|
openSource.setOnClickListener(this)
|
||||||
|
pinterestLink.setOnClickListener(this)
|
||||||
|
bugReportLink.setOnClickListener(this)
|
||||||
|
|
||||||
private fun setUpView() {
|
}
|
||||||
appGithub.setOnClickListener(this)
|
|
||||||
faqLink.setOnClickListener(this)
|
|
||||||
telegramLink.setOnClickListener(this)
|
|
||||||
appRate.setOnClickListener(this)
|
|
||||||
appTranslation.setOnClickListener(this)
|
|
||||||
appShare.setOnClickListener(this)
|
|
||||||
donateLink.setOnClickListener(this)
|
|
||||||
instagramLink.setOnClickListener(this)
|
|
||||||
twitterLink.setOnClickListener(this)
|
|
||||||
changelog.setOnClickListener(this)
|
|
||||||
openSource.setOnClickListener(this)
|
|
||||||
pinterestLink.setOnClickListener(this)
|
|
||||||
bugReportLink.setOnClickListener(this)
|
|
||||||
|
|
||||||
}
|
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.appShare -> shareApp()
|
||||||
|
R.id.donateLink -> NavigationUtil.goToSupportDevelopment(this)
|
||||||
|
R.id.instagramLink -> openUrl(APP_INSTAGRAM_LINK)
|
||||||
|
R.id.twitterLink -> openUrl(APP_TWITTER_LINK)
|
||||||
|
R.id.changelog -> showChangeLogOptions()
|
||||||
|
R.id.openSource -> NavigationUtil.goToOpenSource(this)
|
||||||
|
R.id.bugReportLink -> NavigationUtil.bugReport(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onClick(view: View) {
|
private fun showChangeLogOptions() {
|
||||||
when (view.id) {
|
MaterialDialog(this, BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
||||||
R.id.pinterestLink -> openUrl(PINTEREST)
|
cornerRadius(PreferenceUtil.getInstance(this@AboutActivity).dialogCorner)
|
||||||
R.id.faqLink -> openUrl(FAQ_LINK)
|
listItems(items = listOf("Telegram Channel", "App")) { _, position, _ ->
|
||||||
R.id.telegramLink -> openUrl(APP_TELEGRAM_LINK)
|
if (position == 0) {
|
||||||
R.id.appGithub -> openUrl(GITHUB_PROJECT)
|
openUrl(TELEGRAM_CHANGE_LOG)
|
||||||
R.id.appTranslation -> openUrl(TRANSLATE)
|
} else {
|
||||||
R.id.appRate -> openUrl(RATE_ON_GOOGLE_PLAY)
|
NavigationUtil.gotoWhatNews(this@AboutActivity)
|
||||||
R.id.appShare -> shareApp()
|
}
|
||||||
R.id.donateLink -> NavigationUtil.goToSupportDevelopment(this)
|
}
|
||||||
R.id.instagramLink -> openUrl(APP_INSTAGRAM_LINK)
|
}
|
||||||
R.id.twitterLink -> openUrl(APP_TWITTER_LINK)
|
}
|
||||||
R.id.changelog -> showChangeLogOptions()
|
|
||||||
R.id.openSource -> NavigationUtil.goToOpenSource(this)
|
|
||||||
R.id.bugReportLink -> NavigationUtil.bugReport(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showChangeLogOptions() {
|
private fun getAppVersion(): String {
|
||||||
MaterialDialog(this, BottomSheet(LayoutMode.WRAP_CONTENT))
|
return try {
|
||||||
.show {
|
val packageInfo = packageManager.getPackageInfo(packageName, 0)
|
||||||
cornerRadius(PreferenceUtil.getInstance(this@AboutActivity).dialogCorner)
|
packageInfo.versionName
|
||||||
listItems(items = listOf("Telegram Channel", "App")) { _, position, _ ->
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
if (position == 0) {
|
e.printStackTrace()
|
||||||
openUrl(TELEGRAM_CHANGE_LOG)
|
"0.0.0"
|
||||||
} else {
|
}
|
||||||
NavigationUtil.gotoWhatNews(this@AboutActivity)
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAppVersion(): String {
|
private fun shareApp() {
|
||||||
return try {
|
ShareCompat.IntentBuilder.from(this).setType("text/plain")
|
||||||
val packageInfo = packageManager.getPackageInfo(packageName, 0)
|
.setChooserTitle(R.string.share_app)
|
||||||
packageInfo.versionName
|
.setText(String.format(getString(R.string.app_share), packageName)).startChooser()
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
}
|
||||||
e.printStackTrace()
|
|
||||||
"0.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun shareApp() {
|
private fun loadContributors() {
|
||||||
ShareCompat.IntentBuilder.from(this)
|
val data = assetJsonData
|
||||||
.setType("text/plain")
|
val type = object : TypeToken<List<Contributor>>() {
|
||||||
.setChooserTitle(R.string.share_app)
|
|
||||||
.setText(String.format(getString(R.string.app_share), packageName))
|
|
||||||
.startChooser()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadContributors() {
|
}.type
|
||||||
val data = assetJsonData
|
val contributors = Gson().fromJson<List<Contributor>>(data, type)
|
||||||
val type = object : TypeToken<List<Contributor>>() {
|
|
||||||
|
|
||||||
}.type
|
val contributorAdapter = ContributorAdapter(contributors)
|
||||||
val contributors = Gson().fromJson<List<Contributor>>(data, type)
|
recyclerView.layoutManager = LinearLayoutManager(this)
|
||||||
|
recyclerView.itemAnimator = DefaultItemAnimator()
|
||||||
val contributorAdapter = ContributorAdapter(contributors)
|
recyclerView.adapter = contributorAdapter
|
||||||
recyclerView.layoutManager = LinearLayoutManager(this)
|
}
|
||||||
recyclerView.itemAnimator = DefaultItemAnimator()
|
|
||||||
recyclerView.adapter = contributorAdapter
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,41 +4,25 @@ import android.app.ActivityOptions
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.*
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.SubMenu
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
import androidx.recyclerview.widget.*
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
import code.name.monkey.retromusic.*
|
||||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
|
||||||
import code.name.monkey.retromusic.App
|
|
||||||
import code.name.monkey.retromusic.R
|
|
||||||
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
|
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
|
||||||
import code.name.monkey.retromusic.activities.tageditor.AbsTagEditorActivity
|
import code.name.monkey.retromusic.activities.tageditor.*
|
||||||
import code.name.monkey.retromusic.activities.tageditor.AlbumTagEditorActivity
|
|
||||||
import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter
|
import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter
|
||||||
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
|
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
|
||||||
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
|
import code.name.monkey.retromusic.dialogs.*
|
||||||
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
|
|
||||||
import code.name.monkey.retromusic.extensions.show
|
import code.name.monkey.retromusic.extensions.show
|
||||||
import code.name.monkey.retromusic.glide.ArtistGlideRequest
|
import code.name.monkey.retromusic.glide.*
|
||||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
|
||||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder
|
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder
|
||||||
import code.name.monkey.retromusic.model.Album
|
import code.name.monkey.retromusic.model.*
|
||||||
import code.name.monkey.retromusic.model.Artist
|
import code.name.monkey.retromusic.mvp.presenter.*
|
||||||
import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsPresenter
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsView
|
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import kotlinx.android.synthetic.main.activity_album.*
|
import kotlinx.android.synthetic.main.activity_album.*
|
||||||
import kotlinx.android.synthetic.main.activity_album_content.*
|
import kotlinx.android.synthetic.main.activity_album_content.*
|
||||||
|
@ -46,236 +30,263 @@ import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import android.util.Pair as UtilPair
|
import android.util.Pair as UtilPair
|
||||||
|
|
||||||
|
|
||||||
class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
|
class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
|
||||||
|
|
||||||
private lateinit var simpleSongAdapter: SimpleSongAdapter
|
private lateinit var simpleSongAdapter: SimpleSongAdapter
|
||||||
private lateinit var album: Album
|
private lateinit var album: Album
|
||||||
private lateinit var artistImage: ImageView
|
private lateinit var artistImage: ImageView
|
||||||
private val savedSortOrder: String
|
private val savedSortOrder: String
|
||||||
get() = PreferenceUtil.getInstance(this).albumDetailSongSortOrder
|
get() = PreferenceUtil.getInstance(this).albumDetailSongSortOrder
|
||||||
|
|
||||||
override fun createContentView(): View {
|
override fun createContentView(): View {
|
||||||
return wrapSlidingMusicPanel(R.layout.activity_album)
|
return wrapSlidingMusicPanel(R.layout.activity_album)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var albumDetailsPresenter: AlbumDetailsPresenter
|
lateinit var albumDetailsPresenter: AlbumDetailsPresenter
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setDrawUnderStatusBar()
|
setDrawUnderStatusBar()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
toggleBottomNavigationView(true)
|
toggleBottomNavigationView(true)
|
||||||
setStatusbarColor(Color.TRANSPARENT)
|
setStatusbarColor(Color.TRANSPARENT)
|
||||||
setNavigationbarColorAuto()
|
setNavigationbarColorAuto()
|
||||||
setTaskDescriptionColorAuto()
|
setTaskDescriptionColorAuto()
|
||||||
setLightNavigationBar(true)
|
setLightNavigationBar(true)
|
||||||
setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
|
setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
|
||||||
|
|
||||||
ActivityCompat.postponeEnterTransition(this)
|
ActivityCompat.postponeEnterTransition(this)
|
||||||
|
|
||||||
App.musicComponent.inject(this)
|
App.musicComponent.inject(this)
|
||||||
artistImage = findViewById(R.id.artistImage)
|
artistImage = findViewById(R.id.artistImage)
|
||||||
|
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
|
|
||||||
artistImage.setOnClickListener {
|
artistImage.setOnClickListener {
|
||||||
val artistPairs = ActivityOptions.makeSceneTransitionAnimation(this, UtilPair.create(artistImage, getString(R.string.transition_artist_image)))
|
val artistPairs = ActivityOptions.makeSceneTransitionAnimation(
|
||||||
NavigationUtil.goToArtistOptions(this, album.artistId, artistPairs)
|
this,
|
||||||
}
|
UtilPair.create(
|
||||||
playAction.apply {
|
artistImage,
|
||||||
setOnClickListener { MusicPlayerRemote.openQueue(album.songs!!, 0, true) }
|
getString(R.string.transition_artist_image)
|
||||||
}
|
)
|
||||||
shuffleAction.apply {
|
)
|
||||||
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) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
albumDetailsPresenter.attachView(this)
|
albumDetailsPresenter.attachView(this)
|
||||||
|
|
||||||
if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) {
|
if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) {
|
||||||
intent.extras?.getInt(EXTRA_ALBUM_ID)?.let { albumDetailsPresenter.loadAlbum(it) }
|
intent.extras?.getInt(EXTRA_ALBUM_ID)?.let { albumDetailsPresenter.loadAlbum(it) }
|
||||||
} else {
|
} else {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupRecyclerView() {
|
private fun setupRecyclerView() {
|
||||||
simpleSongAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song)
|
simpleSongAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song)
|
||||||
recyclerView.apply {
|
recyclerView.apply {
|
||||||
layoutManager = LinearLayoutManager(this@AlbumDetailsActivity)
|
layoutManager = LinearLayoutManager(this@AlbumDetailsActivity)
|
||||||
itemAnimator = DefaultItemAnimator()
|
itemAnimator = DefaultItemAnimator()
|
||||||
isNestedScrollingEnabled = false
|
isNestedScrollingEnabled = false
|
||||||
adapter = simpleSongAdapter
|
adapter = simpleSongAdapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
albumDetailsPresenter.detachView()
|
albumDetailsPresenter.detachView()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun complete() {
|
override fun complete() {
|
||||||
ActivityCompat.startPostponedEnterTransition(this)
|
ActivityCompat.startPostponedEnterTransition(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun album(album: Album) {
|
override fun album(album: Album) {
|
||||||
|
|
||||||
if (album.songs!!.isEmpty()) {
|
if (album.songs!!.isEmpty()) {
|
||||||
finish()
|
finish()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.album = album
|
this.album = album
|
||||||
|
|
||||||
albumTitle.text = album.title
|
albumTitle.text = album.title
|
||||||
if (MusicUtil.getYearString(album.year) == "-") {
|
if (MusicUtil.getYearString(album.year) == "-") {
|
||||||
albumText.text = String.format("%s • %s", album.artistName, MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs)))
|
albumText.text = String.format(
|
||||||
} else {
|
"%s • %s",
|
||||||
albumText.text = String.format("%s • %s • %s", album.artistName, MusicUtil.getYearString(album.year), MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs)))
|
album.artistName,
|
||||||
}
|
MusicUtil.getReadableDurationString(
|
||||||
loadAlbumCover()
|
MusicUtil.getTotalDuration(
|
||||||
simpleSongAdapter.swapDataSet(album.songs)
|
this,
|
||||||
albumDetailsPresenter.loadMore(album.artistId)
|
album.songs
|
||||||
}
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
albumText.text = String.format(
|
||||||
|
"%s • %s • %s",
|
||||||
|
album.artistName,
|
||||||
|
MusicUtil.getYearString(album.year),
|
||||||
|
MusicUtil.getReadableDurationString(
|
||||||
|
MusicUtil.getTotalDuration(
|
||||||
|
this,
|
||||||
|
album.songs
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
loadAlbumCover()
|
||||||
|
simpleSongAdapter.swapDataSet(album.songs)
|
||||||
|
albumDetailsPresenter.loadMore(album.artistId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun moreAlbums(albums: ArrayList<Album>) {
|
||||||
|
moreTitle.show()
|
||||||
|
moreRecyclerView.show()
|
||||||
|
moreTitle.text = String.format(getString(R.string.label_more_from), album.artistName)
|
||||||
|
|
||||||
override fun moreAlbums(albums: ArrayList<Album>) {
|
val albumAdapter = HorizontalAlbumAdapter(this, albums, false, null)
|
||||||
moreTitle.show()
|
moreRecyclerView.layoutManager = GridLayoutManager(
|
||||||
moreRecyclerView.show()
|
this,
|
||||||
moreTitle.text = String.format(getString(R.string.label_more_from), album.artistName)
|
1,
|
||||||
|
GridLayoutManager.HORIZONTAL,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
moreRecyclerView.adapter = albumAdapter
|
||||||
|
}
|
||||||
|
|
||||||
val albumAdapter = HorizontalAlbumAdapter(this, albums, false, null)
|
override fun loadArtistImage(artist: Artist) {
|
||||||
moreRecyclerView.layoutManager = GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false)
|
ArtistGlideRequest.Builder.from(Glide.with(this), artist).generatePalette(this).build()
|
||||||
moreRecyclerView.adapter = albumAdapter
|
.dontAnimate().dontTransform().into(object : RetroMusicColoredTarget(artistImage) {
|
||||||
}
|
override fun onColorReady(color: Int) {
|
||||||
|
|
||||||
override fun loadArtistImage(artist: Artist) {
|
}
|
||||||
ArtistGlideRequest.Builder.from(Glide.with(this), artist)
|
})
|
||||||
.generatePalette(this).build()
|
|
||||||
.dontAnimate()
|
|
||||||
.dontTransform()
|
|
||||||
.into(object : RetroMusicColoredTarget(artistImage) {
|
|
||||||
override fun onColorReady(color: Int) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
}
|
private fun loadAlbumCover() {
|
||||||
|
SongGlideRequest.Builder.from(Glide.with(this), album.safeGetFirstSong())
|
||||||
|
.checkIgnoreMediaStore(this).generatePalette(this).build().dontAnimate().dontTransform()
|
||||||
|
.into(object : RetroMusicColoredTarget(image) {
|
||||||
|
override fun onColorReady(color: Int) {
|
||||||
|
setColors(color)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private fun loadAlbumCover() {
|
private fun setColors(color: Int) {
|
||||||
SongGlideRequest.Builder.from(Glide.with(this), album.safeGetFirstSong())
|
val themeColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color
|
||||||
.checkIgnoreMediaStore(this)
|
else ThemeStore.accentColor(this)
|
||||||
.generatePalette(this).build()
|
|
||||||
.dontAnimate().dontTransform()
|
|
||||||
.into(object : RetroMusicColoredTarget(image) {
|
|
||||||
override fun onColorReady(color: Int) {
|
|
||||||
setColors(color)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setColors(color: Int) {
|
songTitle.setTextColor(themeColor)
|
||||||
val themeColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color
|
moreTitle.setTextColor(themeColor)
|
||||||
else ThemeStore.accentColor(this)
|
|
||||||
|
|
||||||
songTitle.setTextColor(themeColor)
|
val buttonColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color
|
||||||
moreTitle.setTextColor(themeColor)
|
else ATHUtil.resolveColor(this, R.attr.cardBackgroundColor)
|
||||||
|
|
||||||
val buttonColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color
|
MaterialUtil.setTint(button = shuffleAction, color = buttonColor)
|
||||||
else ATHUtil.resolveColor(this, R.attr.cardBackgroundColor)
|
MaterialUtil.setTint(button = playAction, color = buttonColor)
|
||||||
|
|
||||||
MaterialUtil.setTint(button = shuffleAction, color = buttonColor)
|
toolbar.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
||||||
MaterialUtil.setTint(button = playAction, color = buttonColor)
|
setSupportActionBar(toolbar)
|
||||||
|
supportActionBar?.title = null
|
||||||
|
}
|
||||||
|
|
||||||
toolbar.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
setSupportActionBar(toolbar)
|
menuInflater.inflate(R.menu.menu_album_detail, menu)
|
||||||
supportActionBar?.title = null
|
val sortOrder = menu.findItem(R.id.action_sort_order)
|
||||||
}
|
setUpSortOrderMenu(sortOrder.subMenu)
|
||||||
|
return super.onCreateOptionsMenu(menu)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
menuInflater.inflate(R.menu.menu_album_detail, menu)
|
return handleSortOrderMenuItem(item)
|
||||||
val sortOrder = menu.findItem(R.id.action_sort_order)
|
}
|
||||||
setUpSortOrderMenu(sortOrder.subMenu)
|
|
||||||
return super.onCreateOptionsMenu(menu)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
|
||||||
return handleSortOrderMenuItem(item)
|
var sortOrder: String? = null
|
||||||
}
|
val songs = simpleSongAdapter.dataSet
|
||||||
|
when (item.itemId) {
|
||||||
|
R.id.action_play_next -> {
|
||||||
|
MusicPlayerRemote.playNext(songs)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
R.id.action_add_to_current_playing -> {
|
||||||
|
MusicPlayerRemote.enqueue(songs)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
R.id.action_add_to_playlist -> {
|
||||||
|
AddToPlaylistDialog.create(songs).show(supportFragmentManager, "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()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
R.id.action_tag_editor -> {
|
||||||
|
val intent = Intent(this, AlbumTagEditorActivity::class.java)
|
||||||
|
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, album.id)
|
||||||
|
startActivityForResult(intent, TAG_EDITOR_REQUEST)
|
||||||
|
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_artist_song_duration -> sortOrder = AlbumSongSortOrder.SONG_DURATION
|
||||||
|
}
|
||||||
|
if (sortOrder != null) {
|
||||||
|
item.isChecked = true
|
||||||
|
setSaveSortOrder(sortOrder)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
|
private fun setUpSortOrderMenu(sortOrder: SubMenu) {
|
||||||
var sortOrder: String? = null
|
when (savedSortOrder) {
|
||||||
val songs = simpleSongAdapter.dataSet
|
AlbumSongSortOrder.SONG_A_Z -> sortOrder.findItem(R.id.action_sort_order_title)
|
||||||
when (item.itemId) {
|
.isChecked = true
|
||||||
R.id.action_play_next -> {
|
AlbumSongSortOrder.SONG_Z_A -> sortOrder.findItem(R.id.action_sort_order_title_desc)
|
||||||
MusicPlayerRemote.playNext(songs)
|
.isChecked = true
|
||||||
return true
|
AlbumSongSortOrder.SONG_TRACK_LIST -> sortOrder.findItem(R.id.action_sort_order_track_list)
|
||||||
}
|
.isChecked = true
|
||||||
R.id.action_add_to_current_playing -> {
|
AlbumSongSortOrder.SONG_DURATION -> sortOrder.findItem(R.id.action_sort_order_artist_song_duration)
|
||||||
MusicPlayerRemote.enqueue(songs)
|
.isChecked = true
|
||||||
return true
|
}
|
||||||
}
|
}
|
||||||
R.id.action_add_to_playlist -> {
|
|
||||||
AddToPlaylistDialog.create(songs).show(supportFragmentManager, "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()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
R.id.action_tag_editor -> {
|
|
||||||
val intent = Intent(this, AlbumTagEditorActivity::class.java)
|
|
||||||
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, album.id)
|
|
||||||
startActivityForResult(intent, TAG_EDITOR_REQUEST)
|
|
||||||
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_artist_song_duration -> sortOrder = AlbumSongSortOrder.SONG_DURATION
|
|
||||||
}
|
|
||||||
if (sortOrder != null) {
|
|
||||||
item.isChecked = true
|
|
||||||
setSaveSortOrder(sortOrder)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setUpSortOrderMenu(sortOrder: SubMenu) {
|
private fun setSaveSortOrder(sortOrder: String?) {
|
||||||
when (savedSortOrder) {
|
PreferenceUtil.getInstance(this).albumDetailSongSortOrder = sortOrder
|
||||||
AlbumSongSortOrder.SONG_A_Z -> sortOrder.findItem(R.id.action_sort_order_title).isChecked = true
|
reload()
|
||||||
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).isChecked = true
|
|
||||||
AlbumSongSortOrder.SONG_DURATION -> sortOrder.findItem(R.id.action_sort_order_artist_song_duration).isChecked = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setSaveSortOrder(sortOrder: String?) {
|
override fun onMediaStoreChanged() {
|
||||||
PreferenceUtil.getInstance(this).albumDetailSongSortOrder = sortOrder
|
super.onMediaStoreChanged()
|
||||||
reload()
|
reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMediaStoreChanged() {
|
private fun reload() {
|
||||||
super.onMediaStoreChanged()
|
if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) {
|
||||||
reload()
|
intent.extras?.getInt(EXTRA_ALBUM_ID)?.let { albumDetailsPresenter.loadAlbum(it) }
|
||||||
}
|
} else {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun reload() {
|
companion object {
|
||||||
if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) {
|
|
||||||
intent.extras?.getInt(EXTRA_ALBUM_ID)?.let { albumDetailsPresenter.loadAlbum(it) }
|
|
||||||
} else {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
const val EXTRA_ALBUM_ID = "extra_album_id"
|
||||||
|
private const val TAG_EDITOR_REQUEST = 2001
|
||||||
const val EXTRA_ALBUM_ID = "extra_album_id"
|
}
|
||||||
private const val TAG_EDITOR_REQUEST = 2001
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -3,35 +3,23 @@ package code.name.monkey.retromusic.activities
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Build
|
import android.os.*
|
||||||
import android.os.Bundle
|
import android.text.*
|
||||||
import android.text.Html
|
import android.view.*
|
||||||
import android.text.Spanned
|
|
||||||
import android.view.Menu
|
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
import androidx.recyclerview.widget.*
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
import code.name.monkey.retromusic.*
|
||||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
|
||||||
import code.name.monkey.retromusic.App
|
|
||||||
import code.name.monkey.retromusic.R
|
|
||||||
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
|
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
|
||||||
import code.name.monkey.retromusic.adapter.album.AlbumAdapter
|
import code.name.monkey.retromusic.adapter.album.*
|
||||||
import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter
|
|
||||||
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
|
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
|
||||||
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
|
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
|
||||||
import code.name.monkey.retromusic.glide.ArtistGlideRequest
|
import code.name.monkey.retromusic.glide.*
|
||||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.model.Artist
|
import code.name.monkey.retromusic.model.Artist
|
||||||
import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsPresenter
|
import code.name.monkey.retromusic.mvp.presenter.*
|
||||||
import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsView
|
|
||||||
import code.name.monkey.retromusic.rest.LastFMRestClient
|
import code.name.monkey.retromusic.rest.LastFMRestClient
|
||||||
import code.name.monkey.retromusic.rest.model.LastFmArtist
|
import code.name.monkey.retromusic.rest.model.LastFmArtist
|
||||||
import code.name.monkey.retromusic.util.*
|
import code.name.monkey.retromusic.util.*
|
||||||
|
@ -44,257 +32,267 @@ import kotlin.collections.ArrayList
|
||||||
|
|
||||||
class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
|
class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
|
||||||
|
|
||||||
private var biography: Spanned? = null
|
private var biography: Spanned? = null
|
||||||
private lateinit var artist: Artist
|
private lateinit var artist: Artist
|
||||||
private var lastFMRestClient: LastFMRestClient? = null
|
private var lastFMRestClient: LastFMRestClient? = null
|
||||||
private lateinit var songAdapter: SimpleSongAdapter
|
private lateinit var songAdapter: SimpleSongAdapter
|
||||||
private lateinit var albumAdapter: AlbumAdapter
|
private lateinit var albumAdapter: AlbumAdapter
|
||||||
private var forceDownload: Boolean = false
|
private var forceDownload: Boolean = false
|
||||||
|
|
||||||
override fun createContentView(): View {
|
override fun createContentView(): View {
|
||||||
return wrapSlidingMusicPanel(R.layout.activity_artist_details)
|
return wrapSlidingMusicPanel(R.layout.activity_artist_details)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var artistDetailsPresenter: ArtistDetailsPresenter
|
lateinit var artistDetailsPresenter: ArtistDetailsPresenter
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setDrawUnderStatusBar()
|
setDrawUnderStatusBar()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
toggleBottomNavigationView(true)
|
toggleBottomNavigationView(true)
|
||||||
setStatusbarColor(Color.TRANSPARENT)
|
setStatusbarColor(Color.TRANSPARENT)
|
||||||
setNavigationbarColorAuto()
|
setNavigationbarColorAuto()
|
||||||
setTaskDescriptionColorAuto()
|
setTaskDescriptionColorAuto()
|
||||||
setLightNavigationBar(true)
|
setLightNavigationBar(true)
|
||||||
setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
|
setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
|
||||||
|
|
||||||
ActivityCompat.postponeEnterTransition(this)
|
ActivityCompat.postponeEnterTransition(this)
|
||||||
|
|
||||||
lastFMRestClient = LastFMRestClient(this)
|
lastFMRestClient = LastFMRestClient(this)
|
||||||
|
|
||||||
setUpViews()
|
setUpViews()
|
||||||
|
|
||||||
playAction.apply {
|
playAction.apply {
|
||||||
setOnClickListener { MusicPlayerRemote.openQueue(artist.songs, 0, true) }
|
setOnClickListener { MusicPlayerRemote.openQueue(artist.songs, 0, true) }
|
||||||
}
|
}
|
||||||
shuffleAction.apply {
|
shuffleAction.apply {
|
||||||
setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(artist.songs, true) }
|
setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(artist.songs, true) }
|
||||||
}
|
}
|
||||||
|
|
||||||
biographyText.setOnClickListener {
|
biographyText.setOnClickListener {
|
||||||
if (biographyText.maxLines == 4) {
|
if (biographyText.maxLines == 4) {
|
||||||
biographyText.maxLines = Integer.MAX_VALUE
|
biographyText.maxLines = Integer.MAX_VALUE
|
||||||
} else {
|
} else {
|
||||||
biographyText.maxLines = 4
|
biographyText.maxLines = 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
App.musicComponent.inject(this)
|
App.musicComponent.inject(this)
|
||||||
artistDetailsPresenter.attachView(this)
|
artistDetailsPresenter.attachView(this)
|
||||||
|
|
||||||
if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) {
|
if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) {
|
||||||
intent.extras?.getInt(EXTRA_ARTIST_ID)?.let { artistDetailsPresenter.loadArtist(it) }
|
intent.extras?.getInt(EXTRA_ARTIST_ID)?.let { artistDetailsPresenter.loadArtist(it) }
|
||||||
} else {
|
} else {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
artistDetailsPresenter.detachView()
|
artistDetailsPresenter.detachView()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpViews() {
|
private fun setUpViews() {
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
setupContainerHeight()
|
setupContainerHeight()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupContainerHeight() {
|
private fun setupContainerHeight() {
|
||||||
imageContainer?.let {
|
imageContainer?.let {
|
||||||
val params = it.layoutParams
|
val params = it.layoutParams
|
||||||
params.width = DensityUtil.getScreenHeight(this) / 2
|
params.width = DensityUtil.getScreenHeight(this) / 2
|
||||||
it.layoutParams = params
|
it.layoutParams = params
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupRecyclerView() {
|
||||||
|
albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), false, null)
|
||||||
|
albumRecyclerView.apply {
|
||||||
|
itemAnimator = DefaultItemAnimator()
|
||||||
|
layoutManager = GridLayoutManager(this.context, 1, GridLayoutManager.HORIZONTAL, false)
|
||||||
|
adapter = albumAdapter
|
||||||
|
}
|
||||||
|
songAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song)
|
||||||
|
recyclerView.apply {
|
||||||
|
itemAnimator = DefaultItemAnimator()
|
||||||
|
layoutManager = LinearLayoutManager(this.context)
|
||||||
|
adapter = songAdapter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupRecyclerView() {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), false, null)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
albumRecyclerView.apply {
|
when (requestCode) {
|
||||||
itemAnimator = DefaultItemAnimator()
|
REQUEST_CODE_SELECT_IMAGE -> if (resultCode == Activity.RESULT_OK) {
|
||||||
layoutManager = GridLayoutManager(this.context, 1, GridLayoutManager.HORIZONTAL, false)
|
data?.data?.let {
|
||||||
adapter = albumAdapter
|
CustomArtistImageUtil.getInstance(this).setCustomArtistImage(artist, it)
|
||||||
}
|
}
|
||||||
songAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song)
|
}
|
||||||
recyclerView.apply {
|
else -> if (resultCode == Activity.RESULT_OK) {
|
||||||
itemAnimator = DefaultItemAnimator()
|
reload()
|
||||||
layoutManager = LinearLayoutManager(this.context)
|
}
|
||||||
adapter = songAdapter
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
override fun showEmptyView() {
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun showEmptyView() {
|
override fun complete() {
|
||||||
|
ActivityCompat.startPostponedEnterTransition(this)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
override fun artist(artist: Artist) {
|
||||||
|
if (artist.songCount <= 0) {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
this.artist = artist
|
||||||
|
loadArtistImage()
|
||||||
|
|
||||||
override fun complete() {
|
if (RetroUtil.isAllowedToDownloadMetadata(this)) {
|
||||||
ActivityCompat.startPostponedEnterTransition(this)
|
loadBiography(artist.name)
|
||||||
}
|
}
|
||||||
|
artistTitle.text = artist.name
|
||||||
|
text.text = String.format(
|
||||||
|
"%s • %s",
|
||||||
|
MusicUtil.getArtistInfoString(this, artist),
|
||||||
|
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, artist.songs))
|
||||||
|
)
|
||||||
|
|
||||||
override fun artist(artist: Artist) {
|
songAdapter.swapDataSet(artist.songs)
|
||||||
if (artist.songCount <= 0) {
|
albumAdapter.swapDataSet(artist.albums!!)
|
||||||
finish()
|
}
|
||||||
}
|
|
||||||
this.artist = artist
|
|
||||||
loadArtistImage()
|
|
||||||
|
|
||||||
if (RetroUtil.isAllowedToDownloadMetadata(this)) {
|
private fun loadBiography(
|
||||||
loadBiography(artist.name)
|
name: String, lang: String? = Locale.getDefault().language
|
||||||
}
|
) {
|
||||||
artistTitle.text = artist.name
|
biography = null
|
||||||
text.text = String.format("%s • %s", MusicUtil.getArtistInfoString(this, artist), MusicUtil
|
this.lang = lang
|
||||||
.getReadableDurationString(MusicUtil.getTotalDuration(this, artist.songs)))
|
artistDetailsPresenter.loadBiography(name, lang, null)
|
||||||
|
}
|
||||||
|
|
||||||
songAdapter.swapDataSet(artist.songs)
|
override fun artistInfo(lastFmArtist: LastFmArtist?) {
|
||||||
albumAdapter.swapDataSet(artist.albums!!)
|
if (lastFmArtist != null && lastFmArtist.artist != null) {
|
||||||
}
|
val bioContent = lastFmArtist.artist.bio.content
|
||||||
|
if (bioContent != null && bioContent.trim { it <= ' ' }.isNotEmpty()) {
|
||||||
|
biographyText.visibility = View.VISIBLE
|
||||||
|
biographyTitle.visibility = View.VISIBLE
|
||||||
|
biography = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
Html.fromHtml(bioContent, Html.FROM_HTML_MODE_LEGACY)
|
||||||
|
} else {
|
||||||
|
Html.fromHtml(bioContent)
|
||||||
|
}
|
||||||
|
biographyText.text = biography
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun loadBiography(name: String,
|
// If the "lang" parameter is set and no biography is given, retry with default language
|
||||||
lang: String? = Locale.getDefault().language) {
|
if (biography == null && lang != null) {
|
||||||
biography = null
|
loadBiography(artist.name, null)
|
||||||
this.lang = lang
|
}
|
||||||
artistDetailsPresenter.loadBiography(name, lang, null)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun artistInfo(lastFmArtist: LastFmArtist?) {
|
private var lang: String? = null
|
||||||
if (lastFmArtist != null && lastFmArtist.artist != null) {
|
|
||||||
val bioContent = lastFmArtist.artist.bio.content
|
|
||||||
if (bioContent != null && bioContent.trim { it <= ' ' }.isNotEmpty()) {
|
|
||||||
biographyText.visibility = View.VISIBLE
|
|
||||||
biographyTitle.visibility = View.VISIBLE
|
|
||||||
biography = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
||||||
Html.fromHtml(bioContent, Html.FROM_HTML_MODE_LEGACY)
|
|
||||||
} else {
|
|
||||||
Html.fromHtml(bioContent)
|
|
||||||
}
|
|
||||||
biographyText.text = biography
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the "lang" parameter is set and no biography is given, retry with default language
|
private fun loadArtistImage() {
|
||||||
if (biography == null && lang != null) {
|
ArtistGlideRequest.Builder.from(Glide.with(this), artist).generatePalette(this).build()
|
||||||
loadBiography(artist.name, null)
|
.dontAnimate().into(object : RetroMusicColoredTarget(artistImage) {
|
||||||
}
|
override fun onColorReady(color: Int) {
|
||||||
}
|
setColors(color)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private var lang: String? = null
|
private fun setColors(color: Int) {
|
||||||
|
|
||||||
private fun loadArtistImage() {
|
val textColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color
|
||||||
ArtistGlideRequest.Builder.from(Glide.with(this), artist)
|
else ThemeStore.accentColor(this)
|
||||||
.generatePalette(this).build()
|
|
||||||
.dontAnimate()
|
|
||||||
.into(object : RetroMusicColoredTarget(artistImage) {
|
|
||||||
override fun onColorReady(color: Int) {
|
|
||||||
setColors(color)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setColors(color: Int) {
|
albumTitle.setTextColor(textColor)
|
||||||
|
songTitle.setTextColor(textColor)
|
||||||
|
biographyTitle.setTextColor(textColor)
|
||||||
|
|
||||||
val textColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color
|
val buttonColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color
|
||||||
else ThemeStore.accentColor(this)
|
else ATHUtil.resolveColor(this, R.attr.cardBackgroundColor)
|
||||||
|
|
||||||
albumTitle.setTextColor(textColor)
|
MaterialUtil.setTint(button = shuffleAction, color = buttonColor)
|
||||||
songTitle.setTextColor(textColor)
|
MaterialUtil.setTint(button = playAction, color = buttonColor)
|
||||||
biographyTitle.setTextColor(textColor)
|
|
||||||
|
|
||||||
val buttonColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color
|
toolbar.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
||||||
else ATHUtil.resolveColor(this, R.attr.cardBackgroundColor)
|
setSupportActionBar(toolbar)
|
||||||
|
supportActionBar?.title = null
|
||||||
|
}
|
||||||
|
|
||||||
MaterialUtil.setTint(button = shuffleAction, color = buttonColor)
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
MaterialUtil.setTint(button = playAction, color = buttonColor)
|
return handleSortOrderMenuItem(item)
|
||||||
|
}
|
||||||
|
|
||||||
toolbar.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
|
||||||
setSupportActionBar(toolbar)
|
val songs = artist.songs
|
||||||
supportActionBar?.title = null
|
when (item.itemId) {
|
||||||
}
|
android.R.id.home -> {
|
||||||
|
super.onBackPressed()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
R.id.action_play_next -> {
|
||||||
|
MusicPlayerRemote.playNext(songs)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
R.id.action_add_to_current_playing -> {
|
||||||
|
MusicPlayerRemote.enqueue(songs)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
R.id.action_add_to_playlist -> {
|
||||||
|
AddToPlaylistDialog.create(songs).show(supportFragmentManager, "ADD_PLAYLIST")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
R.id.action_set_artist_image -> {
|
||||||
|
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||||
|
intent.type = "image/*"
|
||||||
|
startActivityForResult(
|
||||||
|
Intent.createChooser(
|
||||||
|
intent,
|
||||||
|
getString(R.string.pick_from_local_storage)
|
||||||
|
), REQUEST_CODE_SELECT_IMAGE
|
||||||
|
)
|
||||||
|
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)
|
||||||
|
forceDownload = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
|
menuInflater.inflate(R.menu.menu_artist_detail, menu)
|
||||||
|
return super.onCreateOptionsMenu(menu)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onMediaStoreChanged() {
|
||||||
return handleSortOrderMenuItem(item)
|
super.onMediaStoreChanged()
|
||||||
}
|
reload()
|
||||||
|
}
|
||||||
|
|
||||||
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
|
private fun reload() {
|
||||||
val songs = artist.songs
|
if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) {
|
||||||
when (item.itemId) {
|
intent.extras?.getInt(EXTRA_ARTIST_ID)?.let { artistDetailsPresenter.loadArtist(it) }
|
||||||
android.R.id.home -> {
|
} else {
|
||||||
super.onBackPressed()
|
finish()
|
||||||
return true
|
}
|
||||||
}
|
}
|
||||||
R.id.action_play_next -> {
|
|
||||||
MusicPlayerRemote.playNext(songs)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
R.id.action_add_to_current_playing -> {
|
|
||||||
MusicPlayerRemote.enqueue(songs)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
R.id.action_add_to_playlist -> {
|
|
||||||
AddToPlaylistDialog.create(songs).show(supportFragmentManager, "ADD_PLAYLIST")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
R.id.action_set_artist_image -> {
|
|
||||||
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
|
||||||
intent.type = "image/*"
|
|
||||||
startActivityForResult(Intent.createChooser(intent, getString(R.string.pick_from_local_storage)), REQUEST_CODE_SELECT_IMAGE)
|
|
||||||
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)
|
|
||||||
forceDownload = true
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
companion object {
|
||||||
menuInflater.inflate(R.menu.menu_artist_detail, menu)
|
|
||||||
return super.onCreateOptionsMenu(menu)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMediaStoreChanged() {
|
const val EXTRA_ARTIST_ID = "extra_artist_id"
|
||||||
super.onMediaStoreChanged()
|
const val REQUEST_CODE_SELECT_IMAGE = 9003
|
||||||
reload()
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun reload() {
|
|
||||||
if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) {
|
|
||||||
intent.extras?.getInt(EXTRA_ARTIST_ID)?.let { artistDetailsPresenter.loadArtist(it) }
|
|
||||||
} else {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
const val EXTRA_ARTIST_ID = "extra_artist_id"
|
|
||||||
const val REQUEST_CODE_SELECT_IMAGE = 9003
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,26 +2,18 @@ package code.name.monkey.retromusic.activities
|
||||||
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.*
|
||||||
import android.view.MenuItem
|
import androidx.recyclerview.widget.*
|
||||||
import android.view.View
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
import code.name.monkey.retromusic.*
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
|
||||||
import code.name.monkey.retromusic.App
|
|
||||||
import code.name.monkey.retromusic.R
|
|
||||||
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
|
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
|
||||||
import code.name.monkey.retromusic.adapter.song.ShuffleButtonSongAdapter
|
import code.name.monkey.retromusic.adapter.song.ShuffleButtonSongAdapter
|
||||||
import code.name.monkey.retromusic.extensions.applyToolbar
|
import code.name.monkey.retromusic.extensions.applyToolbar
|
||||||
import code.name.monkey.retromusic.helper.menu.GenreMenuHelper
|
import code.name.monkey.retromusic.helper.menu.GenreMenuHelper
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.model.Genre
|
import code.name.monkey.retromusic.model.*
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.mvp.presenter.*
|
||||||
import code.name.monkey.retromusic.mvp.presenter.GenreDetailsPresenter
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.mvp.presenter.GenreDetailsView
|
|
||||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
|
||||||
import code.name.monkey.retromusic.util.ViewUtil
|
import code.name.monkey.retromusic.util.ViewUtil
|
||||||
import com.afollestad.materialcab.MaterialCab
|
import com.afollestad.materialcab.MaterialCab
|
||||||
import kotlinx.android.synthetic.main.activity_playlist_detail.*
|
import kotlinx.android.synthetic.main.activity_playlist_detail.*
|
||||||
|
@ -34,124 +26,127 @@ import javax.inject.Inject
|
||||||
|
|
||||||
class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder, GenreDetailsView {
|
class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder, GenreDetailsView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var genreDetailsPresenter: GenreDetailsPresenter
|
lateinit var genreDetailsPresenter: GenreDetailsPresenter
|
||||||
|
|
||||||
private lateinit var genre: Genre
|
private lateinit var genre: Genre
|
||||||
private lateinit var songAdapter: ShuffleButtonSongAdapter
|
private lateinit var songAdapter: ShuffleButtonSongAdapter
|
||||||
private var cab: MaterialCab? = null
|
private var cab: MaterialCab? = null
|
||||||
|
|
||||||
private fun checkIsEmpty() {
|
private fun checkIsEmpty() {
|
||||||
empty?.visibility = if (songAdapter.itemCount == 0) View.VISIBLE else View.GONE
|
empty?.visibility = if (songAdapter.itemCount == 0) View.VISIBLE else View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setDrawUnderStatusBar()
|
setDrawUnderStatusBar()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
setStatusbarColor(Color.TRANSPARENT)
|
setStatusbarColor(Color.TRANSPARENT)
|
||||||
setNavigationbarColorAuto()
|
setNavigationbarColorAuto()
|
||||||
setTaskDescriptionColorAuto()
|
setTaskDescriptionColorAuto()
|
||||||
setLightNavigationBar(true)
|
setLightNavigationBar(true)
|
||||||
setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
|
setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
|
||||||
toggleBottomNavigationView(true)
|
toggleBottomNavigationView(true)
|
||||||
|
|
||||||
if (intent.extras != null) {
|
if (intent.extras != null) {
|
||||||
genre = intent?.extras?.getParcelable(EXTRA_GENRE_ID)!!
|
genre = intent?.extras?.getParcelable(EXTRA_GENRE_ID)!!
|
||||||
} else {
|
} else {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
setUpToolBar()
|
setUpToolBar()
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
|
|
||||||
App.musicComponent.inject(this)
|
App.musicComponent.inject(this)
|
||||||
genreDetailsPresenter.attachView(this)
|
genreDetailsPresenter.attachView(this)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpToolBar() {
|
private fun setUpToolBar() {
|
||||||
val primaryColor = ATHUtil.resolveColor(this, R.attr.colorPrimary)
|
val primaryColor = ATHUtil.resolveColor(this, R.attr.colorPrimary)
|
||||||
appBarLayout.setBackgroundColor(primaryColor)
|
appBarLayout.setBackgroundColor(primaryColor)
|
||||||
applyToolbar(toolbar)
|
applyToolbar(toolbar)
|
||||||
title = genre.name
|
title = genre.name
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
genreDetailsPresenter.loadGenreSongs(genre.id)
|
genreDetailsPresenter.loadGenreSongs(genre.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
genreDetailsPresenter.detachView()
|
genreDetailsPresenter.detachView()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createContentView(): View {
|
override fun createContentView(): View {
|
||||||
return wrapSlidingMusicPanel(R.layout.activity_playlist_detail)
|
return wrapSlidingMusicPanel(R.layout.activity_playlist_detail)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showEmptyView() {
|
override fun showEmptyView() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
menuInflater.inflate(R.menu.menu_genre_detail, menu)
|
menuInflater.inflate(R.menu.menu_genre_detail, menu)
|
||||||
return super.onCreateOptionsMenu(menu)
|
return super.onCreateOptionsMenu(menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
if (item.itemId == android.R.id.home) {
|
if (item.itemId == android.R.id.home) {
|
||||||
onBackPressed()
|
onBackPressed()
|
||||||
}
|
}
|
||||||
return GenreMenuHelper.handleMenuClick(this, genre, item)
|
return GenreMenuHelper.handleMenuClick(this, genre, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupRecyclerView() {
|
private fun setupRecyclerView() {
|
||||||
ViewUtil.setUpFastScrollRecyclerViewColor(this, recyclerView )
|
ViewUtil.setUpFastScrollRecyclerViewColor(this, recyclerView)
|
||||||
songAdapter = ShuffleButtonSongAdapter(this, ArrayList(), R.layout.item_list, false, this)
|
songAdapter = ShuffleButtonSongAdapter(this, ArrayList(), R.layout.item_list, false, this)
|
||||||
recyclerView.apply {
|
recyclerView.apply {
|
||||||
itemAnimator = DefaultItemAnimator()
|
itemAnimator = DefaultItemAnimator()
|
||||||
layoutManager = LinearLayoutManager(this@GenreDetailsActivity)
|
layoutManager = LinearLayoutManager(this@GenreDetailsActivity)
|
||||||
adapter = songAdapter
|
adapter = songAdapter
|
||||||
}
|
}
|
||||||
songAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
songAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||||
override fun onChanged() {
|
override fun onChanged() {
|
||||||
super.onChanged()
|
super.onChanged()
|
||||||
checkIsEmpty()
|
checkIsEmpty()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun songs(songs: ArrayList<Song>) {
|
override fun songs(songs: ArrayList<Song>) {
|
||||||
songAdapter.swapDataSet(songs)
|
songAdapter.swapDataSet(songs)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
|
override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
|
||||||
if (cab != null && cab!!.isActive) cab!!.finish()
|
if (cab != null && cab!!.isActive) cab!!.finish()
|
||||||
cab = MaterialCab(this, R.id.cab_stub)
|
cab = MaterialCab(this, R.id.cab_stub).setMenu(menuRes)
|
||||||
.setMenu(menuRes)
|
.setCloseDrawableRes(R.drawable.ic_close_white_24dp).setBackgroundColor(
|
||||||
.setCloseDrawableRes(R.drawable.ic_close_white_24dp)
|
RetroColorUtil.shiftBackgroundColorForLightText(
|
||||||
.setBackgroundColor(RetroColorUtil.shiftBackgroundColorForLightText(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
|
ATHUtil.resolveColor(
|
||||||
.start(callback)
|
this,
|
||||||
return cab!!
|
R.attr.colorPrimary
|
||||||
}
|
)
|
||||||
|
)
|
||||||
|
).start(callback)
|
||||||
|
return cab!!
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
if (cab != null && cab!!.isActive)
|
if (cab != null && cab!!.isActive) cab!!.finish()
|
||||||
cab!!.finish()
|
else {
|
||||||
else {
|
recyclerView!!.stopScroll()
|
||||||
recyclerView!!.stopScroll()
|
super.onBackPressed()
|
||||||
super.onBackPressed()
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMediaStoreChanged() {
|
override fun onMediaStoreChanged() {
|
||||||
super.onMediaStoreChanged()
|
super.onMediaStoreChanged()
|
||||||
genreDetailsPresenter.loadGenreSongs(genre.id)
|
genreDetailsPresenter.loadGenreSongs(genre.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val EXTRA_GENRE_ID = "extra_genre_id"
|
const val EXTRA_GENRE_ID = "extra_genre_id"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ import java.io.InputStreamReader;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import code.name.monkey.appthemehelper.ThemeStore;
|
import code.name.monkey.appthemehelper.ThemeStore;
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||||
import code.name.monkey.retromusic.R;
|
import code.name.monkey.retromusic.R;
|
||||||
|
|
|
@ -2,110 +2,100 @@ package code.name.monkey.retromusic.activities
|
||||||
|
|
||||||
import android.app.KeyguardManager
|
import android.app.KeyguardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.*
|
||||||
import android.os.Bundle
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import android.view.WindowManager
|
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
|
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
|
||||||
import code.name.monkey.retromusic.fragments.player.lockscreen.LockScreenPlayerControlsFragment
|
import code.name.monkey.retromusic.fragments.player.lockscreen.LockScreenPlayerControlsFragment
|
||||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
import code.name.monkey.retromusic.glide.*
|
||||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.r0adkll.slidr.Slidr
|
import com.r0adkll.slidr.Slidr
|
||||||
import com.r0adkll.slidr.model.SlidrConfig
|
import com.r0adkll.slidr.model.*
|
||||||
import com.r0adkll.slidr.model.SlidrListener
|
|
||||||
import com.r0adkll.slidr.model.SlidrPosition
|
|
||||||
import kotlinx.android.synthetic.main.activity_lock_screen.*
|
import kotlinx.android.synthetic.main.activity_lock_screen.*
|
||||||
|
|
||||||
class LockScreenActivity : AbsMusicServiceActivity() {
|
class LockScreenActivity : AbsMusicServiceActivity() {
|
||||||
private var fragment: LockScreenPlayerControlsFragment? = null
|
private var fragment: LockScreenPlayerControlsFragment? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
||||||
setShowWhenLocked(true)
|
setShowWhenLocked(true)
|
||||||
setTurnScreenOn(true)
|
setTurnScreenOn(true)
|
||||||
} else {
|
} else {
|
||||||
this.window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
|
this.window.addFlags(
|
||||||
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
|
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
|
||||||
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
|
)
|
||||||
}
|
}
|
||||||
setDrawUnderStatusBar()
|
setDrawUnderStatusBar()
|
||||||
setContentView(R.layout.activity_lock_screen)
|
setContentView(R.layout.activity_lock_screen)
|
||||||
|
|
||||||
hideStatusBar()
|
hideStatusBar()
|
||||||
setStatusbarColorAuto()
|
setStatusbarColorAuto()
|
||||||
setNavigationBarColorPrimary()
|
setNavigationBarColorPrimary()
|
||||||
setTaskDescriptionColorAuto()
|
setTaskDescriptionColorAuto()
|
||||||
setLightNavigationBar(true)
|
setLightNavigationBar(true)
|
||||||
|
|
||||||
val config = SlidrConfig.Builder()
|
val config = SlidrConfig.Builder().listener(object : SlidrListener {
|
||||||
.listener(object : SlidrListener {
|
override fun onSlideStateChanged(state: Int) {
|
||||||
override fun onSlideStateChanged(state: Int) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSlideChange(percent: Float) {
|
override fun onSlideChange(percent: Float) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSlideOpened() {
|
override fun onSlideOpened() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSlideClosed(): Boolean {
|
override fun onSlideClosed(): Boolean {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
|
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
|
||||||
keyguardManager.requestDismissKeyguard(this@LockScreenActivity, null)
|
keyguardManager.requestDismissKeyguard(this@LockScreenActivity, null)
|
||||||
}
|
}
|
||||||
finish()
|
finish()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
})
|
}).position(SlidrPosition.BOTTOM).build()
|
||||||
.position(SlidrPosition.BOTTOM)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
Slidr.attach(this, config)
|
Slidr.attach(this, config)
|
||||||
|
|
||||||
fragment = supportFragmentManager.findFragmentById(R.id.playback_controls_fragment) as LockScreenPlayerControlsFragment?
|
fragment = supportFragmentManager.findFragmentById(R.id.playback_controls_fragment) as LockScreenPlayerControlsFragment?
|
||||||
|
|
||||||
findViewById<View>(R.id.slide).apply {
|
findViewById<View>(R.id.slide).apply {
|
||||||
translationY = 100f
|
translationY = 100f
|
||||||
alpha = 0f
|
alpha = 0f
|
||||||
ViewCompat.animate(this)
|
ViewCompat.animate(this).translationY(0f).alpha(1f).setDuration(1500).start()
|
||||||
.translationY(0f)
|
}
|
||||||
.alpha(1f)
|
|
||||||
.setDuration(1500)
|
|
||||||
.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
findViewById<View>(R.id.root_layout).setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
findViewById<View>(R.id.root_layout).setBackgroundColor(
|
||||||
}
|
ATHUtil.resolveColor(
|
||||||
|
this, R.attr.colorPrimary
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onPlayingMetaChanged() {
|
override fun onPlayingMetaChanged() {
|
||||||
super.onPlayingMetaChanged()
|
super.onPlayingMetaChanged()
|
||||||
updateSongs()
|
updateSongs()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onServiceConnected() {
|
override fun onServiceConnected() {
|
||||||
super.onServiceConnected()
|
super.onServiceConnected()
|
||||||
updateSongs()
|
updateSongs()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSongs() {
|
private fun updateSongs() {
|
||||||
val song = MusicPlayerRemote.currentSong
|
val song = MusicPlayerRemote.currentSong
|
||||||
SongGlideRequest.Builder.from(Glide.with(this), song)
|
SongGlideRequest.Builder.from(Glide.with(this), song).checkIgnoreMediaStore(this)
|
||||||
.checkIgnoreMediaStore(this)
|
.generatePalette(this).build().dontAnimate()
|
||||||
.generatePalette(this).build()
|
.into(object : RetroMusicColoredTarget(image) {
|
||||||
.dontAnimate()
|
override fun onColorReady(color: Int) {
|
||||||
.into(object : RetroMusicColoredTarget(image ) {
|
fragment?.setDark(color)
|
||||||
override fun onColorReady(color: Int) {
|
}
|
||||||
fragment?.setDark(color)
|
})
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -95,7 +95,13 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
|
||||||
appBarLayout.setBackgroundColor(primaryColor)
|
appBarLayout.setBackgroundColor(primaryColor)
|
||||||
toolbar.apply {
|
toolbar.apply {
|
||||||
setBackgroundColor(primaryColor)
|
setBackgroundColor(primaryColor)
|
||||||
navigationIcon = TintHelper.createTintedDrawable(ContextCompat.getDrawable(this@LyricsActivity, R.drawable.ic_keyboard_backspace_black_24dp), ThemeStore.textColorSecondary(this@LyricsActivity))
|
navigationIcon = TintHelper.createTintedDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
this@LyricsActivity,
|
||||||
|
R.drawable.ic_keyboard_backspace_black_24dp
|
||||||
|
),
|
||||||
|
ThemeStore.textColorSecondary(this@LyricsActivity)
|
||||||
|
)
|
||||||
setSupportActionBar(toolbar)
|
setSupportActionBar(toolbar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,12 +166,17 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|
||||||
val materialDialog = MaterialDialog(this, BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
val materialDialog = MaterialDialog(
|
||||||
|
this,
|
||||||
|
BottomSheet(LayoutMode.WRAP_CONTENT)
|
||||||
|
).show {
|
||||||
title(R.string.add_time_framed_lryics)
|
title(R.string.add_time_framed_lryics)
|
||||||
negativeButton(R.string.action_search) { RetroUtil.openUrl(this@LyricsActivity, googleSearchLrcUrl) }
|
negativeButton(R.string.action_search) { RetroUtil.openUrl(this@LyricsActivity, googleSearchLrcUrl) }
|
||||||
input(hint = getString(R.string.paste_lyrics_here),
|
input(
|
||||||
|
hint = getString(R.string.paste_lyrics_here),
|
||||||
prefill = content,
|
prefill = content,
|
||||||
inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE) { _, input ->
|
inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE
|
||||||
|
) { _, input ->
|
||||||
LyricUtil.writeLrcToLoc(song.data, song.artistName, input.toString())
|
LyricUtil.writeLrcToLoc(song.data, song.artistName, input.toString())
|
||||||
}
|
}
|
||||||
positiveButton(android.R.string.ok) {
|
positiveButton(android.R.string.ok) {
|
||||||
|
@ -189,12 +200,16 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
|
||||||
lyricsString!!
|
lyricsString!!
|
||||||
}
|
}
|
||||||
|
|
||||||
val materialDialog = MaterialDialog(this, BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
val materialDialog = MaterialDialog(
|
||||||
|
this, BottomSheet(LayoutMode.WRAP_CONTENT)
|
||||||
|
).show {
|
||||||
title(R.string.add_lyrics)
|
title(R.string.add_lyrics)
|
||||||
negativeButton(R.string.action_search) { RetroUtil.openUrl(this@LyricsActivity, getGoogleSearchUrl()) }
|
negativeButton(R.string.action_search) { RetroUtil.openUrl(this@LyricsActivity, getGoogleSearchUrl()) }
|
||||||
input(hint = getString(R.string.paste_lyrics_here),
|
input(
|
||||||
|
hint = getString(R.string.paste_lyrics_here),
|
||||||
prefill = content,
|
prefill = content,
|
||||||
inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE) { _, input ->
|
inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE
|
||||||
|
) { _, input ->
|
||||||
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
||||||
fieldKeyValueMap[FieldKey.LYRICS] = input.toString()
|
fieldKeyValueMap[FieldKey.LYRICS] = input.toString()
|
||||||
WriteTagsAsyncTask(this@LyricsActivity).execute(WriteTagsAsyncTask.LoadingInfo(getSongPaths(song), fieldKeyValueMap, null))
|
WriteTagsAsyncTask(this@LyricsActivity).execute(WriteTagsAsyncTask.LoadingInfo(getSongPaths(song), fieldKeyValueMap, null))
|
||||||
|
@ -221,8 +236,10 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
|
||||||
}
|
}
|
||||||
|
|
||||||
class PagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
|
class PagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
|
||||||
class Tabs(@StringRes val title: Int,
|
class Tabs(
|
||||||
val fragment: Fragment)
|
@StringRes val title: Int,
|
||||||
|
val fragment: Fragment
|
||||||
|
)
|
||||||
|
|
||||||
private var tabs = ArrayList<Tabs>()
|
private var tabs = ArrayList<Tabs>()
|
||||||
|
|
||||||
|
|
|
@ -12,288 +12,263 @@ import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
|
||||||
import code.name.monkey.retromusic.fragments.mainactivity.LibraryFragment
|
import code.name.monkey.retromusic.fragments.mainactivity.LibraryFragment
|
||||||
import code.name.monkey.retromusic.fragments.mainactivity.folders.FoldersFragment
|
import code.name.monkey.retromusic.fragments.mainactivity.folders.FoldersFragment
|
||||||
import code.name.monkey.retromusic.fragments.mainactivity.home.BannerHomeFragment
|
import code.name.monkey.retromusic.fragments.mainactivity.home.BannerHomeFragment
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.*
|
||||||
import code.name.monkey.retromusic.helper.SearchQueryHelper
|
|
||||||
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
|
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
|
||||||
import code.name.monkey.retromusic.loaders.AlbumLoader
|
import code.name.monkey.retromusic.loaders.*
|
||||||
import code.name.monkey.retromusic.loaders.ArtistLoader
|
|
||||||
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
|
|
||||||
import code.name.monkey.retromusic.service.MusicService
|
import code.name.monkey.retromusic.service.MusicService
|
||||||
import code.name.monkey.retromusic.util.AppRater
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedPreferenceChangeListener {
|
class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
private lateinit var currentFragment: MainActivityFragmentCallbacks
|
private lateinit var currentFragment: MainActivityFragmentCallbacks
|
||||||
|
|
||||||
private var blockRequestPermissions: Boolean = false
|
private var blockRequestPermissions: Boolean = false
|
||||||
private val disposable = CompositeDisposable()
|
private val disposable = CompositeDisposable()
|
||||||
private val broadcastReceiver = object : BroadcastReceiver() {
|
private val broadcastReceiver = object : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
val action = intent.action
|
val action = intent.action
|
||||||
if (action != null && action == Intent.ACTION_SCREEN_OFF) {
|
if (action != null && action == Intent.ACTION_SCREEN_OFF) {
|
||||||
if (PreferenceUtil.getInstance(this@MainActivity).lockScreen && MusicPlayerRemote.isPlaying) {
|
if (PreferenceUtil.getInstance(this@MainActivity).lockScreen && MusicPlayerRemote.isPlaying) {
|
||||||
val activity = Intent(context, LockScreenActivity::class.java)
|
val activity = Intent(context, LockScreenActivity::class.java)
|
||||||
activity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
activity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
activity.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
|
activity.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
|
||||||
ActivityCompat.startActivity(context, activity, null)
|
ActivityCompat.startActivity(context, activity, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createContentView(): View {
|
override fun createContentView(): View {
|
||||||
return wrapSlidingMusicPanel(R.layout.activity_main_content)
|
return wrapSlidingMusicPanel(R.layout.activity_main_content)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(
|
override fun onCreate(
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
) {
|
) {
|
||||||
setDrawUnderStatusBar()
|
setDrawUnderStatusBar()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
getBottomNavigationView().selectedItemId = PreferenceUtil.getInstance(this).lastPage
|
getBottomNavigationView().selectedItemId = PreferenceUtil.getInstance(this).lastPage
|
||||||
|
|
||||||
getBottomNavigationView().setOnNavigationItemSelectedListener {
|
getBottomNavigationView().setOnNavigationItemSelectedListener {
|
||||||
PreferenceUtil.getInstance(this).lastPage = it.itemId
|
PreferenceUtil.getInstance(this).lastPage = it.itemId
|
||||||
selectedFragment(it.itemId)
|
selectedFragment(it.itemId)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
setMusicChooser(PreferenceUtil.getInstance(this).lastMusicChooser)
|
setMusicChooser(PreferenceUtil.getInstance(this).lastMusicChooser)
|
||||||
} else {
|
} else {
|
||||||
restoreCurrentFragment()
|
restoreCurrentFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
checkShowChangelog()
|
checkShowChangelog()
|
||||||
AppRater.appLaunched(this);
|
AppRater.appLaunched(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkShowChangelog() {
|
private fun checkShowChangelog() {
|
||||||
try {
|
try {
|
||||||
val pInfo = packageManager.getPackageInfo(packageName, 0)
|
val pInfo = packageManager.getPackageInfo(packageName, 0)
|
||||||
val currentVersion = pInfo.versionCode
|
val currentVersion = pInfo.versionCode
|
||||||
if (currentVersion != PreferenceUtil.getInstance(this).lastChangelogVersion) {
|
if (currentVersion != PreferenceUtil.getInstance(this).lastChangelogVersion) {
|
||||||
startActivityForResult(Intent(this, WhatsNewActivity::class.java), APP_INTRO_REQUEST)
|
startActivityForResult(
|
||||||
}
|
Intent(this, WhatsNewActivity::class.java),
|
||||||
} catch (e: Throwable) {
|
APP_INTRO_REQUEST
|
||||||
e.printStackTrace()
|
)
|
||||||
}
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
val screenOnOff = IntentFilter()
|
val screenOnOff = IntentFilter()
|
||||||
screenOnOff.addAction(Intent.ACTION_SCREEN_OFF)
|
screenOnOff.addAction(Intent.ACTION_SCREEN_OFF)
|
||||||
registerReceiver(broadcastReceiver, screenOnOff)
|
registerReceiver(broadcastReceiver, screenOnOff)
|
||||||
|
|
||||||
PreferenceUtil.getInstance(this).registerOnSharedPreferenceChangedListener(this)
|
PreferenceUtil.getInstance(this).registerOnSharedPreferenceChangedListener(this)
|
||||||
|
|
||||||
if (intent.hasExtra("expand")) {
|
if (intent.hasExtra("expand")) {
|
||||||
if (intent.getBooleanExtra("expand", false)) {
|
if (intent.getBooleanExtra("expand", false)) {
|
||||||
expandPanel()
|
expandPanel()
|
||||||
intent.putExtra("expand", false)
|
intent.putExtra("expand", false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
disposable.clear()
|
disposable.clear()
|
||||||
unregisterReceiver(broadcastReceiver)
|
unregisterReceiver(broadcastReceiver)
|
||||||
PreferenceUtil.getInstance(this).unregisterOnSharedPreferenceChangedListener(this)
|
PreferenceUtil.getInstance(this).unregisterOnSharedPreferenceChangedListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setCurrentFragment(fragment: Fragment, tag: String) {
|
private fun setCurrentFragment(fragment: Fragment, tag: String) {
|
||||||
println("setCurrentFragment -> $tag -> ${supportFragmentManager.findFragmentById(R.id.fragment_container)?.tag}")
|
println("setCurrentFragment -> $tag -> ${supportFragmentManager.findFragmentById(R.id.fragment_container)?.tag}")
|
||||||
if (tag != supportFragmentManager.findFragmentById(R.id.fragment_container)?.tag) {
|
if (tag != supportFragmentManager.findFragmentById(R.id.fragment_container)?.tag) {
|
||||||
supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment, tag).commit()
|
supportFragmentManager.beginTransaction()
|
||||||
currentFragment = fragment as MainActivityFragmentCallbacks
|
.replace(R.id.fragment_container, fragment, tag).commit()
|
||||||
}
|
currentFragment = fragment as MainActivityFragmentCallbacks
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun restoreCurrentFragment() {
|
private fun restoreCurrentFragment() {
|
||||||
currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container) as MainActivityFragmentCallbacks
|
currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container) as MainActivityFragmentCallbacks
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handlePlaybackIntent(intent: Intent?) {
|
private fun handlePlaybackIntent(intent: Intent?) {
|
||||||
if (intent == null) {
|
if (intent == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val uri = intent.data
|
val uri = intent.data
|
||||||
val mimeType = intent.type
|
val mimeType = intent.type
|
||||||
var handled = false
|
var handled = false
|
||||||
if (intent.action != null && intent.action == MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) {
|
if (intent.action != null && intent.action == MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) {
|
||||||
val songs = SearchQueryHelper.getSongs(this, intent.extras!!)
|
val songs = SearchQueryHelper.getSongs(this, intent.extras!!)
|
||||||
if (MusicPlayerRemote.shuffleMode == MusicService.SHUFFLE_MODE_SHUFFLE) {
|
if (MusicPlayerRemote.shuffleMode == MusicService.SHUFFLE_MODE_SHUFFLE) {
|
||||||
MusicPlayerRemote.openAndShuffleQueue(songs, true)
|
MusicPlayerRemote.openAndShuffleQueue(songs, true)
|
||||||
} else {
|
} else {
|
||||||
MusicPlayerRemote.openQueue(songs, 0, true)
|
MusicPlayerRemote.openQueue(songs, 0, true)
|
||||||
}
|
}
|
||||||
handled = true
|
handled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uri != null && uri.toString().isNotEmpty()) {
|
if (uri != null && uri.toString().isNotEmpty()) {
|
||||||
MusicPlayerRemote.playFromUri(uri)
|
MusicPlayerRemote.playFromUri(uri)
|
||||||
handled = true
|
handled = true
|
||||||
} else if (MediaStore.Audio.Playlists.CONTENT_TYPE == mimeType) {
|
} else if (MediaStore.Audio.Playlists.CONTENT_TYPE == mimeType) {
|
||||||
val id = parseIdFromIntent(intent, "playlistId", "playlist").toInt()
|
val id = parseIdFromIntent(intent, "playlistId", "playlist").toInt()
|
||||||
if (id >= 0) {
|
if (id >= 0) {
|
||||||
val position = intent.getIntExtra("position", 0)
|
val position = intent.getIntExtra("position", 0)
|
||||||
val songs = ArrayList(PlaylistSongsLoader.getPlaylistSongList(this, id))
|
val songs = ArrayList(PlaylistSongsLoader.getPlaylistSongList(this, id))
|
||||||
MusicPlayerRemote.openQueue(songs, position, true)
|
MusicPlayerRemote.openQueue(songs, position, true)
|
||||||
handled = true
|
handled = true
|
||||||
}
|
}
|
||||||
} else if (MediaStore.Audio.Albums.CONTENT_TYPE == mimeType) {
|
} else if (MediaStore.Audio.Albums.CONTENT_TYPE == mimeType) {
|
||||||
val id = parseIdFromIntent(intent, "albumId", "album").toInt()
|
val id = parseIdFromIntent(intent, "albumId", "album").toInt()
|
||||||
if (id >= 0) {
|
if (id >= 0) {
|
||||||
val position = intent.getIntExtra("position", 0)
|
val position = intent.getIntExtra("position", 0)
|
||||||
MusicPlayerRemote.openQueue(AlbumLoader.getAlbum(this, id).songs!!, position, true)
|
MusicPlayerRemote.openQueue(AlbumLoader.getAlbum(this, id).songs!!, position, true)
|
||||||
handled = true
|
handled = true
|
||||||
}
|
}
|
||||||
} else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) {
|
} else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) {
|
||||||
val id = parseIdFromIntent(intent, "artistId", "artist").toInt()
|
val id = parseIdFromIntent(intent, "artistId", "artist").toInt()
|
||||||
if (id >= 0) {
|
if (id >= 0) {
|
||||||
val position = intent.getIntExtra("position", 0)
|
val position = intent.getIntExtra("position", 0)
|
||||||
MusicPlayerRemote.openQueue(ArtistLoader.getArtist(this, id).songs, position, true)
|
MusicPlayerRemote.openQueue(ArtistLoader.getArtist(this, id).songs, position, true)
|
||||||
handled = true
|
handled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (handled) {
|
if (handled) {
|
||||||
setIntent(Intent())
|
setIntent(Intent())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseIdFromIntent(intent: Intent, longKey: String, stringKey: String): Long {
|
private fun parseIdFromIntent(intent: Intent, longKey: String, stringKey: String): Long {
|
||||||
var id = intent.getLongExtra(longKey, -1)
|
var id = intent.getLongExtra(longKey, -1)
|
||||||
if (id < 0) {
|
if (id < 0) {
|
||||||
val idString = intent.getStringExtra(stringKey)
|
val idString = intent.getStringExtra(stringKey)
|
||||||
if (idString != null) {
|
if (idString != null) {
|
||||||
try {
|
try {
|
||||||
id = java.lang.Long.parseLong(idString)
|
id = java.lang.Long.parseLong(idString)
|
||||||
} catch (e: NumberFormatException) {
|
} catch (e: NumberFormatException) {
|
||||||
Log.e(TAG, e.message)
|
Log.e(TAG, e.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
when (requestCode) {
|
when (requestCode) {
|
||||||
APP_INTRO_REQUEST -> {
|
APP_INTRO_REQUEST -> {
|
||||||
blockRequestPermissions = false
|
blockRequestPermissions = false
|
||||||
if (!hasPermissions()) {
|
if (!hasPermissions()) {
|
||||||
requestPermissions()
|
requestPermissions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
REQUEST_CODE_THEME, APP_USER_INFO_REQUEST -> postRecreate()
|
REQUEST_CODE_THEME, APP_USER_INFO_REQUEST -> postRecreate()
|
||||||
PURCHASE_REQUEST -> {
|
PURCHASE_REQUEST -> {
|
||||||
if (resultCode == RESULT_OK) {
|
if (resultCode == RESULT_OK) {
|
||||||
//checkSetUpPro();
|
//checkSetUpPro();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleBackPress(): Boolean {
|
override fun handleBackPress(): Boolean {
|
||||||
return super.handleBackPress() || currentFragment.handleBackPress()
|
return super.handleBackPress() || currentFragment.handleBackPress()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onServiceConnected() {
|
override fun onServiceConnected() {
|
||||||
super.onServiceConnected()
|
super.onServiceConnected()
|
||||||
handlePlaybackIntent(intent)
|
handlePlaybackIntent(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun requestPermissions() {
|
override fun requestPermissions() {
|
||||||
if (!blockRequestPermissions) {
|
if (!blockRequestPermissions) {
|
||||||
super.requestPermissions()
|
super.requestPermissions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||||
if (key == PreferenceUtil.GENERAL_THEME ||
|
if (key == PreferenceUtil.GENERAL_THEME || key == PreferenceUtil.BLACK_THEME || key == PreferenceUtil.ADAPTIVE_COLOR_APP || key == PreferenceUtil.DOMINANT_COLOR || key == PreferenceUtil.USER_NAME || key == PreferenceUtil.TOGGLE_FULL_SCREEN || key == PreferenceUtil.TOGGLE_VOLUME || key == PreferenceUtil.ROUND_CORNERS || key == PreferenceUtil.CAROUSEL_EFFECT || key == PreferenceUtil.NOW_PLAYING_SCREEN_ID || key == PreferenceUtil.TOGGLE_GENRE || key == PreferenceUtil.BANNER_IMAGE_PATH || key == PreferenceUtil.PROFILE_IMAGE_PATH || key == PreferenceUtil.CIRCULAR_ALBUM_ART || key == PreferenceUtil.KEEP_SCREEN_ON || key == PreferenceUtil.TOGGLE_SEPARATE_LINE || key == PreferenceUtil.ALBUM_GRID_STYLE || key == PreferenceUtil.ARTIST_GRID_STYLE || key == PreferenceUtil.TOGGLE_HOME_BANNER || key == PreferenceUtil.TOGGLE_ADD_CONTROLS || key == PreferenceUtil.ALBUM_COVER_STYLE || key == PreferenceUtil.HOME_ARTIST_GRID_STYLE || key == PreferenceUtil.ALBUM_COVER_TRANSFORM || key == PreferenceUtil.DESATURATED_COLOR || key == PreferenceUtil.TAB_TEXT_MODE || key == PreferenceUtil.LIBRARY_CATEGORIES) postRecreate()
|
||||||
key == PreferenceUtil.BLACK_THEME ||
|
|
||||||
key == PreferenceUtil.ADAPTIVE_COLOR_APP ||
|
|
||||||
key == PreferenceUtil.DOMINANT_COLOR ||
|
|
||||||
key == PreferenceUtil.USER_NAME ||
|
|
||||||
key == PreferenceUtil.TOGGLE_FULL_SCREEN ||
|
|
||||||
key == PreferenceUtil.TOGGLE_VOLUME ||
|
|
||||||
key == PreferenceUtil.ROUND_CORNERS ||
|
|
||||||
key == PreferenceUtil.CAROUSEL_EFFECT ||
|
|
||||||
key == PreferenceUtil.NOW_PLAYING_SCREEN_ID ||
|
|
||||||
key == PreferenceUtil.TOGGLE_GENRE ||
|
|
||||||
key == PreferenceUtil.BANNER_IMAGE_PATH ||
|
|
||||||
key == PreferenceUtil.PROFILE_IMAGE_PATH ||
|
|
||||||
key == PreferenceUtil.CIRCULAR_ALBUM_ART ||
|
|
||||||
key == PreferenceUtil.KEEP_SCREEN_ON ||
|
|
||||||
key == PreferenceUtil.TOGGLE_SEPARATE_LINE ||
|
|
||||||
key == PreferenceUtil.ALBUM_GRID_STYLE ||
|
|
||||||
key == PreferenceUtil.ARTIST_GRID_STYLE ||
|
|
||||||
key == PreferenceUtil.TOGGLE_HOME_BANNER ||
|
|
||||||
key == PreferenceUtil.TOGGLE_ADD_CONTROLS ||
|
|
||||||
key == PreferenceUtil.ALBUM_COVER_STYLE ||
|
|
||||||
key == PreferenceUtil.HOME_ARTIST_GRID_STYLE ||
|
|
||||||
key == PreferenceUtil.ALBUM_COVER_TRANSFORM ||
|
|
||||||
key == PreferenceUtil.DESATURATED_COLOR ||
|
|
||||||
key == PreferenceUtil.TAB_TEXT_MODE ||
|
|
||||||
key == PreferenceUtil.LIBRARY_CATEGORIES)
|
|
||||||
postRecreate()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showPromotionalOffer() {
|
private fun showPromotionalOffer() {
|
||||||
/*MaterialDialog(this).show {
|
/*MaterialDialog(this).show {
|
||||||
positiveButton(text = "Buy") { startActivity(Intent(this@MainActivity, PurchaseActivity::class.java)) }
|
positiveButton(text = "Buy") { startActivity(Intent(this@MainActivity, PurchaseActivity::class.java)) }
|
||||||
negativeButton(android.R.string.cancel)
|
negativeButton(android.R.string.cancel)
|
||||||
customView(R.layout.dialog_promotional_offer)
|
customView(R.layout.dialog_promotional_offer)
|
||||||
onDismiss {
|
onDismiss {
|
||||||
PreferenceManager.getDefaultSharedPreferences(this@MainActivity)
|
PreferenceManager.getDefaultSharedPreferences(this@MainActivity)
|
||||||
.edit()
|
.edit()
|
||||||
.putBoolean("shown", true)
|
.putBoolean("shown", true)
|
||||||
.apply()
|
.apply()
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun selectedFragment(itemId: Int) {
|
private fun selectedFragment(itemId: Int) {
|
||||||
when (itemId) {
|
when (itemId) {
|
||||||
R.id.action_album,
|
R.id.action_album, R.id.action_artist, R.id.action_playlist, R.id.action_genre, R.id.action_song -> setCurrentFragment(
|
||||||
R.id.action_artist,
|
LibraryFragment.newInstance(itemId),
|
||||||
R.id.action_playlist,
|
itemId.toString()
|
||||||
R.id.action_genre,
|
)
|
||||||
R.id.action_song -> setCurrentFragment(LibraryFragment.newInstance(itemId), itemId.toString())
|
R.id.action_home -> setCurrentFragment(
|
||||||
R.id.action_home -> setCurrentFragment(BannerHomeFragment.newInstance(), BannerHomeFragment.TAG)
|
BannerHomeFragment.newInstance(),
|
||||||
else -> {
|
BannerHomeFragment.TAG
|
||||||
setCurrentFragment(BannerHomeFragment.newInstance(), BannerHomeFragment.TAG)
|
)
|
||||||
}
|
else -> {
|
||||||
}
|
setCurrentFragment(BannerHomeFragment.newInstance(), BannerHomeFragment.TAG)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun setMusicChooser(key: Int) {
|
fun setMusicChooser(key: Int) {
|
||||||
PreferenceUtil.getInstance(this).lastMusicChooser = key
|
PreferenceUtil.getInstance(this).lastMusicChooser = key
|
||||||
when (key) {
|
when (key) {
|
||||||
FOLDER -> setCurrentFragment(FoldersFragment.newInstance(this), FoldersFragment.TAG)
|
FOLDER -> setCurrentFragment(FoldersFragment.newInstance(this), FoldersFragment.TAG)
|
||||||
else -> selectedFragment(PreferenceUtil.getInstance(this).lastPage)
|
else -> selectedFragment(PreferenceUtil.getInstance(this).lastPage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val APP_INTRO_REQUEST = 2323
|
const val APP_INTRO_REQUEST = 2323
|
||||||
const val HOME = 0
|
const val HOME = 0
|
||||||
const val FOLDER = 1
|
const val FOLDER = 1
|
||||||
const val LIBRARY = 2
|
const val LIBRARY = 2
|
||||||
private const val TAG = "MainActivity"
|
private const val TAG = "MainActivity"
|
||||||
private const val APP_USER_INFO_REQUEST = 9003
|
private const val APP_USER_INFO_REQUEST = 9003
|
||||||
private const val REQUEST_CODE_THEME = 9002
|
private const val REQUEST_CODE_THEME = 9002
|
||||||
private const val PURCHASE_REQUEST = 101
|
private const val PURCHASE_REQUEST = 101
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,182 +3,186 @@ package code.name.monkey.retromusic.activities
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.*
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
|
||||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
|
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
|
||||||
import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter
|
import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter
|
||||||
import code.name.monkey.retromusic.extensions.applyToolbar
|
import code.name.monkey.retromusic.extensions.applyToolbar
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.ViewUtil
|
import code.name.monkey.retromusic.util.ViewUtil
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator
|
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager
|
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
|
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
|
||||||
import kotlinx.android.synthetic.main.activity_playing_queue.*
|
import kotlinx.android.synthetic.main.activity_playing_queue.*
|
||||||
|
|
||||||
|
|
||||||
open class PlayingQueueActivity : AbsMusicServiceActivity() {
|
open class PlayingQueueActivity : AbsMusicServiceActivity() {
|
||||||
|
|
||||||
private var wrappedAdapter: RecyclerView.Adapter<*>? = null
|
private var wrappedAdapter: RecyclerView.Adapter<*>? = null
|
||||||
private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null
|
private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null
|
||||||
private var playingQueueAdapter: PlayingQueueAdapter? = null
|
private var playingQueueAdapter: PlayingQueueAdapter? = null
|
||||||
private lateinit var linearLayoutManager: LinearLayoutManager
|
private lateinit var linearLayoutManager: LinearLayoutManager
|
||||||
|
|
||||||
|
private fun getUpNextAndQueueTime(): String {
|
||||||
|
val duration = MusicPlayerRemote.getQueueDurationMillis(MusicPlayerRemote.position)
|
||||||
|
|
||||||
private fun getUpNextAndQueueTime(): String {
|
return MusicUtil.buildInfoString(
|
||||||
val duration = MusicPlayerRemote.getQueueDurationMillis(MusicPlayerRemote.position)
|
resources.getString(R.string.up_next), MusicUtil.getReadableDurationString(duration)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return MusicUtil.buildInfoString(
|
override fun onCreate(
|
||||||
resources.getString(R.string.up_next),
|
savedInstanceState: Bundle?
|
||||||
MusicUtil.getReadableDurationString(duration)
|
) {
|
||||||
)
|
super.onCreate(savedInstanceState)
|
||||||
}
|
setContentView(R.layout.activity_playing_queue)
|
||||||
|
|
||||||
override fun onCreate(
|
setStatusbarColorAuto()
|
||||||
savedInstanceState: Bundle?
|
setNavigationBarColorPrimary()
|
||||||
) {
|
setTaskDescriptionColorAuto()
|
||||||
super.onCreate(savedInstanceState)
|
setLightNavigationBar(true)
|
||||||
setContentView(R.layout.activity_playing_queue)
|
|
||||||
|
|
||||||
setStatusbarColorAuto()
|
setupToolbar()
|
||||||
setNavigationBarColorPrimary()
|
setUpRecyclerView()
|
||||||
setTaskDescriptionColorAuto()
|
|
||||||
setLightNavigationBar(true)
|
|
||||||
|
|
||||||
setupToolbar()
|
clearQueue.setOnClickListener {
|
||||||
setUpRecyclerView()
|
MusicPlayerRemote.clearQueue()
|
||||||
|
}
|
||||||
|
checkForPadding()
|
||||||
|
}
|
||||||
|
|
||||||
clearQueue.setOnClickListener {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
MusicPlayerRemote.clearQueue()
|
return when (item.itemId) {
|
||||||
}
|
android.R.id.home -> {
|
||||||
checkForPadding()
|
onBackPressed()
|
||||||
}
|
true
|
||||||
|
}
|
||||||
|
else -> super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
private fun setUpRecyclerView() {
|
||||||
return when (item.itemId) {
|
recyclerViewDragDropManager = RecyclerViewDragDropManager()
|
||||||
android.R.id.home -> {
|
val animator = RefactoredDefaultItemAnimator()
|
||||||
onBackPressed()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
else -> super.onOptionsItemSelected(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setUpRecyclerView() {
|
playingQueueAdapter = PlayingQueueAdapter(
|
||||||
recyclerViewDragDropManager = RecyclerViewDragDropManager()
|
this,
|
||||||
val animator = RefactoredDefaultItemAnimator()
|
MusicPlayerRemote.playingQueue,
|
||||||
|
MusicPlayerRemote.position,
|
||||||
|
R.layout.item_queue
|
||||||
|
)
|
||||||
|
wrappedAdapter = recyclerViewDragDropManager?.createWrappedAdapter(playingQueueAdapter!!)
|
||||||
|
|
||||||
playingQueueAdapter = PlayingQueueAdapter(
|
linearLayoutManager = LinearLayoutManager(this)
|
||||||
this,
|
|
||||||
MusicPlayerRemote.playingQueue,
|
|
||||||
MusicPlayerRemote.position,
|
|
||||||
R.layout.item_queue)
|
|
||||||
wrappedAdapter = recyclerViewDragDropManager?.createWrappedAdapter(playingQueueAdapter!!)
|
|
||||||
|
|
||||||
linearLayoutManager = LinearLayoutManager(this)
|
recyclerView.apply {
|
||||||
|
layoutManager = linearLayoutManager
|
||||||
|
adapter = wrappedAdapter
|
||||||
|
itemAnimator = animator
|
||||||
|
recyclerViewDragDropManager?.attachRecyclerView(this)
|
||||||
|
}
|
||||||
|
|
||||||
recyclerView.apply {
|
linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
|
||||||
layoutManager = linearLayoutManager
|
|
||||||
adapter = wrappedAdapter
|
|
||||||
itemAnimator = animator
|
|
||||||
recyclerViewDragDropManager?.attachRecyclerView(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
|
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
|
super.onScrolled(recyclerView, dx, dy)
|
||||||
|
if (dy > 0) {
|
||||||
|
clearQueue.shrink()
|
||||||
|
} else if (dy < 0) {
|
||||||
|
clearQueue.extend()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
ViewUtil.setUpFastScrollRecyclerViewColor(this, recyclerView)
|
||||||
|
}
|
||||||
|
|
||||||
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
private fun checkForPadding() {
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
|
||||||
if (dy > 0) {
|
|
||||||
clearQueue.shrink()
|
|
||||||
} else if (dy < 0) {
|
|
||||||
clearQueue.extend()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
ViewUtil.setUpFastScrollRecyclerViewColor(this, recyclerView)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkForPadding() {
|
}
|
||||||
|
|
||||||
}
|
override fun onQueueChanged() {
|
||||||
|
if (MusicPlayerRemote.playingQueue.isEmpty()) {
|
||||||
|
finish()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
checkForPadding()
|
||||||
|
updateQueue()
|
||||||
|
updateCurrentSong()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onQueueChanged() {
|
override fun onMediaStoreChanged() {
|
||||||
if (MusicPlayerRemote.playingQueue.isEmpty()) {
|
updateQueue()
|
||||||
finish()
|
updateCurrentSong()
|
||||||
return
|
}
|
||||||
}
|
|
||||||
checkForPadding()
|
|
||||||
updateQueue()
|
|
||||||
updateCurrentSong()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMediaStoreChanged() {
|
private fun updateCurrentSong() {
|
||||||
updateQueue()
|
playerQueueSubHeader.text = getUpNextAndQueueTime()
|
||||||
updateCurrentSong()
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateCurrentSong() {
|
override fun onPlayingMetaChanged() {
|
||||||
playerQueueSubHeader.text = getUpNextAndQueueTime()
|
updateQueuePosition()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPlayingMetaChanged() {
|
private fun updateQueuePosition() {
|
||||||
updateQueuePosition()
|
playingQueueAdapter?.setCurrent(MusicPlayerRemote.position)
|
||||||
}
|
resetToCurrentPosition()
|
||||||
|
playerQueueSubHeader.text = getUpNextAndQueueTime()
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateQueuePosition() {
|
private fun updateQueue() {
|
||||||
playingQueueAdapter?.setCurrent(MusicPlayerRemote.position)
|
playingQueueAdapter?.swapDataSet(MusicPlayerRemote.playingQueue, MusicPlayerRemote.position)
|
||||||
resetToCurrentPosition()
|
resetToCurrentPosition()
|
||||||
playerQueueSubHeader.text = getUpNextAndQueueTime()
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateQueue() {
|
private fun resetToCurrentPosition() {
|
||||||
playingQueueAdapter?.swapDataSet(MusicPlayerRemote.playingQueue, MusicPlayerRemote.position)
|
recyclerView.stopScroll()
|
||||||
resetToCurrentPosition()
|
linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resetToCurrentPosition() {
|
override fun onPause() {
|
||||||
recyclerView.stopScroll()
|
if (recyclerViewDragDropManager != null) {
|
||||||
linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
|
recyclerViewDragDropManager!!.cancelDrag()
|
||||||
}
|
}
|
||||||
|
super.onPause()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onDestroy() {
|
||||||
if (recyclerViewDragDropManager != null) {
|
if (recyclerViewDragDropManager != null) {
|
||||||
recyclerViewDragDropManager!!.cancelDrag()
|
recyclerViewDragDropManager!!.release()
|
||||||
}
|
recyclerViewDragDropManager = null
|
||||||
super.onPause()
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
if (wrappedAdapter != null) {
|
||||||
if (recyclerViewDragDropManager != null) {
|
WrapperAdapterUtils.releaseAll(wrappedAdapter)
|
||||||
recyclerViewDragDropManager!!.release()
|
wrappedAdapter = null
|
||||||
recyclerViewDragDropManager = null
|
}
|
||||||
}
|
playingQueueAdapter = null
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
if (wrappedAdapter != null) {
|
private fun setupToolbar() {
|
||||||
WrapperAdapterUtils.releaseAll(wrappedAdapter)
|
playerQueueSubHeader.text = getUpNextAndQueueTime()
|
||||||
wrappedAdapter = null
|
playerQueueSubHeader.setTextColor(ThemeStore.accentColor(this))
|
||||||
}
|
|
||||||
playingQueueAdapter = null
|
|
||||||
super.onDestroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupToolbar() {
|
applyToolbar(toolbar)
|
||||||
playerQueueSubHeader.text = getUpNextAndQueueTime()
|
appBarLayout.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
||||||
playerQueueSubHeader.setTextColor(ThemeStore.accentColor(this))
|
|
||||||
|
|
||||||
applyToolbar(toolbar)
|
clearQueue.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
|
||||||
appBarLayout.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
ColorStateList.valueOf(
|
||||||
|
MaterialValueHelper.getPrimaryTextColor(
|
||||||
clearQueue.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
|
this,
|
||||||
ColorStateList.valueOf(MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(ThemeStore.accentColor(this)))).apply {
|
ColorUtil.isColorLight(
|
||||||
clearQueue.setTextColor(this)
|
ThemeStore.accentColor(
|
||||||
clearQueue.iconTint = this
|
this
|
||||||
}
|
)
|
||||||
}
|
)
|
||||||
|
)
|
||||||
|
).apply {
|
||||||
|
clearQueue.setTextColor(this)
|
||||||
|
clearQueue.iconTint = this
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,31 +2,19 @@ package code.name.monkey.retromusic.activities
|
||||||
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.*
|
||||||
import android.view.MenuItem
|
import androidx.recyclerview.widget.*
|
||||||
import android.view.View
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import code.name.monkey.retromusic.*
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
|
||||||
import code.name.monkey.retromusic.App
|
|
||||||
import code.name.monkey.retromusic.R
|
|
||||||
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
|
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
|
||||||
import code.name.monkey.retromusic.adapter.song.OrderablePlaylistSongAdapter
|
import code.name.monkey.retromusic.adapter.song.*
|
||||||
import code.name.monkey.retromusic.adapter.song.PlaylistSongAdapter
|
|
||||||
import code.name.monkey.retromusic.adapter.song.SongAdapter
|
|
||||||
import code.name.monkey.retromusic.extensions.applyToolbar
|
import code.name.monkey.retromusic.extensions.applyToolbar
|
||||||
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
|
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.loaders.PlaylistLoader
|
import code.name.monkey.retromusic.loaders.PlaylistLoader
|
||||||
import code.name.monkey.retromusic.model.AbsCustomPlaylist
|
import code.name.monkey.retromusic.model.*
|
||||||
import code.name.monkey.retromusic.model.Playlist
|
import code.name.monkey.retromusic.mvp.presenter.*
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsPresenter
|
|
||||||
import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsView
|
|
||||||
import code.name.monkey.retromusic.util.DensityUtil
|
|
||||||
import code.name.monkey.retromusic.util.PlaylistsUtil
|
|
||||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
|
||||||
import code.name.monkey.retromusic.util.ViewUtil
|
import code.name.monkey.retromusic.util.ViewUtil
|
||||||
import com.afollestad.materialcab.MaterialCab
|
import com.afollestad.materialcab.MaterialCab
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator
|
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator
|
||||||
|
@ -35,197 +23,219 @@ import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
|
||||||
import kotlinx.android.synthetic.main.activity_playlist_detail.*
|
import kotlinx.android.synthetic.main.activity_playlist_detail.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, PlaylistSongsView {
|
class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, PlaylistSongsView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var playlistSongsPresenter: PlaylistSongsPresenter
|
lateinit var playlistSongsPresenter: PlaylistSongsPresenter
|
||||||
|
|
||||||
private lateinit var playlist: Playlist
|
private lateinit var playlist: Playlist
|
||||||
private var cab: MaterialCab? = null
|
private var cab: MaterialCab? = null
|
||||||
private lateinit var adapter: SongAdapter
|
private lateinit var adapter: SongAdapter
|
||||||
private var wrappedAdapter: RecyclerView.Adapter<*>? = null
|
private var wrappedAdapter: RecyclerView.Adapter<*>? = null
|
||||||
private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null
|
private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setDrawUnderStatusBar()
|
setDrawUnderStatusBar()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
App.musicComponent.inject(this)
|
App.musicComponent.inject(this)
|
||||||
|
|
||||||
playlistSongsPresenter.attachView(this)
|
playlistSongsPresenter.attachView(this)
|
||||||
|
|
||||||
setStatusbarColor(Color.TRANSPARENT)
|
setStatusbarColor(Color.TRANSPARENT)
|
||||||
setNavigationbarColorAuto()
|
setNavigationbarColorAuto()
|
||||||
setTaskDescriptionColorAuto()
|
setTaskDescriptionColorAuto()
|
||||||
setLightNavigationBar(true)
|
setLightNavigationBar(true)
|
||||||
setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
|
setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
|
||||||
|
|
||||||
toggleBottomNavigationView(true)
|
toggleBottomNavigationView(true)
|
||||||
|
|
||||||
if (intent.extras != null) {
|
if (intent.extras != null) {
|
||||||
playlist = intent.extras!!.getParcelable(EXTRA_PLAYLIST)!!
|
playlist = intent.extras!!.getParcelable(EXTRA_PLAYLIST)!!
|
||||||
} else {
|
} else {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
setUpToolBar()
|
setUpToolBar()
|
||||||
setUpRecyclerView()
|
setUpRecyclerView()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createContentView(): View {
|
override fun createContentView(): View {
|
||||||
return wrapSlidingMusicPanel(R.layout.activity_playlist_detail)
|
return wrapSlidingMusicPanel(R.layout.activity_playlist_detail)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpRecyclerView() {
|
private fun setUpRecyclerView() {
|
||||||
ViewUtil.setUpFastScrollRecyclerViewColor(this, recyclerView)
|
ViewUtil.setUpFastScrollRecyclerViewColor(this, recyclerView)
|
||||||
recyclerView.layoutManager = LinearLayoutManager(this)
|
recyclerView.layoutManager = LinearLayoutManager(this)
|
||||||
if (playlist is AbsCustomPlaylist) {
|
if (playlist is AbsCustomPlaylist) {
|
||||||
adapter = PlaylistSongAdapter(this, ArrayList(), R.layout.item_list, false, this)
|
adapter = PlaylistSongAdapter(this, ArrayList(), R.layout.item_list, false, this)
|
||||||
recyclerView.adapter = adapter
|
recyclerView.adapter = adapter
|
||||||
} else {
|
} else {
|
||||||
recyclerViewDragDropManager = RecyclerViewDragDropManager()
|
recyclerViewDragDropManager = RecyclerViewDragDropManager()
|
||||||
val animator = RefactoredDefaultItemAnimator()
|
val animator = RefactoredDefaultItemAnimator()
|
||||||
adapter = OrderablePlaylistSongAdapter(this, ArrayList(), R.layout.item_list, false, this,
|
adapter = OrderablePlaylistSongAdapter(this,
|
||||||
object : OrderablePlaylistSongAdapter.OnMoveItemListener {
|
ArrayList(),
|
||||||
override fun onMoveItem(fromPosition: Int, toPosition: Int) {
|
R.layout.item_list,
|
||||||
if (PlaylistsUtil.moveItem(this@PlaylistDetailActivity, playlist.id, fromPosition, toPosition)) {
|
false,
|
||||||
val song = adapter.dataSet.removeAt(fromPosition)
|
this,
|
||||||
adapter.dataSet.add(toPosition, song)
|
object : OrderablePlaylistSongAdapter.OnMoveItemListener {
|
||||||
adapter.notifyItemMoved(fromPosition, toPosition)
|
override fun onMoveItem(
|
||||||
}
|
fromPosition: Int,
|
||||||
}
|
toPosition: Int
|
||||||
})
|
) {
|
||||||
wrappedAdapter = recyclerViewDragDropManager!!.createWrappedAdapter(adapter)
|
if (PlaylistsUtil.moveItem(
|
||||||
|
this@PlaylistDetailActivity,
|
||||||
|
playlist.id,
|
||||||
|
fromPosition,
|
||||||
|
toPosition
|
||||||
|
)) {
|
||||||
|
val song = adapter.dataSet.removeAt(
|
||||||
|
fromPosition
|
||||||
|
)
|
||||||
|
adapter.dataSet.add(toPosition, song)
|
||||||
|
adapter.notifyItemMoved(
|
||||||
|
fromPosition,
|
||||||
|
toPosition
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
wrappedAdapter = recyclerViewDragDropManager!!.createWrappedAdapter(adapter)
|
||||||
|
|
||||||
recyclerView.adapter = wrappedAdapter
|
recyclerView.adapter = wrappedAdapter
|
||||||
recyclerView.itemAnimator = animator
|
recyclerView.itemAnimator = animator
|
||||||
|
|
||||||
recyclerViewDragDropManager?.attachRecyclerView(recyclerView)
|
recyclerViewDragDropManager?.attachRecyclerView(recyclerView)
|
||||||
}
|
}
|
||||||
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||||
override fun onChanged() {
|
override fun onChanged() {
|
||||||
super.onChanged()
|
super.onChanged()
|
||||||
checkIsEmpty()
|
checkIsEmpty()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
playlistSongsPresenter.loadPlaylistSongs(playlist)
|
playlistSongsPresenter.loadPlaylistSongs(playlist)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpToolBar() {
|
private fun setUpToolBar() {
|
||||||
applyToolbar(toolbar)
|
applyToolbar(toolbar)
|
||||||
title = playlist.name
|
title = playlist.name
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
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)
|
menuInflater.inflate(
|
||||||
return super.onCreateOptionsMenu(menu)
|
if (playlist is AbsCustomPlaylist) R.menu.menu_smart_playlist_detail
|
||||||
}
|
else R.menu.menu_playlist_detail, menu
|
||||||
|
)
|
||||||
|
return super.onCreateOptionsMenu(menu)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
android.R.id.home -> {
|
android.R.id.home -> {
|
||||||
onBackPressed()
|
onBackPressed()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PlaylistMenuHelper.handleMenuClick(this, playlist, item)
|
return PlaylistMenuHelper.handleMenuClick(this, playlist, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
|
override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
|
||||||
if (cab != null && cab!!.isActive) {
|
if (cab != null && cab!!.isActive) {
|
||||||
cab!!.finish()
|
cab!!.finish()
|
||||||
}
|
}
|
||||||
cab = MaterialCab(this, R.id.cab_stub)
|
cab = MaterialCab(this, R.id.cab_stub).setMenu(menuRes)
|
||||||
.setMenu(menuRes)
|
.setCloseDrawableRes(R.drawable.ic_close_white_24dp).setBackgroundColor(
|
||||||
.setCloseDrawableRes(R.drawable.ic_close_white_24dp)
|
RetroColorUtil.shiftBackgroundColorForLightText(
|
||||||
.setBackgroundColor(
|
ATHUtil.resolveColor(
|
||||||
RetroColorUtil.shiftBackgroundColorForLightText(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
|
this,
|
||||||
.start(callback)
|
R.attr.colorPrimary
|
||||||
return cab!!
|
)
|
||||||
}
|
)
|
||||||
|
).start(callback)
|
||||||
|
return cab!!
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
if (cab != null && cab!!.isActive) {
|
if (cab != null && cab!!.isActive) {
|
||||||
cab!!.finish()
|
cab!!.finish()
|
||||||
} else {
|
} else {
|
||||||
recyclerView!!.stopScroll()
|
recyclerView!!.stopScroll()
|
||||||
super.onBackPressed()
|
super.onBackPressed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMediaStoreChanged() {
|
override fun onMediaStoreChanged() {
|
||||||
super.onMediaStoreChanged()
|
super.onMediaStoreChanged()
|
||||||
if (playlist !is AbsCustomPlaylist) {
|
if (playlist !is AbsCustomPlaylist) {
|
||||||
// Playlist deleted
|
// Playlist deleted
|
||||||
if (!PlaylistsUtil.doesPlaylistExist(this, playlist.id)) {
|
if (!PlaylistsUtil.doesPlaylistExist(this, playlist.id)) {
|
||||||
finish()
|
finish()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Playlist renamed
|
// Playlist renamed
|
||||||
val playlistName = PlaylistsUtil.getNameForPlaylist(this, playlist.id.toLong())
|
val playlistName = PlaylistsUtil.getNameForPlaylist(this, playlist.id.toLong())
|
||||||
if (playlistName != playlist.name) {
|
if (playlistName != playlist.name) {
|
||||||
playlist = PlaylistLoader.getPlaylist(this, playlist.id)
|
playlist = PlaylistLoader.getPlaylist(this, playlist.id)
|
||||||
setToolbarTitle(playlist.name)
|
setToolbarTitle(playlist.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
playlistSongsPresenter.loadPlaylistSongs(playlist)
|
playlistSongsPresenter.loadPlaylistSongs(playlist)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setToolbarTitle(title: String) {
|
private fun setToolbarTitle(title: String) {
|
||||||
supportActionBar!!.title = title
|
supportActionBar!!.title = title
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkForPadding() {
|
private fun checkForPadding() {
|
||||||
val height = DensityUtil.dip2px(this, 52f)
|
val height = DensityUtil.dip2px(this, 52f)
|
||||||
recyclerView.setPadding(0, 0, 0, (height))
|
recyclerView.setPadding(0, 0, 0, (height))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkIsEmpty() {
|
private fun checkIsEmpty() {
|
||||||
checkForPadding()
|
checkForPadding()
|
||||||
empty.visibility = if (adapter.itemCount == 0) View.VISIBLE else View.GONE
|
empty.visibility = if (adapter.itemCount == 0) View.VISIBLE else View.GONE
|
||||||
emptyText.visibility = if (adapter.itemCount == 0) View.VISIBLE else View.GONE
|
emptyText.visibility = if (adapter.itemCount == 0) View.VISIBLE else View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun onPause() {
|
public override fun onPause() {
|
||||||
if (recyclerViewDragDropManager != null) {
|
if (recyclerViewDragDropManager != null) {
|
||||||
recyclerViewDragDropManager!!.cancelDrag()
|
recyclerViewDragDropManager!!.cancelDrag()
|
||||||
}
|
}
|
||||||
super.onPause()
|
super.onPause()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
if (recyclerViewDragDropManager != null) {
|
if (recyclerViewDragDropManager != null) {
|
||||||
recyclerViewDragDropManager!!.release()
|
recyclerViewDragDropManager!!.release()
|
||||||
recyclerViewDragDropManager = null
|
recyclerViewDragDropManager = null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recyclerView != null) {
|
if (recyclerView != null) {
|
||||||
recyclerView!!.itemAnimator = null
|
recyclerView!!.itemAnimator = null
|
||||||
recyclerView!!.adapter = null
|
recyclerView!!.adapter = null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wrappedAdapter != null) {
|
if (wrappedAdapter != null) {
|
||||||
WrapperAdapterUtils.releaseAll(wrappedAdapter)
|
WrapperAdapterUtils.releaseAll(wrappedAdapter)
|
||||||
wrappedAdapter = null
|
wrappedAdapter = null
|
||||||
}
|
}
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
playlistSongsPresenter.detachView()
|
playlistSongsPresenter.detachView()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showEmptyView() {
|
override fun showEmptyView() {
|
||||||
empty.visibility = View.VISIBLE
|
empty.visibility = View.VISIBLE
|
||||||
emptyText.visibility = View.VISIBLE
|
emptyText.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun songs(songs: ArrayList<Song>) {
|
override fun songs(songs: ArrayList<Song>) {
|
||||||
adapter.swapDataSet(songs)
|
adapter.swapDataSet(songs)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
var EXTRA_PLAYLIST = "extra_playlist"
|
var EXTRA_PLAYLIST = "extra_playlist"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,155 +1,157 @@
|
||||||
package code.name.monkey.retromusic.activities
|
package code.name.monkey.retromusic.activities
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.AsyncTask
|
import android.os.*
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
import code.name.monkey.retromusic.*
|
||||||
import code.name.monkey.retromusic.App
|
|
||||||
import code.name.monkey.retromusic.BuildConfig
|
import code.name.monkey.retromusic.BuildConfig
|
||||||
import code.name.monkey.retromusic.R
|
|
||||||
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
||||||
import code.name.monkey.retromusic.extensions.applyToolbar
|
import code.name.monkey.retromusic.extensions.applyToolbar
|
||||||
import com.anjlab.android.iab.v3.BillingProcessor
|
import com.anjlab.android.iab.v3.*
|
||||||
import com.anjlab.android.iab.v3.TransactionDetails
|
|
||||||
import kotlinx.android.synthetic.main.activity_pro_version.*
|
import kotlinx.android.synthetic.main.activity_pro_version.*
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
|
|
||||||
class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
||||||
|
|
||||||
|
private lateinit var billingProcessor: BillingProcessor
|
||||||
|
private var restorePurchaseAsyncTask: AsyncTask<*, *, *>? = null
|
||||||
|
|
||||||
private lateinit var billingProcessor: BillingProcessor
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
private var restorePurchaseAsyncTask: AsyncTask<*, *, *>? = null
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_pro_version)
|
||||||
|
setDrawUnderStatusBar()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
setStatusbarColorAuto()
|
||||||
super.onCreate(savedInstanceState)
|
setNavigationBarColorPrimary()
|
||||||
setContentView(R.layout.activity_pro_version)
|
setTaskDescriptionColorAuto()
|
||||||
setDrawUnderStatusBar()
|
setLightNavigationBar(true)
|
||||||
|
|
||||||
setStatusbarColorAuto()
|
val primaryColor = ATHUtil.resolveColor(this, R.attr.colorPrimary)
|
||||||
setNavigationBarColorPrimary()
|
toolbar.setBackgroundColor(primaryColor)
|
||||||
setTaskDescriptionColorAuto()
|
appBarLayout.setBackgroundColor(primaryColor)
|
||||||
setLightNavigationBar(true)
|
|
||||||
|
|
||||||
val primaryColor = ATHUtil.resolveColor(this, R.attr.colorPrimary)
|
applyToolbar(toolbar)
|
||||||
toolbar.setBackgroundColor(primaryColor)
|
|
||||||
appBarLayout.setBackgroundColor(primaryColor)
|
|
||||||
|
|
||||||
applyToolbar(toolbar)
|
restoreButton.isEnabled = false
|
||||||
|
purchaseButton.isEnabled = false
|
||||||
|
|
||||||
restoreButton.isEnabled = false
|
billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSING_KEY, this)
|
||||||
purchaseButton.isEnabled = false
|
|
||||||
|
|
||||||
billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSING_KEY, this)
|
MaterialUtil.setTint(restoreButton, false)
|
||||||
|
MaterialUtil.setTint(purchaseButton, true)
|
||||||
|
|
||||||
MaterialUtil.setTint(restoreButton, false)
|
restoreButton.setOnClickListener {
|
||||||
MaterialUtil.setTint(purchaseButton, true)
|
if (restorePurchaseAsyncTask == null || restorePurchaseAsyncTask!!.status != AsyncTask.Status.RUNNING) {
|
||||||
|
restorePurchase()
|
||||||
|
}
|
||||||
|
|
||||||
restoreButton.setOnClickListener {
|
}
|
||||||
if (restorePurchaseAsyncTask == null || restorePurchaseAsyncTask!!.status != AsyncTask.Status.RUNNING) {
|
purchaseButton.setOnClickListener {
|
||||||
restorePurchase()
|
billingProcessor.purchase(this@PurchaseActivity, App.PRO_VERSION_PRODUCT_ID)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
private fun restorePurchase() {
|
||||||
purchaseButton.setOnClickListener {
|
if (restorePurchaseAsyncTask != null) {
|
||||||
billingProcessor.purchase(this@PurchaseActivity, App.PRO_VERSION_PRODUCT_ID)
|
restorePurchaseAsyncTask!!.cancel(false)
|
||||||
}
|
}
|
||||||
}
|
restorePurchaseAsyncTask = RestorePurchaseAsyncTask(this).execute()
|
||||||
|
}
|
||||||
|
|
||||||
private fun restorePurchase() {
|
override fun onProductPurchased(productId: String, details: TransactionDetails?) {
|
||||||
if (restorePurchaseAsyncTask != null) {
|
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show()
|
||||||
restorePurchaseAsyncTask!!.cancel(false)
|
setResult(RESULT_OK)
|
||||||
}
|
}
|
||||||
restorePurchaseAsyncTask = RestorePurchaseAsyncTask(this).execute()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
override fun onPurchaseHistoryRestored() {
|
||||||
|
if (App.isProVersion()) {
|
||||||
|
Toast.makeText(
|
||||||
|
this,
|
||||||
|
R.string.restored_previous_purchase_please_restart,
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
setResult(RESULT_OK)
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, R.string.no_purchase_found, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onProductPurchased(productId: String, details: TransactionDetails?) {
|
override fun onBillingError(errorCode: Int, error: Throwable?) {
|
||||||
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show()
|
Log.e(TAG, "Billing error: code = $errorCode", error)
|
||||||
setResult(RESULT_OK)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPurchaseHistoryRestored() {
|
override fun onBillingInitialized() {
|
||||||
if (App.isProVersion()) {
|
restoreButton.isEnabled = true
|
||||||
Toast.makeText(this, R.string.restored_previous_purchase_please_restart, Toast.LENGTH_LONG).show()
|
purchaseButton.isEnabled = true
|
||||||
setResult(RESULT_OK)
|
}
|
||||||
} else {
|
|
||||||
Toast.makeText(this, R.string.no_purchase_found, Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBillingError(errorCode: Int, error: Throwable?) {
|
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
Log.e(TAG, "Billing error: code = $errorCode", error)
|
if (!billingProcessor.handleActivityResult(requestCode, resultCode, data)) {
|
||||||
}
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
when (item.itemId) {
|
||||||
|
android.R.id.home -> finish()
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBillingInitialized() {
|
override fun onDestroy() {
|
||||||
restoreButton.isEnabled = true
|
billingProcessor.release()
|
||||||
purchaseButton.isEnabled = true
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class RestorePurchaseAsyncTask internal constructor(purchaseActivity: PurchaseActivity) : AsyncTask<Void, Void, Boolean>() {
|
||||||
|
|
||||||
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
private val buyActivityWeakReference: WeakReference<PurchaseActivity> = WeakReference(
|
||||||
if (!billingProcessor.handleActivityResult(requestCode, resultCode, data)) {
|
purchaseActivity
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onPreExecute() {
|
||||||
when (item.itemId) {
|
super.onPreExecute()
|
||||||
android.R.id.home -> finish()
|
val purchaseActivity = buyActivityWeakReference.get()
|
||||||
}
|
if (purchaseActivity != null) {
|
||||||
return super.onOptionsItemSelected(item)
|
Toast.makeText(purchaseActivity, R.string.restoring_purchase, Toast.LENGTH_SHORT)
|
||||||
}
|
.show()
|
||||||
|
} else {
|
||||||
|
cancel(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun doInBackground(vararg params: Void): Boolean? {
|
||||||
billingProcessor.release()
|
val purchaseActivity = buyActivityWeakReference.get()
|
||||||
super.onDestroy()
|
if (purchaseActivity != null) {
|
||||||
}
|
return purchaseActivity.billingProcessor.loadOwnedPurchasesFromGoogle()
|
||||||
|
}
|
||||||
|
cancel(false)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
private class RestorePurchaseAsyncTask internal constructor(purchaseActivity: PurchaseActivity) : AsyncTask<Void, Void, Boolean>() {
|
override fun onPostExecute(b: Boolean?) {
|
||||||
|
super.onPostExecute(b)
|
||||||
|
val purchaseActivity = buyActivityWeakReference.get()
|
||||||
|
if (purchaseActivity == null || b == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
private val buyActivityWeakReference: WeakReference<PurchaseActivity> = WeakReference(purchaseActivity)
|
if (b) {
|
||||||
|
purchaseActivity.onPurchaseHistoryRestored()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(
|
||||||
|
purchaseActivity,
|
||||||
|
R.string.could_not_restore_purchase,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onPreExecute() {
|
companion object {
|
||||||
super.onPreExecute()
|
private const val TAG: String = "PurchaseActivity"
|
||||||
val purchaseActivity = buyActivityWeakReference.get()
|
}
|
||||||
if (purchaseActivity != null) {
|
|
||||||
Toast.makeText(purchaseActivity, R.string.restoring_purchase, Toast.LENGTH_SHORT).show()
|
|
||||||
} else {
|
|
||||||
cancel(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun doInBackground(vararg params: Void): Boolean? {
|
|
||||||
val purchaseActivity = buyActivityWeakReference.get()
|
|
||||||
if (purchaseActivity != null) {
|
|
||||||
return purchaseActivity.billingProcessor.loadOwnedPurchasesFromGoogle()
|
|
||||||
}
|
|
||||||
cancel(false)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPostExecute(b: Boolean?) {
|
|
||||||
super.onPostExecute(b)
|
|
||||||
val purchaseActivity = buyActivityWeakReference.get()
|
|
||||||
if (purchaseActivity == null || b == null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b) {
|
|
||||||
purchaseActivity.onPurchaseHistoryRestored()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(purchaseActivity, R.string.could_not_restore_purchase, Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val TAG: String = "PurchaseActivity"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,212 +1,215 @@
|
||||||
package code.name.monkey.retromusic.activities
|
package code.name.monkey.retromusic.activities
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.*
|
||||||
import android.app.Service
|
import android.content.*
|
||||||
import android.content.ActivityNotFoundException
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.speech.RecognizerIntent
|
import android.speech.RecognizerIntent
|
||||||
import android.text.Editable
|
import android.text.*
|
||||||
import android.text.TextWatcher
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import android.widget.TextView.BufferType
|
import android.widget.TextView.BufferType
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.widget.SearchView.OnQueryTextListener
|
import androidx.appcompat.widget.SearchView.OnQueryTextListener
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.*
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
import code.name.monkey.retromusic.*
|
||||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
|
||||||
import code.name.monkey.retromusic.App
|
|
||||||
import code.name.monkey.retromusic.R
|
|
||||||
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
|
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
|
||||||
import code.name.monkey.retromusic.adapter.SearchAdapter
|
import code.name.monkey.retromusic.adapter.SearchAdapter
|
||||||
import code.name.monkey.retromusic.mvp.presenter.SearchPresenter
|
import code.name.monkey.retromusic.mvp.presenter.*
|
||||||
import code.name.monkey.retromusic.mvp.presenter.SearchView
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
|
||||||
import code.name.monkey.retromusic.util.RetroUtil
|
|
||||||
import kotlinx.android.synthetic.main.activity_search.*
|
import kotlinx.android.synthetic.main.activity_search.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatcher, SearchView {
|
class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatcher, SearchView {
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var searchPresenter: SearchPresenter
|
lateinit var searchPresenter: SearchPresenter
|
||||||
|
|
||||||
private var searchAdapter: SearchAdapter? = null
|
private var searchAdapter: SearchAdapter? = null
|
||||||
private var query: String? = null
|
private var query: String? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setDrawUnderStatusBar()
|
setDrawUnderStatusBar()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_search)
|
setContentView(R.layout.activity_search)
|
||||||
App.musicComponent.inject(this)
|
App.musicComponent.inject(this)
|
||||||
searchPresenter.attachView(this)
|
searchPresenter.attachView(this)
|
||||||
|
|
||||||
setStatusbarColorAuto()
|
setStatusbarColorAuto()
|
||||||
setNavigationBarColorPrimary()
|
setNavigationBarColorPrimary()
|
||||||
setTaskDescriptionColorAuto()
|
setTaskDescriptionColorAuto()
|
||||||
setLightNavigationBar(true)
|
setLightNavigationBar(true)
|
||||||
|
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
setUpToolBar()
|
setUpToolBar()
|
||||||
setupSearchView()
|
setupSearchView()
|
||||||
|
|
||||||
if (intent.getBooleanExtra(EXTRA_SHOW_MIC, false)) {
|
if (intent.getBooleanExtra(EXTRA_SHOW_MIC, false)) {
|
||||||
startMicSearch()
|
startMicSearch()
|
||||||
}
|
}
|
||||||
|
|
||||||
back.setOnClickListener { onBackPressed() }
|
back.setOnClickListener { onBackPressed() }
|
||||||
voiceSearch.setOnClickListener { startMicSearch() }
|
voiceSearch.setOnClickListener { startMicSearch() }
|
||||||
|
|
||||||
searchContainer.setCardBackgroundColor(RetroColorUtil.toolbarColor(this))
|
searchContainer.setCardBackgroundColor(RetroColorUtil.toolbarColor(this))
|
||||||
|
|
||||||
keyboardPopup.setOnClickListener {
|
keyboardPopup.setOnClickListener {
|
||||||
val inputManager = getSystemService(Service.INPUT_METHOD_SERVICE) as InputMethodManager
|
val inputManager = getSystemService(Service.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
inputManager.showSoftInput(searchView, InputMethodManager.SHOW_IMPLICIT)
|
inputManager.showSoftInput(searchView, InputMethodManager.SHOW_IMPLICIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
keyboardPopup.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
|
keyboardPopup.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
|
||||||
ColorStateList.valueOf(MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(ThemeStore.accentColor(this)))).apply {
|
ColorStateList.valueOf(
|
||||||
keyboardPopup.setTextColor(this)
|
MaterialValueHelper.getPrimaryTextColor(
|
||||||
keyboardPopup.iconTint = this
|
this,
|
||||||
}
|
ColorUtil.isColorLight(
|
||||||
if (savedInstanceState != null) {
|
ThemeStore.accentColor(
|
||||||
query = savedInstanceState.getString(QUERY);
|
this
|
||||||
}
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).apply {
|
||||||
|
keyboardPopup.setTextColor(this)
|
||||||
|
keyboardPopup.iconTint = this
|
||||||
|
}
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
query = savedInstanceState.getString(QUERY);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupRecyclerView() {
|
private fun setupRecyclerView() {
|
||||||
searchAdapter = SearchAdapter(this, emptyList())
|
searchAdapter = SearchAdapter(this, emptyList())
|
||||||
searchAdapter!!.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
searchAdapter!!.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||||
override fun onChanged() {
|
override fun onChanged() {
|
||||||
super.onChanged()
|
super.onChanged()
|
||||||
empty.visibility = if (searchAdapter!!.itemCount < 1) View.VISIBLE else View.GONE
|
empty.visibility = if (searchAdapter!!.itemCount < 1) View.VISIBLE else View.GONE
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
recyclerView.apply {
|
recyclerView.apply {
|
||||||
layoutManager = LinearLayoutManager(this@SearchActivity)
|
layoutManager = LinearLayoutManager(this@SearchActivity)
|
||||||
adapter = searchAdapter
|
adapter = searchAdapter
|
||||||
}
|
}
|
||||||
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
super.onScrolled(recyclerView, dx, dy)
|
||||||
if (dy > 0) {
|
if (dy > 0) {
|
||||||
keyboardPopup.shrink()
|
keyboardPopup.shrink()
|
||||||
} else if (dy < 0) {
|
} else if (dy < 0) {
|
||||||
keyboardPopup.extend()
|
keyboardPopup.extend()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupSearchView() {
|
private fun setupSearchView() {
|
||||||
searchView.addTextChangedListener(this)
|
searchView.addTextChangedListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
searchPresenter.detachView()
|
searchPresenter.detachView()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
outState.putString(QUERY, query)
|
outState.putString(QUERY, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpToolBar() {
|
private fun setUpToolBar() {
|
||||||
title = null
|
title = null
|
||||||
appBarLayout.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
appBarLayout.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun search(query: String) {
|
||||||
|
this.query = query
|
||||||
|
voiceSearch.visibility = if (query.isNotEmpty()) View.GONE else View.VISIBLE
|
||||||
|
searchPresenter.search(query)
|
||||||
|
}
|
||||||
|
|
||||||
private fun search(query: String) {
|
override fun onMediaStoreChanged() {
|
||||||
this.query = query
|
super.onMediaStoreChanged()
|
||||||
voiceSearch.visibility = if (query.isNotEmpty()) View.GONE else View.VISIBLE
|
query?.let { search(it) }
|
||||||
searchPresenter.search(query)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMediaStoreChanged() {
|
override fun onQueryTextSubmit(query: String): Boolean {
|
||||||
super.onMediaStoreChanged()
|
hideSoftKeyboard()
|
||||||
query?.let { search(it) }
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueryTextSubmit(query: String): Boolean {
|
override fun onQueryTextChange(newText: String): Boolean {
|
||||||
hideSoftKeyboard()
|
search(newText)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueryTextChange(newText: String): Boolean {
|
private fun hideSoftKeyboard() {
|
||||||
search(newText)
|
RetroUtil.hideSoftKeyboard(this@SearchActivity)
|
||||||
return false
|
if (searchView != null) {
|
||||||
}
|
searchView.clearFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun hideSoftKeyboard() {
|
override fun showEmptyView() {
|
||||||
RetroUtil.hideSoftKeyboard(this@SearchActivity)
|
searchAdapter?.swapDataSet(ArrayList())
|
||||||
if (searchView != null) {
|
}
|
||||||
searchView.clearFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun showEmptyView() {
|
override fun showData(data: MutableList<Any>) {
|
||||||
searchAdapter?.swapDataSet(ArrayList())
|
searchAdapter?.swapDataSet(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showData(data: MutableList<Any>) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
searchAdapter?.swapDataSet(data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
}
|
when (requestCode) {
|
||||||
|
REQ_CODE_SPEECH_INPUT -> {
|
||||||
|
if (resultCode == Activity.RESULT_OK && null != data) {
|
||||||
|
val result: ArrayList<String>? = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)
|
||||||
|
query = result?.get(0)
|
||||||
|
searchView.setText(query, BufferType.EDITABLE)
|
||||||
|
searchPresenter.search(query!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
private fun startMicSearch() {
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
|
||||||
when (requestCode) {
|
intent.putExtra(
|
||||||
REQ_CODE_SPEECH_INPUT -> {
|
RecognizerIntent.EXTRA_LANGUAGE_MODEL,
|
||||||
if (resultCode == Activity.RESULT_OK && null != data) {
|
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
|
||||||
val result: ArrayList<String>? = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)
|
)
|
||||||
query = result?.get(0)
|
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault())
|
||||||
searchView.setText(query, BufferType.EDITABLE)
|
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.speech_prompt))
|
||||||
searchPresenter.search(query!!)
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
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 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 onTextChanged(newText: CharSequence, start: Int, before: Int, count: Int) {
|
override fun afterTextChanged(s: Editable) {
|
||||||
search(newText.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun afterTextChanged(s: Editable) {
|
}
|
||||||
|
|
||||||
}
|
companion object {
|
||||||
|
val TAG: String = SearchActivity::class.java.simpleName
|
||||||
|
|
||||||
companion object {
|
const val EXTRA_SHOW_MIC = "extra_show_mic"
|
||||||
val TAG: String = SearchActivity::class.java.simpleName
|
const val QUERY: String = "query"
|
||||||
|
|
||||||
const val EXTRA_SHOW_MIC = "extra_show_mic"
|
private const val REQ_CODE_SPEECH_INPUT = 9002
|
||||||
const val QUERY: String = "query"
|
}
|
||||||
|
|
||||||
private const val REQ_CODE_SPEECH_INPUT = 9002
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,12 @@ import android.view.MenuItem
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.transition.TransitionManager
|
import androidx.transition.TransitionManager
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
||||||
import code.name.monkey.retromusic.fragments.settings.MainSettingsFragment
|
import code.name.monkey.retromusic.fragments.settings.MainSettingsFragment
|
||||||
import kotlinx.android.synthetic.main.activity_settings.*
|
import kotlinx.android.synthetic.main.activity_settings.*
|
||||||
|
|
||||||
|
|
||||||
class SettingsActivity : AbsBaseActivity() {
|
class SettingsActivity : AbsBaseActivity() {
|
||||||
|
|
||||||
private val fragmentManager = supportFragmentManager
|
private val fragmentManager = supportFragmentManager
|
||||||
|
|
|
@ -2,237 +2,238 @@ package code.name.monkey.retromusic.activities
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.os.AsyncTask
|
import android.os.*
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.MenuItem
|
import android.widget.*
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.TextView
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.annotation.LayoutRes
|
import androidx.annotation.LayoutRes
|
||||||
import androidx.appcompat.widget.AppCompatImageView
|
import androidx.appcompat.widget.AppCompatImageView
|
||||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
import androidx.recyclerview.widget.*
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.TintHelper
|
import code.name.monkey.retromusic.*
|
||||||
import code.name.monkey.retromusic.BuildConfig
|
import code.name.monkey.retromusic.BuildConfig
|
||||||
import code.name.monkey.retromusic.R
|
|
||||||
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
||||||
import code.name.monkey.retromusic.extensions.applyToolbar
|
import code.name.monkey.retromusic.extensions.applyToolbar
|
||||||
import com.anjlab.android.iab.v3.BillingProcessor
|
import com.anjlab.android.iab.v3.*
|
||||||
import com.anjlab.android.iab.v3.SkuDetails
|
|
||||||
import com.anjlab.android.iab.v3.TransactionDetails
|
|
||||||
import kotlinx.android.synthetic.main.activity_donation.*
|
import kotlinx.android.synthetic.main.activity_donation.*
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val TAG: String = SupportDevelopmentActivity::class.java.simpleName
|
val TAG: String = SupportDevelopmentActivity::class.java.simpleName
|
||||||
const val DONATION_PRODUCT_IDS = R.array.donation_ids
|
const val DONATION_PRODUCT_IDS = R.array.donation_ids
|
||||||
private const val TEZ_REQUEST_CODE = 123
|
private const val TEZ_REQUEST_CODE = 123
|
||||||
}
|
}
|
||||||
|
|
||||||
var billingProcessor: BillingProcessor? = null
|
var billingProcessor: BillingProcessor? = null
|
||||||
private var skuDetailsLoadAsyncTask: AsyncTask<*, *, *>? = null
|
private var skuDetailsLoadAsyncTask: AsyncTask<*, *, *>? = null
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
if (item.itemId == android.R.id.home) {
|
if (item.itemId == android.R.id.home) {
|
||||||
onBackPressed()
|
onBackPressed()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item)
|
return super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun donate(i: Int) {
|
fun donate(i: Int) {
|
||||||
val ids = resources.getStringArray(DONATION_PRODUCT_IDS)
|
val ids = resources.getStringArray(DONATION_PRODUCT_IDS)
|
||||||
billingProcessor!!.purchase(this, ids[i])
|
billingProcessor!!.purchase(this, ids[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_donation)
|
setContentView(R.layout.activity_donation)
|
||||||
|
|
||||||
setStatusbarColorAuto()
|
setStatusbarColorAuto()
|
||||||
setNavigationBarColorPrimary()
|
setNavigationBarColorPrimary()
|
||||||
setTaskDescriptionColorAuto()
|
setTaskDescriptionColorAuto()
|
||||||
setLightNavigationBar(true)
|
setLightNavigationBar(true)
|
||||||
|
|
||||||
setupToolbar()
|
setupToolbar()
|
||||||
|
|
||||||
billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSING_KEY, this)
|
billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSING_KEY, this)
|
||||||
TintHelper.setTint(progress, ThemeStore.accentColor(this))
|
TintHelper.setTint(progress, ThemeStore.accentColor(this))
|
||||||
donation.setTextColor(ThemeStore.accentColor(this))
|
donation.setTextColor(ThemeStore.accentColor(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupToolbar() {
|
private fun setupToolbar() {
|
||||||
val primaryColor = ATHUtil.resolveColor(this, R.attr.colorPrimary)
|
val primaryColor = ATHUtil.resolveColor(this, R.attr.colorPrimary)
|
||||||
appBarLayout.setBackgroundColor(primaryColor)
|
appBarLayout.setBackgroundColor(primaryColor)
|
||||||
applyToolbar(toolbar)
|
applyToolbar(toolbar)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBillingInitialized() {
|
override fun onBillingInitialized() {
|
||||||
loadSkuDetails()
|
loadSkuDetails()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadSkuDetails() {
|
private fun loadSkuDetails() {
|
||||||
if (skuDetailsLoadAsyncTask != null) {
|
if (skuDetailsLoadAsyncTask != null) {
|
||||||
skuDetailsLoadAsyncTask!!.cancel(false)
|
skuDetailsLoadAsyncTask!!.cancel(false)
|
||||||
}
|
}
|
||||||
skuDetailsLoadAsyncTask = SkuDetailsLoadAsyncTask(this).execute()
|
skuDetailsLoadAsyncTask = SkuDetailsLoadAsyncTask(this).execute()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onProductPurchased(productId: String, details: TransactionDetails?) {
|
override fun onProductPurchased(productId: String, details: TransactionDetails?) {
|
||||||
//loadSkuDetails();
|
//loadSkuDetails();
|
||||||
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBillingError(errorCode: Int, error: Throwable?) {
|
override fun onBillingError(errorCode: Int, error: Throwable?) {
|
||||||
Log.e(TAG, "Billing error: code = $errorCode", error)
|
Log.e(TAG, "Billing error: code = $errorCode", error)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPurchaseHistoryRestored() {
|
override fun onPurchaseHistoryRestored() {
|
||||||
//loadSkuDetails();
|
//loadSkuDetails();
|
||||||
Toast.makeText(this, R.string.restored_previous_purchases, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.restored_previous_purchases, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
if (!billingProcessor!!.handleActivityResult(requestCode, resultCode, data)) {
|
if (!billingProcessor!!.handleActivityResult(requestCode, resultCode, data)) {
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
}
|
}
|
||||||
if (requestCode == TEZ_REQUEST_CODE) {
|
if (requestCode == TEZ_REQUEST_CODE) {
|
||||||
// Process based on the data in response.
|
// Process based on the data in response.
|
||||||
Log.d("result", data!!.getStringExtra("Status"))
|
Log.d("result", data!!.getStringExtra("Status"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
if (billingProcessor != null) {
|
if (billingProcessor != null) {
|
||||||
billingProcessor!!.release()
|
billingProcessor!!.release()
|
||||||
}
|
}
|
||||||
if (skuDetailsLoadAsyncTask != null) {
|
if (skuDetailsLoadAsyncTask != null) {
|
||||||
skuDetailsLoadAsyncTask!!.cancel(true)
|
skuDetailsLoadAsyncTask!!.cancel(true)
|
||||||
}
|
}
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SkuDetailsLoadAsyncTask internal constructor(supportDevelopmentActivity: SupportDevelopmentActivity) : AsyncTask<Void, Void, List<SkuDetails>>() {
|
private class SkuDetailsLoadAsyncTask internal constructor(supportDevelopmentActivity: SupportDevelopmentActivity) : AsyncTask<Void, Void, List<SkuDetails>>() {
|
||||||
private val weakReference: WeakReference<SupportDevelopmentActivity> = WeakReference(supportDevelopmentActivity)
|
private val weakReference: WeakReference<SupportDevelopmentActivity> = WeakReference(
|
||||||
|
supportDevelopmentActivity
|
||||||
|
)
|
||||||
|
|
||||||
override fun onPreExecute() {
|
override fun onPreExecute() {
|
||||||
super.onPreExecute()
|
super.onPreExecute()
|
||||||
val supportDevelopmentActivity = weakReference.get() ?: return
|
val supportDevelopmentActivity = weakReference.get() ?: return
|
||||||
|
|
||||||
supportDevelopmentActivity.progressContainer.visibility = View.VISIBLE
|
supportDevelopmentActivity.progressContainer.visibility = View.VISIBLE
|
||||||
supportDevelopmentActivity.recyclerView.visibility = View.GONE
|
supportDevelopmentActivity.recyclerView.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doInBackground(vararg params: Void): List<SkuDetails>? {
|
override fun doInBackground(vararg params: Void): List<SkuDetails>? {
|
||||||
val dialog = weakReference.get()
|
val dialog = weakReference.get()
|
||||||
if (dialog != null) {
|
if (dialog != null) {
|
||||||
val ids = dialog.resources.getStringArray(SupportDevelopmentActivity.DONATION_PRODUCT_IDS)
|
val ids = dialog.resources.getStringArray(SupportDevelopmentActivity.DONATION_PRODUCT_IDS)
|
||||||
return dialog.billingProcessor!!.getPurchaseListingDetails(ArrayList(Arrays.asList(*ids)))
|
return dialog.billingProcessor!!.getPurchaseListingDetails(ArrayList(Arrays.asList(*ids)))
|
||||||
}
|
}
|
||||||
cancel(false)
|
cancel(false)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPostExecute(skuDetails: List<SkuDetails>?) {
|
override fun onPostExecute(skuDetails: List<SkuDetails>?) {
|
||||||
super.onPostExecute(skuDetails)
|
super.onPostExecute(skuDetails)
|
||||||
val dialog = weakReference.get() ?: return
|
val dialog = weakReference.get() ?: return
|
||||||
|
|
||||||
if (skuDetails == null || skuDetails.isEmpty()) {
|
if (skuDetails == null || skuDetails.isEmpty()) {
|
||||||
dialog.progressContainer.visibility = View.GONE
|
dialog.progressContainer.visibility = View.GONE
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.progressContainer.visibility = View.GONE
|
dialog.progressContainer.visibility = View.GONE
|
||||||
dialog.recyclerView.itemAnimator = DefaultItemAnimator()
|
dialog.recyclerView.itemAnimator = DefaultItemAnimator()
|
||||||
dialog.recyclerView.layoutManager = GridLayoutManager(dialog, 2)
|
dialog.recyclerView.layoutManager = GridLayoutManager(dialog, 2)
|
||||||
dialog.recyclerView.adapter = SkuDetailsAdapter(dialog, skuDetails)
|
dialog.recyclerView.adapter = SkuDetailsAdapter(dialog, skuDetails)
|
||||||
dialog.recyclerView.visibility = View.VISIBLE
|
dialog.recyclerView.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SkuDetailsAdapter(
|
class SkuDetailsAdapter(
|
||||||
private var donationsDialog: SupportDevelopmentActivity,
|
private var donationsDialog: SupportDevelopmentActivity, objects: List<SkuDetails>
|
||||||
objects: List<SkuDetails>
|
|
||||||
) : RecyclerView.Adapter<SkuDetailsAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<SkuDetailsAdapter.ViewHolder>() {
|
||||||
private var skuDetailsList: List<SkuDetails> = ArrayList()
|
private var skuDetailsList: List<SkuDetails> = ArrayList()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
skuDetailsList = objects
|
skuDetailsList = objects
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getIcon(position: Int): Int {
|
private fun getIcon(position: Int): Int {
|
||||||
return when (position) {
|
return when (position) {
|
||||||
0 -> R.drawable.ic_cookie_white_24dp
|
0 -> R.drawable.ic_cookie_white_24dp
|
||||||
1 -> R.drawable.ic_take_away_white_24dp
|
1 -> R.drawable.ic_take_away_white_24dp
|
||||||
2 -> R.drawable.ic_take_away_coffe_white_24dp
|
2 -> R.drawable.ic_take_away_coffe_white_24dp
|
||||||
3 -> R.drawable.ic_beer_white_24dp
|
3 -> R.drawable.ic_beer_white_24dp
|
||||||
4 -> R.drawable.ic_fast_food_meal_white_24dp
|
4 -> R.drawable.ic_fast_food_meal_white_24dp
|
||||||
5 -> R.drawable.ic_popcorn_white_24dp
|
5 -> R.drawable.ic_popcorn_white_24dp
|
||||||
6 -> R.drawable.ic_card_giftcard_white_24dp
|
6 -> R.drawable.ic_card_giftcard_white_24dp
|
||||||
else -> R.drawable.ic_card_giftcard_white_24dp
|
else -> R.drawable.ic_card_giftcard_white_24dp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
|
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
|
||||||
return ViewHolder(LayoutInflater.from(donationsDialog).inflate(LAYOUT_RES_ID, viewGroup, false))
|
return ViewHolder(
|
||||||
}
|
LayoutInflater.from(donationsDialog).inflate(
|
||||||
|
LAYOUT_RES_ID,
|
||||||
|
viewGroup,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
|
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
|
||||||
val skuDetails = skuDetailsList[i]
|
val skuDetails = skuDetailsList[i]
|
||||||
viewHolder.title.text = skuDetails.title.replace("(Retro Music Player)", "").trim { it <= ' ' }
|
viewHolder.title.text = skuDetails.title.replace("(Retro Music Player)", "")
|
||||||
viewHolder.text.text = skuDetails.description
|
.trim { it <= ' ' }
|
||||||
viewHolder.text.visibility = View.GONE
|
viewHolder.text.text = skuDetails.description
|
||||||
viewHolder.price.text = skuDetails.priceText
|
viewHolder.text.visibility = View.GONE
|
||||||
viewHolder.image.setImageResource(getIcon(i))
|
viewHolder.price.text = skuDetails.priceText
|
||||||
|
viewHolder.image.setImageResource(getIcon(i))
|
||||||
|
|
||||||
val purchased = donationsDialog.billingProcessor!!.isPurchased(skuDetails.productId)
|
val purchased = donationsDialog.billingProcessor!!.isPurchased(skuDetails.productId)
|
||||||
val titleTextColor = if (purchased) ATHUtil.resolveColor(donationsDialog, android.R.attr.textColorHint) else ThemeStore.textColorPrimary(donationsDialog)
|
val titleTextColor = if (purchased) ATHUtil.resolveColor(
|
||||||
val contentTextColor = if (purchased) titleTextColor else ThemeStore.textColorSecondary(donationsDialog)
|
donationsDialog,
|
||||||
|
android.R.attr.textColorHint
|
||||||
|
) else ThemeStore.textColorPrimary(donationsDialog)
|
||||||
|
val contentTextColor = if (purchased) titleTextColor else ThemeStore.textColorSecondary(
|
||||||
|
donationsDialog
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
viewHolder.title.setTextColor(titleTextColor)
|
viewHolder.title.setTextColor(titleTextColor)
|
||||||
viewHolder.text.setTextColor(contentTextColor)
|
viewHolder.text.setTextColor(contentTextColor)
|
||||||
viewHolder.price.setTextColor(titleTextColor)
|
viewHolder.price.setTextColor(titleTextColor)
|
||||||
|
|
||||||
strikeThrough(viewHolder.title, purchased)
|
strikeThrough(viewHolder.title, purchased)
|
||||||
strikeThrough(viewHolder.text, purchased)
|
strikeThrough(viewHolder.text, purchased)
|
||||||
strikeThrough(viewHolder.price, purchased)
|
strikeThrough(viewHolder.price, purchased)
|
||||||
|
|
||||||
viewHolder.itemView.setOnTouchListener { _, _ -> purchased }
|
viewHolder.itemView.setOnTouchListener { _, _ -> purchased }
|
||||||
viewHolder.itemView.setOnClickListener { donationsDialog.donate(i) }
|
viewHolder.itemView.setOnClickListener { donationsDialog.donate(i) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return skuDetailsList.size
|
return skuDetailsList.size
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
var title: TextView = view.findViewById(R.id.itemTitle)
|
var title: TextView = view.findViewById(R.id.itemTitle)
|
||||||
var text: TextView = view.findViewById(R.id.itemText)
|
var text: TextView = view.findViewById(R.id.itemText)
|
||||||
var price: TextView = view.findViewById(R.id.itemPrice)
|
var price: TextView = view.findViewById(R.id.itemPrice)
|
||||||
var image: AppCompatImageView = view.findViewById(R.id.itemImage)
|
var image: AppCompatImageView = view.findViewById(R.id.itemImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@LayoutRes
|
@LayoutRes
|
||||||
private val LAYOUT_RES_ID = R.layout.item_donation_option
|
private val LAYOUT_RES_ID = R.layout.item_donation_option
|
||||||
|
|
||||||
private fun strikeThrough(textView: TextView, strikeThrough: Boolean) {
|
private fun strikeThrough(textView: TextView, strikeThrough: Boolean) {
|
||||||
textView.paintFlags = if (strikeThrough)
|
textView.paintFlags = if (strikeThrough) textView.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
|
||||||
textView.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
|
else textView.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
|
||||||
else
|
}
|
||||||
textView.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
package code.name.monkey.retromusic.activities
|
package code.name.monkey.retromusic.activities
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.ContentUris
|
import android.content.*
|
||||||
import android.content.Context
|
|
||||||
import android.content.ContextWrapper
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
@ -16,275 +13,298 @@ import android.text.TextUtils
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
import code.name.monkey.retromusic.*
|
||||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
|
||||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
|
||||||
import code.name.monkey.retromusic.App
|
|
||||||
import code.name.monkey.retromusic.Constants.USER_BANNER
|
import code.name.monkey.retromusic.Constants.USER_BANNER
|
||||||
import code.name.monkey.retromusic.Constants.USER_PROFILE
|
import code.name.monkey.retromusic.Constants.USER_PROFILE
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
||||||
import code.name.monkey.retromusic.extensions.applyToolbar
|
import code.name.monkey.retromusic.extensions.applyToolbar
|
||||||
import code.name.monkey.retromusic.util.Compressor
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.ImageUtil.getResizedBitmap
|
import code.name.monkey.retromusic.util.ImageUtil.getResizedBitmap
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import com.afollestad.materialdialogs.*
|
||||||
import com.afollestad.materialdialogs.LayoutMode
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
|
||||||
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
||||||
import com.afollestad.materialdialogs.list.listItems
|
import com.afollestad.materialdialogs.list.listItems
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import kotlinx.android.synthetic.main.activity_user_info.*
|
import kotlinx.android.synthetic.main.activity_user_info.*
|
||||||
import java.io.File
|
import java.io.*
|
||||||
import java.io.FileOutputStream
|
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
class UserInfoActivity : AbsBaseActivity() {
|
class UserInfoActivity : AbsBaseActivity() {
|
||||||
|
|
||||||
private var disposable = CompositeDisposable()
|
private var disposable = CompositeDisposable()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_user_info)
|
setContentView(R.layout.activity_user_info)
|
||||||
setStatusbarColorAuto()
|
setStatusbarColorAuto()
|
||||||
setNavigationBarColorPrimary()
|
setNavigationBarColorPrimary()
|
||||||
setTaskDescriptionColorAuto()
|
setTaskDescriptionColorAuto()
|
||||||
setLightNavigationBar(true)
|
setLightNavigationBar(true)
|
||||||
|
|
||||||
setupToolbar()
|
setupToolbar()
|
||||||
|
|
||||||
MaterialUtil.setTint(nameContainer, false)
|
MaterialUtil.setTint(nameContainer, false)
|
||||||
name.setText(PreferenceUtil.getInstance(this).userName)
|
name.setText(PreferenceUtil.getInstance(this).userName)
|
||||||
|
|
||||||
if (PreferenceUtil.getInstance(this).profileImage.isNotEmpty()) {
|
if (PreferenceUtil.getInstance(this).profileImage.isNotEmpty()) {
|
||||||
loadImageFromStorage(PreferenceUtil.getInstance(this).profileImage)
|
loadImageFromStorage(PreferenceUtil.getInstance(this).profileImage)
|
||||||
}
|
}
|
||||||
if (PreferenceUtil.getInstance(this).bannerImage.isNotEmpty()) {
|
if (PreferenceUtil.getInstance(this).bannerImage.isNotEmpty()) {
|
||||||
loadBannerFromStorage(PreferenceUtil.getInstance(this).bannerImage)
|
loadBannerFromStorage(PreferenceUtil.getInstance(this).bannerImage)
|
||||||
}
|
}
|
||||||
userImage.setOnClickListener {
|
userImage.setOnClickListener {
|
||||||
MaterialDialog(this, BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
MaterialDialog(this, BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
||||||
title(text = getString(R.string.set_photo))
|
title(text = getString(R.string.set_photo))
|
||||||
listItems(items = listOf(getString(R.string.new_profile_photo), getString(R.string.remove_profile_photo))) { _, position, _ ->
|
listItems(
|
||||||
when (position) {
|
items = listOf(
|
||||||
0 -> pickNewPhoto()
|
getString(R.string.new_profile_photo),
|
||||||
1 -> PreferenceUtil.getInstance(this@UserInfoActivity).saveProfileImage("")
|
getString(R.string.remove_profile_photo)
|
||||||
}
|
)
|
||||||
}
|
) { _, position, _ ->
|
||||||
}
|
when (position) {
|
||||||
}
|
0 -> pickNewPhoto()
|
||||||
bannerSelect.setOnClickListener {
|
1 -> PreferenceUtil.getInstance(this@UserInfoActivity).saveProfileImage("")
|
||||||
showBannerOptions()
|
}
|
||||||
}
|
}
|
||||||
next.setOnClickListener {
|
}
|
||||||
val nameString = name.text.toString().trim { it <= ' ' }
|
}
|
||||||
if (TextUtils.isEmpty(nameString)) {
|
bannerSelect.setOnClickListener {
|
||||||
Toast.makeText(this, "Umm name is empty", Toast.LENGTH_SHORT).show()
|
showBannerOptions()
|
||||||
return@setOnClickListener
|
}
|
||||||
}
|
next.setOnClickListener {
|
||||||
/*val bioString = bio.text.toString().trim() { it <= ' ' }
|
val nameString = name.text.toString().trim { it <= ' ' }
|
||||||
if (TextUtils.isEmpty(bioString)) {
|
if (TextUtils.isEmpty(nameString)) {
|
||||||
Toast.makeText(this, "Umm bio is empty", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "Umm name is empty", Toast.LENGTH_SHORT).show()
|
||||||
return@setOnClickListener
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
/*val bioString = bio.text.toString().trim() { it <= ' ' }
|
||||||
|
if (TextUtils.isEmpty(bioString)) {
|
||||||
|
Toast.makeText(this, "Umm bio is empty", Toast.LENGTH_SHORT).show()
|
||||||
|
return@setOnClickListener
|
||||||
|
|
||||||
}*/
|
}*/
|
||||||
PreferenceUtil.getInstance(this).userName = nameString
|
PreferenceUtil.getInstance(this).userName = nameString
|
||||||
//PreferenceUtil.getInstance().userBio = bioString
|
//PreferenceUtil.getInstance().userBio = bioString
|
||||||
setResult(Activity.RESULT_OK)
|
setResult(Activity.RESULT_OK)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
next.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
|
next.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
|
||||||
ColorStateList.valueOf(MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(ThemeStore.accentColor(this)))).apply {
|
ColorStateList.valueOf(
|
||||||
next.setTextColor(this)
|
MaterialValueHelper.getPrimaryTextColor(
|
||||||
next.iconTint = this
|
this,
|
||||||
}
|
ColorUtil.isColorLight(
|
||||||
}
|
ThemeStore.accentColor(
|
||||||
|
this
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).apply {
|
||||||
|
next.setTextColor(this)
|
||||||
|
next.iconTint = this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
if (item.itemId == android.R.id.home) {
|
if (item.itemId == android.R.id.home) {
|
||||||
onBackPressed()
|
onBackPressed()
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item)
|
return super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupToolbar() {
|
private fun setupToolbar() {
|
||||||
val primaryColor = ATHUtil.resolveColor(this, R.attr.colorPrimary)
|
val primaryColor = ATHUtil.resolveColor(this, R.attr.colorPrimary)
|
||||||
applyToolbar(toolbar)
|
applyToolbar(toolbar)
|
||||||
appBarLayout.setBackgroundColor(primaryColor)
|
appBarLayout.setBackgroundColor(primaryColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showBannerOptions() {
|
private fun showBannerOptions() {
|
||||||
MaterialDialog(this, BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
MaterialDialog(this, BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
||||||
title(R.string.select_banner_photo)
|
title(R.string.select_banner_photo)
|
||||||
listItems(items = listOf(getString(R.string.new_banner_photo), getString(R.string.remove_banner_photo)))
|
listItems(
|
||||||
{ _, position, _ ->
|
items = listOf(
|
||||||
when (position) {
|
getString(R.string.new_banner_photo),
|
||||||
0 -> selectBannerImage()
|
getString(R.string.remove_banner_photo)
|
||||||
1 -> PreferenceUtil.getInstance(this@UserInfoActivity).setBannerImagePath("")
|
)
|
||||||
}
|
) { _, position, _ ->
|
||||||
}
|
when (position) {
|
||||||
}
|
0 -> selectBannerImage()
|
||||||
}
|
1 -> PreferenceUtil.getInstance(this@UserInfoActivity).setBannerImagePath("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun selectBannerImage() {
|
private fun selectBannerImage() {
|
||||||
|
|
||||||
if (TextUtils.isEmpty(PreferenceUtil.getInstance(this).bannerImage)) {
|
if (TextUtils.isEmpty(PreferenceUtil.getInstance(this).bannerImage)) {
|
||||||
val pickImageIntent = Intent(Intent.ACTION_PICK, Media.EXTERNAL_CONTENT_URI)
|
val pickImageIntent = Intent(Intent.ACTION_PICK, Media.EXTERNAL_CONTENT_URI)
|
||||||
pickImageIntent.type = "image/*"
|
pickImageIntent.type = "image/*"
|
||||||
//pickImageIntent.putExtra("crop", "true")
|
//pickImageIntent.putExtra("crop", "true")
|
||||||
pickImageIntent.putExtra("outputX", 1290)
|
pickImageIntent.putExtra("outputX", 1290)
|
||||||
pickImageIntent.putExtra("outputY", 720)
|
pickImageIntent.putExtra("outputY", 720)
|
||||||
pickImageIntent.putExtra("aspectX", 16)
|
pickImageIntent.putExtra("aspectX", 16)
|
||||||
pickImageIntent.putExtra("aspectY", 9)
|
pickImageIntent.putExtra("aspectY", 9)
|
||||||
pickImageIntent.putExtra("scale", true)
|
pickImageIntent.putExtra("scale", true)
|
||||||
//intent.setAction(Intent.ACTION_GET_CONTENT);
|
//intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||||
startActivityForResult(Intent.createChooser(pickImageIntent, "Select Picture"), PICK_BANNER_REQUEST)
|
startActivityForResult(
|
||||||
} else {
|
Intent.createChooser(pickImageIntent, "Select Picture"),
|
||||||
PreferenceUtil.getInstance(this).setBannerImagePath("")
|
PICK_BANNER_REQUEST
|
||||||
bannerImage.setImageResource(android.R.color.transparent)
|
)
|
||||||
}
|
} else {
|
||||||
}
|
PreferenceUtil.getInstance(this).setBannerImagePath("")
|
||||||
|
bannerImage.setImageResource(android.R.color.transparent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pickNewPhoto() {
|
||||||
|
val pickImageIntent = Intent(Intent.ACTION_PICK, Media.EXTERNAL_CONTENT_URI)
|
||||||
|
pickImageIntent.type = "image/*"
|
||||||
|
pickImageIntent.putExtra("crop", "true")
|
||||||
|
pickImageIntent.putExtra("outputX", 512)
|
||||||
|
pickImageIntent.putExtra("outputY", 512)
|
||||||
|
pickImageIntent.putExtra("aspectX", 1)
|
||||||
|
pickImageIntent.putExtra("aspectY", 1)
|
||||||
|
pickImageIntent.putExtra("scale", true)
|
||||||
|
startActivityForResult(
|
||||||
|
Intent.createChooser(pickImageIntent, "Select Picture"),
|
||||||
|
PICK_IMAGE_REQUEST
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun pickNewPhoto() {
|
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
val pickImageIntent = Intent(Intent.ACTION_PICK, Media.EXTERNAL_CONTENT_URI)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
pickImageIntent.type = "image/*"
|
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||||
pickImageIntent.putExtra("crop", "true")
|
when (requestCode) {
|
||||||
pickImageIntent.putExtra("outputX", 512)
|
PICK_IMAGE_REQUEST -> {
|
||||||
pickImageIntent.putExtra("outputY", 512)
|
try {
|
||||||
pickImageIntent.putExtra("aspectX", 1)
|
data.data?.let {
|
||||||
pickImageIntent.putExtra("aspectY", 1)
|
val bitmap = getResizedBitmap(
|
||||||
pickImageIntent.putExtra("scale", true)
|
getBitmap(contentResolver, it),
|
||||||
startActivityForResult(Intent.createChooser(pickImageIntent, "Select Picture"), PICK_IMAGE_REQUEST)
|
PROFILE_ICON_SIZE
|
||||||
}
|
)
|
||||||
|
val profileImagePath = saveToInternalStorage(bitmap, USER_PROFILE)
|
||||||
|
PreferenceUtil.getInstance(this).saveProfileImage(profileImagePath)
|
||||||
|
loadImageFromStorage(profileImagePath)
|
||||||
|
}
|
||||||
|
|
||||||
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
} catch (e: IOException) {
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
e.printStackTrace()
|
||||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
}
|
||||||
when (requestCode) {
|
}
|
||||||
PICK_IMAGE_REQUEST -> {
|
PICK_BANNER_REQUEST -> {
|
||||||
try {
|
try {
|
||||||
data.data?.let {
|
data.data?.let {
|
||||||
val bitmap = getResizedBitmap(getBitmap(contentResolver, it), PROFILE_ICON_SIZE)
|
val bitmap = getBitmap(contentResolver, it)
|
||||||
val profileImagePath = saveToInternalStorage(bitmap, USER_PROFILE)
|
val profileImagePath = saveToInternalStorage(bitmap, USER_BANNER)
|
||||||
PreferenceUtil.getInstance(this).saveProfileImage(profileImagePath)
|
PreferenceUtil.getInstance(this).setBannerImagePath(profileImagePath)
|
||||||
loadImageFromStorage(profileImagePath)
|
loadBannerFromStorage(profileImagePath)
|
||||||
}
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} catch (e: IOException) {
|
private fun getImagePathFromUri(aUri: Uri?): String? {
|
||||||
e.printStackTrace()
|
var imagePath: String? = null
|
||||||
}
|
if (aUri == null) {
|
||||||
}
|
return imagePath
|
||||||
PICK_BANNER_REQUEST -> {
|
}
|
||||||
try {
|
if (DocumentsContract.isDocumentUri(App.getContext(), aUri)) {
|
||||||
data.data?.let {
|
val documentId = DocumentsContract.getDocumentId(aUri)
|
||||||
val bitmap = getBitmap(contentResolver, it)
|
if ("com.android.providers.media.documents" == aUri.authority) {
|
||||||
val profileImagePath = saveToInternalStorage(bitmap, USER_BANNER)
|
val id = documentId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
|
||||||
PreferenceUtil.getInstance(this).setBannerImagePath(profileImagePath)
|
val selection = Media._ID + "=" + id
|
||||||
loadBannerFromStorage(profileImagePath)
|
imagePath = getImagePath(Media.EXTERNAL_CONTENT_URI, selection)
|
||||||
}
|
} else if ("com.android.providers.downloads.documents" == aUri.authority) {
|
||||||
} catch (e: IOException) {
|
val contentUri = ContentUris.withAppendedId(
|
||||||
e.printStackTrace()
|
Uri.parse("content://downloads/public_downloads"),
|
||||||
}
|
java.lang.Long.valueOf(documentId)
|
||||||
}
|
)
|
||||||
}
|
imagePath = getImagePath(contentUri, null)
|
||||||
}
|
}
|
||||||
}
|
} else if ("content".equals(aUri.scheme!!, ignoreCase = true)) {
|
||||||
|
imagePath = getImagePath(aUri, null)
|
||||||
|
} else if ("file".equals(aUri.scheme!!, ignoreCase = true)) {
|
||||||
|
imagePath = aUri.path
|
||||||
|
}
|
||||||
|
return imagePath
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getImagePath(aUri: Uri, aSelection: String?): String? {
|
||||||
|
var path: String? = null
|
||||||
|
val cursor = App.getContext().contentResolver.query(aUri, null, aSelection, null, null)
|
||||||
|
if (cursor != null) {
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
path = cursor.getString(cursor.getColumnIndex(Media.DATA))
|
||||||
|
}
|
||||||
|
cursor.close()
|
||||||
|
}
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
private fun getImagePathFromUri(aUri: Uri?): String? {
|
private fun loadBannerFromStorage(profileImagePath: String) {
|
||||||
var imagePath: String? = null
|
disposable.add(
|
||||||
if (aUri == null) {
|
Compressor(this).setQuality(100).setCompressFormat(Bitmap.CompressFormat.WEBP).compressToBitmapAsFlowable(
|
||||||
return imagePath
|
File(profileImagePath, USER_BANNER)
|
||||||
}
|
).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(
|
||||||
if (DocumentsContract.isDocumentUri(App.getContext(), aUri)) {
|
{ bitmap -> bannerImage.setImageBitmap(bitmap) },
|
||||||
val documentId = DocumentsContract.getDocumentId(aUri)
|
{ t -> println() })
|
||||||
if ("com.android.providers.media.documents" == aUri.authority) {
|
)
|
||||||
val id = documentId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
|
}
|
||||||
val selection = Media._ID + "=" + id
|
|
||||||
imagePath = getImagePath(Media.EXTERNAL_CONTENT_URI, selection)
|
|
||||||
} else if ("com.android.providers.downloads.documents" == aUri.authority) {
|
|
||||||
val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
|
|
||||||
java.lang.Long.valueOf(documentId))
|
|
||||||
imagePath = getImagePath(contentUri, null)
|
|
||||||
}
|
|
||||||
} else if ("content".equals(aUri.scheme!!, ignoreCase = true)) {
|
|
||||||
imagePath = getImagePath(aUri, null)
|
|
||||||
} else if ("file".equals(aUri.scheme!!, ignoreCase = true)) {
|
|
||||||
imagePath = aUri.path
|
|
||||||
}
|
|
||||||
return imagePath
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getImagePath(aUri: Uri, aSelection: String?): String? {
|
private fun loadImageFromStorage(path: String) {
|
||||||
var path: String? = null
|
disposable.add(
|
||||||
val cursor = App.getContext().contentResolver.query(aUri, null, aSelection, null, null)
|
Compressor(this).setMaxHeight(300).setMaxWidth(300).setQuality(75).setCompressFormat(
|
||||||
if (cursor != null) {
|
Bitmap.CompressFormat.WEBP
|
||||||
if (cursor.moveToFirst()) {
|
).compressToBitmapAsFlowable(
|
||||||
path = cursor.getString(cursor.getColumnIndex(Media.DATA))
|
File(
|
||||||
}
|
path,
|
||||||
cursor.close()
|
USER_PROFILE
|
||||||
}
|
)
|
||||||
return path
|
).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(
|
||||||
}
|
{ bitmap -> userImage!!.setImageBitmap(bitmap) },
|
||||||
|
{ t -> println() })
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun loadBannerFromStorage(profileImagePath: String) {
|
private fun saveToInternalStorage(bitmapImage: Bitmap, userBanner: String): String {
|
||||||
disposable.add(Compressor(this)
|
val cw = ContextWrapper(this)
|
||||||
.setQuality(100)
|
val directory = cw.getDir("imageDir", Context.MODE_PRIVATE)
|
||||||
.setCompressFormat(Bitmap.CompressFormat.WEBP)
|
val myPath = File(directory, userBanner)
|
||||||
.compressToBitmapAsFlowable(File(profileImagePath, USER_BANNER))
|
var fos: FileOutputStream? = null
|
||||||
.subscribeOn(Schedulers.io())
|
try {
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
fos = FileOutputStream(myPath)
|
||||||
.subscribe({ bitmap -> bannerImage.setImageBitmap(bitmap) }, { t -> println() }))
|
// Use the compress method on the BitMap object to write image to the OutputStream
|
||||||
}
|
bitmapImage.compress(Bitmap.CompressFormat.WEBP, 100, fos)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
fos?.close()
|
||||||
|
} catch (e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return directory.absolutePath
|
||||||
|
}
|
||||||
|
|
||||||
private fun loadImageFromStorage(path: String) {
|
companion object {
|
||||||
disposable.add(Compressor(this)
|
|
||||||
.setMaxHeight(300)
|
|
||||||
.setMaxWidth(300)
|
|
||||||
.setQuality(75)
|
|
||||||
.setCompressFormat(Bitmap.CompressFormat.WEBP)
|
|
||||||
.compressToBitmapAsFlowable(File(path, USER_PROFILE))
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe({ bitmap -> userImage!!.setImageBitmap(bitmap) }, { t -> println() }))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun saveToInternalStorage(bitmapImage: Bitmap, userBanner: String): String {
|
private const val PICK_IMAGE_REQUEST = 9002
|
||||||
val cw = ContextWrapper(this)
|
private const val PICK_BANNER_REQUEST = 9004
|
||||||
val directory = cw.getDir("imageDir", Context.MODE_PRIVATE)
|
private const val PROFILE_ICON_SIZE = 400
|
||||||
val myPath = File(directory, userBanner)
|
}
|
||||||
var fos: FileOutputStream? = null
|
|
||||||
try {
|
|
||||||
fos = FileOutputStream(myPath)
|
|
||||||
// Use the compress method on the BitMap object to write image to the OutputStream
|
|
||||||
bitmapImage.compress(Bitmap.CompressFormat.WEBP, 100, fos)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
fos?.close()
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return directory.absolutePath
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
private const val PICK_IMAGE_REQUEST = 9002
|
|
||||||
private const val PICK_BANNER_REQUEST = 9004
|
|
||||||
private const val PROFILE_ICON_SIZE = 400
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Activity.pickImage(requestCode: Int) {
|
fun Activity.pickImage(requestCode: Int) {
|
||||||
Intent(Intent.ACTION_GET_CONTENT).apply {
|
Intent(Intent.ACTION_GET_CONTENT).apply {
|
||||||
addCategory(Intent.CATEGORY_OPENABLE)
|
addCategory(Intent.CATEGORY_OPENABLE)
|
||||||
type = "image/*"
|
type = "image/*"
|
||||||
startActivityForResult(this, requestCode)
|
startActivityForResult(this, requestCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,134 +5,139 @@ import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.*
|
||||||
import android.os.Bundle
|
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.view.KeyEvent
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
|
||||||
|
|
||||||
abstract class AbsBaseActivity : AbsThemeActivity() {
|
abstract class AbsBaseActivity : AbsThemeActivity() {
|
||||||
private var hadPermissions: Boolean = false
|
private var hadPermissions: Boolean = false
|
||||||
private lateinit var permissions: Array<String>
|
private lateinit var permissions: Array<String>
|
||||||
private var permissionDeniedMessage: String? = null
|
private var permissionDeniedMessage: String? = null
|
||||||
|
|
||||||
|
open fun getPermissionsToRequest(): Array<String> {
|
||||||
|
return arrayOf()
|
||||||
|
}
|
||||||
|
|
||||||
open fun getPermissionsToRequest(): Array<String> {
|
protected fun setPermissionDeniedMessage(message: String) {
|
||||||
return arrayOf()
|
permissionDeniedMessage = message
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun setPermissionDeniedMessage(message: String) {
|
fun getPermissionDeniedMessage(): String {
|
||||||
permissionDeniedMessage = message
|
return if (permissionDeniedMessage == null) getString(code.name.monkey.retromusic.R.string.permissions_denied) else permissionDeniedMessage!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPermissionDeniedMessage(): String {
|
private val snackBarContainer: View
|
||||||
return if (permissionDeniedMessage == null) getString(code.name.monkey.retromusic.R.string.permissions_denied) else permissionDeniedMessage!!
|
get() = window.decorView
|
||||||
}
|
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
volumeControlStream = AudioManager.STREAM_MUSIC
|
||||||
|
permissions = getPermissionsToRequest()
|
||||||
|
hadPermissions = hasPermissions()
|
||||||
|
permissionDeniedMessage = null
|
||||||
|
}
|
||||||
|
|
||||||
private val snackBarContainer: View
|
override fun onPostCreate(savedInstanceState: Bundle?) {
|
||||||
get() = window.decorView
|
super.onPostCreate(savedInstanceState)
|
||||||
|
if (!hasPermissions()) {
|
||||||
|
requestPermissions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
val hasPermissions = hasPermissions()
|
||||||
|
if (hasPermissions != hadPermissions) {
|
||||||
|
hadPermissions = hasPermissions
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
onHasPermissionsChanged(hasPermissions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
protected open fun onHasPermissionsChanged(hasPermissions: Boolean) {
|
||||||
super.onCreate(savedInstanceState)
|
// implemented by sub classes
|
||||||
volumeControlStream = AudioManager.STREAM_MUSIC
|
}
|
||||||
permissions = getPermissionsToRequest()
|
|
||||||
hadPermissions = hasPermissions()
|
|
||||||
permissionDeniedMessage = null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPostCreate(savedInstanceState: Bundle?) {
|
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
||||||
super.onPostCreate(savedInstanceState)
|
if (event.keyCode == KeyEvent.KEYCODE_MENU && event.action == KeyEvent.ACTION_UP) {
|
||||||
if (!hasPermissions()) {
|
showOverflowMenu()
|
||||||
requestPermissions()
|
return true
|
||||||
}
|
}
|
||||||
}
|
return super.dispatchKeyEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
protected fun showOverflowMenu() {
|
||||||
super.onResume()
|
|
||||||
val hasPermissions = hasPermissions()
|
|
||||||
if (hasPermissions != hadPermissions) {
|
|
||||||
hadPermissions = hasPermissions
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
||||||
onHasPermissionsChanged(hasPermissions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun onHasPermissionsChanged(hasPermissions: Boolean) {
|
}
|
||||||
// implemented by sub classes
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
protected open fun requestPermissions() {
|
||||||
if (event.keyCode == KeyEvent.KEYCODE_MENU && event.action == KeyEvent.ACTION_UP) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
showOverflowMenu()
|
requestPermissions(permissions, PERMISSION_REQUEST)
|
||||||
return true
|
}
|
||||||
}
|
}
|
||||||
return super.dispatchKeyEvent(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun showOverflowMenu() {
|
protected fun hasPermissions(): Boolean {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
for (permission in permissions) {
|
||||||
|
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
}
|
override fun onRequestPermissionsResult(
|
||||||
|
requestCode: Int,
|
||||||
|
permissions: Array<String>,
|
||||||
|
grantResults: IntArray
|
||||||
|
) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
|
if (requestCode == PERMISSION_REQUEST) {
|
||||||
|
for (grantResult in grantResults) {
|
||||||
|
if (grantResult != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
if (ActivityCompat.shouldShowRequestPermissionRationale(
|
||||||
|
this@AbsBaseActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
|
)) {
|
||||||
|
//User has deny from permission dialog
|
||||||
|
Snackbar.make(
|
||||||
|
snackBarContainer,
|
||||||
|
permissionDeniedMessage!!,
|
||||||
|
Snackbar.LENGTH_INDEFINITE
|
||||||
|
)
|
||||||
|
.setAction(code.name.monkey.retromusic.R.string.action_grant) { requestPermissions() }
|
||||||
|
.setActionTextColor(ThemeStore.accentColor(this)).show()
|
||||||
|
} else {
|
||||||
|
// User has deny permission and checked never show permission dialog so you can redirect to Application settings page
|
||||||
|
Snackbar.make(
|
||||||
|
snackBarContainer,
|
||||||
|
permissionDeniedMessage!!,
|
||||||
|
Snackbar.LENGTH_INDEFINITE
|
||||||
|
).setAction(code.name.monkey.retromusic.R.string.action_settings) {
|
||||||
|
val intent = Intent()
|
||||||
|
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
|
||||||
|
val uri = Uri.fromParts(
|
||||||
|
"package",
|
||||||
|
this@AbsBaseActivity.packageName,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
intent.data = uri
|
||||||
|
startActivity(intent)
|
||||||
|
}.setActionTextColor(ThemeStore.accentColor(this)).show()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hadPermissions = true
|
||||||
|
onHasPermissionsChanged(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected open fun requestPermissions() {
|
companion object {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
const val PERMISSION_REQUEST = 100
|
||||||
requestPermissions(permissions, PERMISSION_REQUEST)
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun hasPermissions(): Boolean {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
||||||
for (permission in permissions) {
|
|
||||||
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
|
||||||
if (requestCode == PERMISSION_REQUEST) {
|
|
||||||
for (grantResult in grantResults) {
|
|
||||||
if (grantResult != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
if (ActivityCompat.shouldShowRequestPermissionRationale(this@AbsBaseActivity,
|
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
|
||||||
//User has deny from permission dialog
|
|
||||||
Snackbar.make(snackBarContainer, permissionDeniedMessage!!,
|
|
||||||
Snackbar.LENGTH_INDEFINITE)
|
|
||||||
.setAction(code.name.monkey.retromusic.R.string.action_grant) { requestPermissions() }
|
|
||||||
.setActionTextColor(ThemeStore.accentColor(this))
|
|
||||||
.show()
|
|
||||||
} else {
|
|
||||||
// User has deny permission and checked never show permission dialog so you can redirect to Application settings page
|
|
||||||
Snackbar.make(snackBarContainer, permissionDeniedMessage!!,
|
|
||||||
Snackbar.LENGTH_INDEFINITE)
|
|
||||||
.setAction(code.name.monkey.retromusic.R.string.action_settings) {
|
|
||||||
val intent = Intent()
|
|
||||||
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
|
|
||||||
val uri = Uri.fromParts("package", this@AbsBaseActivity.packageName, null)
|
|
||||||
intent.data = uri
|
|
||||||
startActivity(intent)
|
|
||||||
}
|
|
||||||
.setActionTextColor(ThemeStore.accentColor(this))
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hadPermissions = true
|
|
||||||
onHasPermissionsChanged(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val PERMISSION_REQUEST = 100
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
package code.name.monkey.retromusic.activities.base
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import code.name.monkey.appthemehelper.ATHActivity
|
|
||||||
import code.name.monkey.retromusic.helper.TopExceptionHandler
|
|
||||||
|
|
||||||
abstract class AbsCrashCollector : ATHActivity() {
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
Thread.setDefaultUncaughtExceptionHandler(TopExceptionHandler())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,8 +2,7 @@ package code.name.monkey.retromusic.activities.base
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.*
|
import android.content.*
|
||||||
import android.os.Bundle
|
import android.os.*
|
||||||
import android.os.IBinder
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener
|
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener
|
||||||
|
@ -11,155 +10,158 @@ import code.name.monkey.retromusic.service.MusicService.*
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
abstract class AbsMusicServiceActivity : AbsBaseActivity(), MusicServiceEventListener {
|
abstract class AbsMusicServiceActivity : AbsBaseActivity(), MusicServiceEventListener {
|
||||||
|
|
||||||
private val mMusicServiceEventListeners = ArrayList<MusicServiceEventListener>()
|
private val mMusicServiceEventListeners = ArrayList<MusicServiceEventListener>()
|
||||||
|
|
||||||
private var serviceToken: MusicPlayerRemote.ServiceToken? = null
|
private var serviceToken: MusicPlayerRemote.ServiceToken? = null
|
||||||
private var musicStateReceiver: MusicStateReceiver? = null
|
private var musicStateReceiver: MusicStateReceiver? = null
|
||||||
private var receiverRegistered: Boolean = false
|
private var receiverRegistered: Boolean = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
serviceToken = MusicPlayerRemote.bindToService(this, object : ServiceConnection {
|
serviceToken = MusicPlayerRemote.bindToService(this, object : ServiceConnection {
|
||||||
override fun onServiceConnected(name: ComponentName, service: IBinder) {
|
override fun onServiceConnected(name: ComponentName, service: IBinder) {
|
||||||
this@AbsMusicServiceActivity.onServiceConnected()
|
this@AbsMusicServiceActivity.onServiceConnected()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onServiceDisconnected(name: ComponentName) {
|
override fun onServiceDisconnected(name: ComponentName) {
|
||||||
this@AbsMusicServiceActivity.onServiceDisconnected()
|
this@AbsMusicServiceActivity.onServiceDisconnected()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
setPermissionDeniedMessage(getString(R.string.permission_external_storage_denied));
|
setPermissionDeniedMessage(getString(R.string.permission_external_storage_denied));
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
MusicPlayerRemote.unbindFromService(serviceToken)
|
MusicPlayerRemote.unbindFromService(serviceToken)
|
||||||
if (receiverRegistered) {
|
if (receiverRegistered) {
|
||||||
unregisterReceiver(musicStateReceiver)
|
unregisterReceiver(musicStateReceiver)
|
||||||
receiverRegistered = false
|
receiverRegistered = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addMusicServiceEventListener(listener: MusicServiceEventListener?) {
|
fun addMusicServiceEventListener(listener: MusicServiceEventListener?) {
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
mMusicServiceEventListeners.add(listener)
|
mMusicServiceEventListeners.add(listener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeMusicServiceEventListener(listener: MusicServiceEventListener?) {
|
fun removeMusicServiceEventListener(listener: MusicServiceEventListener?) {
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
mMusicServiceEventListeners.remove(listener)
|
mMusicServiceEventListeners.remove(listener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onServiceConnected() {
|
override fun onServiceConnected() {
|
||||||
if (!receiverRegistered) {
|
if (!receiverRegistered) {
|
||||||
musicStateReceiver = MusicStateReceiver(this)
|
musicStateReceiver = MusicStateReceiver(this)
|
||||||
|
|
||||||
val filter = IntentFilter()
|
val filter = IntentFilter()
|
||||||
filter.addAction(PLAY_STATE_CHANGED)
|
filter.addAction(PLAY_STATE_CHANGED)
|
||||||
filter.addAction(SHUFFLE_MODE_CHANGED)
|
filter.addAction(SHUFFLE_MODE_CHANGED)
|
||||||
filter.addAction(REPEAT_MODE_CHANGED)
|
filter.addAction(REPEAT_MODE_CHANGED)
|
||||||
filter.addAction(META_CHANGED)
|
filter.addAction(META_CHANGED)
|
||||||
filter.addAction(QUEUE_CHANGED)
|
filter.addAction(QUEUE_CHANGED)
|
||||||
filter.addAction(MEDIA_STORE_CHANGED)
|
filter.addAction(MEDIA_STORE_CHANGED)
|
||||||
filter.addAction(FAVORITE_STATE_CHANGED)
|
filter.addAction(FAVORITE_STATE_CHANGED)
|
||||||
|
|
||||||
registerReceiver(musicStateReceiver, filter)
|
registerReceiver(musicStateReceiver, filter)
|
||||||
|
|
||||||
receiverRegistered = true
|
receiverRegistered = true
|
||||||
}
|
}
|
||||||
|
|
||||||
for (listener in mMusicServiceEventListeners) {
|
for (listener in mMusicServiceEventListeners) {
|
||||||
listener.onServiceConnected()
|
listener.onServiceConnected()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onServiceDisconnected() {
|
override fun onServiceDisconnected() {
|
||||||
if (receiverRegistered) {
|
if (receiverRegistered) {
|
||||||
unregisterReceiver(musicStateReceiver)
|
unregisterReceiver(musicStateReceiver)
|
||||||
receiverRegistered = false
|
receiverRegistered = false
|
||||||
}
|
}
|
||||||
|
|
||||||
for (listener in mMusicServiceEventListeners) {
|
for (listener in mMusicServiceEventListeners) {
|
||||||
listener.onServiceDisconnected()
|
listener.onServiceDisconnected()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPlayingMetaChanged() {
|
override fun onPlayingMetaChanged() {
|
||||||
for (listener in mMusicServiceEventListeners) {
|
for (listener in mMusicServiceEventListeners) {
|
||||||
listener.onPlayingMetaChanged()
|
listener.onPlayingMetaChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueueChanged() {
|
override fun onQueueChanged() {
|
||||||
for (listener in mMusicServiceEventListeners) {
|
for (listener in mMusicServiceEventListeners) {
|
||||||
listener.onQueueChanged()
|
listener.onQueueChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPlayStateChanged() {
|
override fun onPlayStateChanged() {
|
||||||
for (listener in mMusicServiceEventListeners) {
|
for (listener in mMusicServiceEventListeners) {
|
||||||
listener.onPlayStateChanged()
|
listener.onPlayStateChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMediaStoreChanged() {
|
override fun onMediaStoreChanged() {
|
||||||
for (listener in mMusicServiceEventListeners) {
|
for (listener in mMusicServiceEventListeners) {
|
||||||
listener.onMediaStoreChanged()
|
listener.onMediaStoreChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRepeatModeChanged() {
|
override fun onRepeatModeChanged() {
|
||||||
for (listener in mMusicServiceEventListeners) {
|
for (listener in mMusicServiceEventListeners) {
|
||||||
listener.onRepeatModeChanged()
|
listener.onRepeatModeChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onShuffleModeChanged() {
|
override fun onShuffleModeChanged() {
|
||||||
for (listener in mMusicServiceEventListeners) {
|
for (listener in mMusicServiceEventListeners) {
|
||||||
listener.onShuffleModeChanged()
|
listener.onShuffleModeChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onHasPermissionsChanged(hasPermissions: Boolean) {
|
override fun onHasPermissionsChanged(hasPermissions: Boolean) {
|
||||||
super.onHasPermissionsChanged(hasPermissions)
|
super.onHasPermissionsChanged(hasPermissions)
|
||||||
val intent = Intent(MEDIA_STORE_CHANGED)
|
val intent = Intent(MEDIA_STORE_CHANGED)
|
||||||
intent.putExtra("from_permissions_changed", true) // just in case we need to know this at some point
|
intent.putExtra(
|
||||||
sendBroadcast(intent)
|
"from_permissions_changed",
|
||||||
}
|
true
|
||||||
|
) // just in case we need to know this at some point
|
||||||
|
sendBroadcast(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPermissionsToRequest(): Array<String> {
|
||||||
|
return arrayOf(
|
||||||
|
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||||
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getPermissionsToRequest(): Array<String> {
|
private class MusicStateReceiver(activity: AbsMusicServiceActivity) : BroadcastReceiver() {
|
||||||
return arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MusicStateReceiver(activity: AbsMusicServiceActivity) : BroadcastReceiver() {
|
private val reference: WeakReference<AbsMusicServiceActivity> = WeakReference(activity)
|
||||||
|
|
||||||
private val reference: WeakReference<AbsMusicServiceActivity> = WeakReference(activity)
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
val action = intent.action
|
||||||
|
val activity = reference.get()
|
||||||
|
if (activity != null && action != null) {
|
||||||
|
when (action) {
|
||||||
|
FAVORITE_STATE_CHANGED, META_CHANGED -> activity.onPlayingMetaChanged()
|
||||||
|
QUEUE_CHANGED -> activity.onQueueChanged()
|
||||||
|
PLAY_STATE_CHANGED -> activity.onPlayStateChanged()
|
||||||
|
REPEAT_MODE_CHANGED -> activity.onRepeatModeChanged()
|
||||||
|
SHUFFLE_MODE_CHANGED -> activity.onShuffleModeChanged()
|
||||||
|
MEDIA_STORE_CHANGED -> activity.onMediaStoreChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
companion object {
|
||||||
val action = intent.action
|
val TAG: String = AbsMusicServiceActivity::class.java.simpleName
|
||||||
val activity = reference.get()
|
}
|
||||||
if (activity != null && action != null) {
|
|
||||||
when (action) {
|
|
||||||
FAVORITE_STATE_CHANGED,
|
|
||||||
META_CHANGED -> activity.onPlayingMetaChanged()
|
|
||||||
QUEUE_CHANGED -> activity.onQueueChanged()
|
|
||||||
PLAY_STATE_CHANGED -> activity.onPlayStateChanged()
|
|
||||||
REPEAT_MODE_CHANGED -> activity.onRepeatModeChanged()
|
|
||||||
SHUFFLE_MODE_CHANGED -> activity.onShuffleModeChanged()
|
|
||||||
MEDIA_STORE_CHANGED -> activity.onMediaStoreChanged()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val TAG: String = AbsMusicServiceActivity::class.java.simpleName
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,22 +2,15 @@ package code.name.monkey.retromusic.activities.base
|
||||||
|
|
||||||
import android.animation.ValueAnimator
|
import android.animation.ValueAnimator
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.graphics.Color
|
import android.graphics.*
|
||||||
import android.graphics.Rect
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.MotionEvent
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.view.ViewTreeObserver
|
|
||||||
import androidx.annotation.LayoutRes
|
import androidx.annotation.LayoutRes
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.extensions.hide
|
import code.name.monkey.retromusic.extensions.*
|
||||||
import code.name.monkey.retromusic.extensions.show
|
import code.name.monkey.retromusic.fragments.*
|
||||||
import code.name.monkey.retromusic.fragments.MiniPlayerFragment
|
|
||||||
import code.name.monkey.retromusic.fragments.NowPlayingScreen
|
|
||||||
import code.name.monkey.retromusic.fragments.NowPlayingScreen.*
|
import code.name.monkey.retromusic.fragments.NowPlayingScreen.*
|
||||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||||
import code.name.monkey.retromusic.fragments.player.adaptive.AdaptiveFragment
|
import code.name.monkey.retromusic.fragments.player.adaptive.AdaptiveFragment
|
||||||
|
@ -35,333 +28,330 @@ import code.name.monkey.retromusic.fragments.player.plain.PlainPlayerFragment
|
||||||
import code.name.monkey.retromusic.fragments.player.simple.SimplePlayerFragment
|
import code.name.monkey.retromusic.fragments.player.simple.SimplePlayerFragment
|
||||||
import code.name.monkey.retromusic.fragments.player.tiny.TinyPlayerFragment
|
import code.name.monkey.retromusic.fragments.player.tiny.TinyPlayerFragment
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.util.DensityUtil
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
|
||||||
import code.name.monkey.retromusic.views.BottomNavigationBarTinted
|
import code.name.monkey.retromusic.views.BottomNavigationBarTinted
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
import com.google.android.material.card.MaterialCardView
|
import com.google.android.material.card.MaterialCardView
|
||||||
import kotlinx.android.synthetic.main.sliding_music_panel_layout.*
|
import kotlinx.android.synthetic.main.sliding_music_panel_layout.*
|
||||||
|
|
||||||
|
|
||||||
abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlayerFragment.Callbacks {
|
abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlayerFragment.Callbacks {
|
||||||
companion object {
|
companion object {
|
||||||
val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName
|
val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var bottomSheetBehavior: BottomSheetBehavior<MaterialCardView>
|
private lateinit var bottomSheetBehavior: BottomSheetBehavior<MaterialCardView>
|
||||||
private var miniPlayerFragment: MiniPlayerFragment? = null
|
private var miniPlayerFragment: MiniPlayerFragment? = null
|
||||||
private var playerFragment: AbsPlayerFragment? = null
|
private var playerFragment: AbsPlayerFragment? = null
|
||||||
private var currentNowPlayingScreen: NowPlayingScreen? = null
|
private var currentNowPlayingScreen: NowPlayingScreen? = null
|
||||||
private var navigationBarColor: Int = 0
|
private var navigationBarColor: Int = 0
|
||||||
private var taskColor: Int = 0
|
private var taskColor: Int = 0
|
||||||
private var lightStatusBar: Boolean = false
|
private var lightStatusBar: Boolean = false
|
||||||
private var lightNavigationBar: Boolean = false
|
private var lightNavigationBar: Boolean = false
|
||||||
private var navigationBarColorAnimator: ValueAnimator? = null
|
private var navigationBarColorAnimator: ValueAnimator? = null
|
||||||
protected abstract fun createContentView(): View
|
protected abstract fun createContentView(): View
|
||||||
private val panelState: Int
|
private val panelState: Int
|
||||||
get() = bottomSheetBehavior.state
|
get() = bottomSheetBehavior.state
|
||||||
|
|
||||||
private val bottomSheetCallbackList = object : BottomSheetBehavior.BottomSheetCallback() {
|
private val bottomSheetCallbackList = object : BottomSheetBehavior.BottomSheetCallback() {
|
||||||
|
|
||||||
override fun onSlide(bottomSheet: View, slideOffset: Float) {
|
override fun onSlide(bottomSheet: View, slideOffset: Float) {
|
||||||
setMiniPlayerAlphaProgress(slideOffset)
|
setMiniPlayerAlphaProgress(slideOffset)
|
||||||
dimBackground.show()
|
dimBackground.show()
|
||||||
dimBackground.alpha = slideOffset
|
dimBackground.alpha = slideOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||||
when (newState) {
|
when (newState) {
|
||||||
BottomSheetBehavior.STATE_EXPANDED -> {
|
BottomSheetBehavior.STATE_EXPANDED -> {
|
||||||
onPanelExpanded()
|
onPanelExpanded()
|
||||||
}
|
}
|
||||||
BottomSheetBehavior.STATE_COLLAPSED -> {
|
BottomSheetBehavior.STATE_COLLAPSED -> {
|
||||||
onPanelCollapsed()
|
onPanelCollapsed()
|
||||||
dimBackground.hide()
|
dimBackground.hide()
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(createContentView())
|
||||||
|
|
||||||
|
chooseFragmentForTheme()
|
||||||
|
setupSlidingUpPanel()
|
||||||
|
|
||||||
|
updateTabs()
|
||||||
|
|
||||||
|
bottomSheetBehavior = BottomSheetBehavior.from(slidingPanel)
|
||||||
|
|
||||||
|
val themeColor = ATHUtil.resolveColor(this, R.attr.colorPrimary, Color.GRAY)
|
||||||
|
dimBackground.setBackgroundColor(ColorUtil.withAlpha(themeColor, 0.5f))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
if (currentNowPlayingScreen != PreferenceUtil.getInstance(this).nowPlayingScreen) {
|
||||||
|
postRecreate()
|
||||||
|
}
|
||||||
|
bottomSheetBehavior.addBottomSheetCallback(bottomSheetCallbackList)
|
||||||
|
|
||||||
|
if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) {
|
||||||
|
setMiniPlayerAlphaProgress(1f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
bottomSheetBehavior.removeBottomSheetCallback(bottomSheetCallbackList)
|
||||||
|
if (navigationBarColorAnimator != null) navigationBarColorAnimator!!.cancel() // just in case
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun wrapSlidingMusicPanel(@LayoutRes resId: Int): View {
|
||||||
|
@SuppressLint("InflateParams") val slidingMusicPanelLayout = layoutInflater.inflate(
|
||||||
|
R.layout.sliding_music_panel_layout, null
|
||||||
|
)
|
||||||
|
val contentContainer = slidingMusicPanelLayout.findViewById<ViewGroup>(R.id.mainContentFrame)
|
||||||
|
layoutInflater.inflate(resId, contentContainer)
|
||||||
|
return slidingMusicPanelLayout
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collapsePanel() {
|
||||||
|
bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
|
||||||
|
}
|
||||||
|
|
||||||
|
fun expandPanel() {
|
||||||
|
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||||
|
setMiniPlayerAlphaProgress(1f)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setMiniPlayerAlphaProgress(progress: Float) {
|
||||||
|
if (miniPlayerFragment?.view == null) return
|
||||||
|
val alpha = 1 - progress
|
||||||
|
miniPlayerFragment?.view?.alpha = alpha
|
||||||
|
// necessary to make the views below clickable
|
||||||
|
miniPlayerFragment?.view?.visibility = if (alpha == 0f) View.GONE else View.VISIBLE
|
||||||
|
|
||||||
|
bottomNavigationView.translationY = progress * 500
|
||||||
|
bottomNavigationView.alpha = alpha
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun onPanelCollapsed() {
|
||||||
|
// restore values
|
||||||
|
super.setLightStatusbar(lightStatusBar)
|
||||||
|
super.setTaskDescriptionColor(taskColor)
|
||||||
|
super.setNavigationbarColor(navigationBarColor)
|
||||||
|
super.setLightNavigationBar(lightNavigationBar)
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
playerFragment?.setMenuVisibility(false)
|
||||||
super.onCreate(savedInstanceState)
|
playerFragment?.userVisibleHint = false
|
||||||
setContentView(createContentView())
|
playerFragment?.onHide()
|
||||||
|
}
|
||||||
|
|
||||||
chooseFragmentForTheme()
|
open fun onPanelExpanded() {
|
||||||
setupSlidingUpPanel()
|
val playerFragmentColor = playerFragment!!.paletteColor
|
||||||
|
super.setTaskDescriptionColor(playerFragmentColor)
|
||||||
|
|
||||||
updateTabs()
|
playerFragment?.setMenuVisibility(true)
|
||||||
|
playerFragment?.userVisibleHint = true
|
||||||
|
playerFragment?.onShow()
|
||||||
|
onPaletteColorChanged()
|
||||||
|
}
|
||||||
|
|
||||||
bottomSheetBehavior = BottomSheetBehavior.from(slidingPanel)
|
private fun setupSlidingUpPanel() {
|
||||||
|
slidingPanel.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
|
||||||
|
override fun onGlobalLayout() {
|
||||||
|
slidingPanel.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||||
|
if (currentNowPlayingScreen != PEAK) {
|
||||||
|
val params = slidingPanel.layoutParams as ViewGroup.LayoutParams
|
||||||
|
params.height = ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
slidingPanel.layoutParams = params
|
||||||
|
}
|
||||||
|
when (panelState) {
|
||||||
|
BottomSheetBehavior.STATE_EXPANDED -> onPanelExpanded()
|
||||||
|
BottomSheetBehavior.STATE_COLLAPSED -> onPanelCollapsed()
|
||||||
|
else -> playerFragment!!.onHide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
val themeColor = ATHUtil.resolveColor(this, R.attr.colorPrimary, Color.GRAY)
|
fun toggleBottomNavigationView(toggle: Boolean) {
|
||||||
dimBackground.setBackgroundColor(ColorUtil.withAlpha(themeColor, 0.5f))
|
bottomNavigationView.visibility = if (toggle) View.GONE else View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
fun getBottomNavigationView(): BottomNavigationBarTinted {
|
||||||
super.onResume()
|
return bottomNavigationView
|
||||||
if (currentNowPlayingScreen != PreferenceUtil.getInstance(this).nowPlayingScreen) {
|
}
|
||||||
postRecreate()
|
|
||||||
}
|
|
||||||
bottomSheetBehavior.addBottomSheetCallback(bottomSheetCallbackList)
|
|
||||||
|
|
||||||
if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) {
|
private fun hideBottomBar(hide: Boolean) {
|
||||||
setMiniPlayerAlphaProgress(1f)
|
val heightOfBar = resources.getDimensionPixelSize(R.dimen.mini_player_height)
|
||||||
}
|
val heightOfBarWithTabs = resources.getDimensionPixelSize(R.dimen.mini_player_height_expanded)
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
if (hide) {
|
||||||
super.onDestroy()
|
bottomSheetBehavior.isHideable = true
|
||||||
bottomSheetBehavior.removeBottomSheetCallback(bottomSheetCallbackList)
|
bottomSheetBehavior.peekHeight = 0
|
||||||
if (navigationBarColorAnimator != null) navigationBarColorAnimator!!.cancel() // just in case
|
collapsePanel()
|
||||||
}
|
bottomNavigationView.elevation = DensityUtil.dip2px(this, 10f).toFloat()
|
||||||
|
} else {
|
||||||
|
if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
|
||||||
|
slidingPanel.cardElevation = DensityUtil.dip2px(this, 10f).toFloat()
|
||||||
|
bottomNavigationView.elevation = DensityUtil.dip2px(this, 10f).toFloat()
|
||||||
|
bottomSheetBehavior.isHideable = false
|
||||||
|
bottomSheetBehavior.peekHeight = if (bottomNavigationView.visibility == View.VISIBLE) heightOfBarWithTabs else heightOfBar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setBottomBarVisibility(gone: Int) {
|
||||||
|
bottomNavigationView.visibility = gone
|
||||||
|
hideBottomBar(false)
|
||||||
|
}
|
||||||
|
|
||||||
protected fun wrapSlidingMusicPanel(@LayoutRes resId: Int): View {
|
private fun chooseFragmentForTheme() {
|
||||||
@SuppressLint("InflateParams")
|
currentNowPlayingScreen = PreferenceUtil.getInstance(this).nowPlayingScreen
|
||||||
val slidingMusicPanelLayout = layoutInflater.inflate(R.layout.sliding_music_panel_layout, null)
|
|
||||||
val contentContainer = slidingMusicPanelLayout.findViewById<ViewGroup>(R.id.mainContentFrame)
|
|
||||||
layoutInflater.inflate(resId, contentContainer)
|
|
||||||
return slidingMusicPanelLayout
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun collapsePanel() {
|
val fragment: Fragment = when (currentNowPlayingScreen) {
|
||||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
|
BLUR -> BlurPlayerFragment()
|
||||||
}
|
ADAPTIVE -> AdaptiveFragment()
|
||||||
|
NORMAL -> PlayerFragment()
|
||||||
|
CARD -> CardFragment()
|
||||||
|
BLUR_CARD -> CardBlurFragment()
|
||||||
|
FIT -> FitFragment()
|
||||||
|
FLAT -> FlatPlayerFragment()
|
||||||
|
FULL -> FullPlayerFragment()
|
||||||
|
PLAIN -> PlainPlayerFragment()
|
||||||
|
SIMPLE -> SimplePlayerFragment()
|
||||||
|
MATERIAL -> MaterialFragment()
|
||||||
|
COLOR -> ColorFragment()
|
||||||
|
TINY -> TinyPlayerFragment()
|
||||||
|
PEAK -> PeakPlayerFragment()
|
||||||
|
else -> PlayerFragment()
|
||||||
|
} // must implement AbsPlayerFragment
|
||||||
|
supportFragmentManager.beginTransaction().replace(R.id.playerFragmentContainer, fragment)
|
||||||
|
.commit()
|
||||||
|
supportFragmentManager.executePendingTransactions()
|
||||||
|
|
||||||
fun expandPanel() {
|
playerFragment = supportFragmentManager.findFragmentById(R.id.playerFragmentContainer) as AbsPlayerFragment
|
||||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
|
miniPlayerFragment = supportFragmentManager.findFragmentById(R.id.miniPlayerFragment) as MiniPlayerFragment
|
||||||
setMiniPlayerAlphaProgress(1f)
|
miniPlayerFragment?.view?.setOnClickListener { expandPanel() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setMiniPlayerAlphaProgress(progress: Float) {
|
override fun onServiceConnected() {
|
||||||
if (miniPlayerFragment?.view == null) return
|
super.onServiceConnected()
|
||||||
val alpha = 1 - progress
|
if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
|
||||||
miniPlayerFragment?.view?.alpha = alpha
|
slidingPanel.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
|
||||||
// necessary to make the views below clickable
|
override fun onGlobalLayout() {
|
||||||
miniPlayerFragment?.view?.visibility = if (alpha == 0f) View.GONE else View.VISIBLE
|
slidingPanel.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||||
|
hideBottomBar(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} // don't call hideBottomBar(true) here as it causes a bug with the SlidingUpPanelLayout
|
||||||
|
}
|
||||||
|
|
||||||
bottomNavigationView.translationY = progress * 500
|
override fun onQueueChanged() {
|
||||||
bottomNavigationView.alpha = alpha
|
super.onQueueChanged()
|
||||||
}
|
hideBottomBar(MusicPlayerRemote.playingQueue.isEmpty())
|
||||||
|
}
|
||||||
|
|
||||||
open fun onPanelCollapsed() {
|
override fun onBackPressed() {
|
||||||
// restore values
|
if (!handleBackPress()) super.onBackPressed()
|
||||||
super.setLightStatusbar(lightStatusBar)
|
}
|
||||||
super.setTaskDescriptionColor(taskColor)
|
|
||||||
super.setNavigationbarColor(navigationBarColor)
|
|
||||||
super.setLightNavigationBar(lightNavigationBar)
|
|
||||||
|
|
||||||
|
open fun handleBackPress(): Boolean {
|
||||||
|
if (bottomSheetBehavior.peekHeight != 0 && playerFragment!!.onBackPressed()) return true
|
||||||
|
if (panelState == BottomSheetBehavior.STATE_EXPANDED) {
|
||||||
|
collapsePanel()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
playerFragment?.setMenuVisibility(false)
|
override fun onPaletteColorChanged() {
|
||||||
playerFragment?.userVisibleHint = false
|
if (panelState == BottomSheetBehavior.STATE_EXPANDED) {
|
||||||
playerFragment?.onHide()
|
val paletteColor = playerFragment!!.paletteColor
|
||||||
}
|
super.setTaskDescriptionColor(paletteColor)
|
||||||
|
|
||||||
open fun onPanelExpanded() {
|
val isColorLight = ColorUtil.isColorLight(paletteColor)
|
||||||
val playerFragmentColor = playerFragment!!.paletteColor
|
|
||||||
super.setTaskDescriptionColor(playerFragmentColor)
|
|
||||||
|
|
||||||
playerFragment?.setMenuVisibility(true)
|
if (PreferenceUtil.getInstance(this).adaptiveColor && (currentNowPlayingScreen == NORMAL || currentNowPlayingScreen == FLAT)) {
|
||||||
playerFragment?.userVisibleHint = true
|
super.setLightNavigationBar(true)
|
||||||
playerFragment?.onShow()
|
super.setLightStatusbar(isColorLight)
|
||||||
onPaletteColorChanged()
|
} else if (currentNowPlayingScreen == FULL || currentNowPlayingScreen == CARD || currentNowPlayingScreen == FIT || currentNowPlayingScreen == BLUR || currentNowPlayingScreen == BLUR_CARD) {
|
||||||
}
|
super.setLightStatusbar(false)
|
||||||
|
super.setLightNavigationBar(true)
|
||||||
|
} else if (currentNowPlayingScreen == COLOR || currentNowPlayingScreen == TINY) {
|
||||||
|
super.setNavigationbarColor(paletteColor)
|
||||||
|
super.setLightNavigationBar(isColorLight)
|
||||||
|
super.setLightStatusbar(isColorLight)
|
||||||
|
} else {
|
||||||
|
super.setLightStatusbar(
|
||||||
|
ColorUtil.isColorLight(
|
||||||
|
ATHUtil.resolveColor(
|
||||||
|
this, R.attr.colorPrimary
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
super.setLightNavigationBar(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupSlidingUpPanel() {
|
override fun setLightStatusbar(enabled: Boolean) {
|
||||||
slidingPanel.viewTreeObserver
|
lightStatusBar = enabled
|
||||||
.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
|
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||||
override fun onGlobalLayout() {
|
super.setLightStatusbar(enabled)
|
||||||
slidingPanel.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
}
|
||||||
if (currentNowPlayingScreen != PEAK) {
|
}
|
||||||
val params = slidingPanel.layoutParams as ViewGroup.LayoutParams
|
|
||||||
params.height = ViewGroup.LayoutParams.MATCH_PARENT
|
|
||||||
slidingPanel.layoutParams = params
|
|
||||||
}
|
|
||||||
when (panelState) {
|
|
||||||
BottomSheetBehavior.STATE_EXPANDED -> {
|
|
||||||
onPanelExpanded()
|
|
||||||
}
|
|
||||||
BottomSheetBehavior.STATE_COLLAPSED -> onPanelCollapsed()
|
|
||||||
else -> playerFragment!!.onHide()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fun toggleBottomNavigationView(toggle: Boolean) {
|
override fun setLightNavigationBar(enabled: Boolean) {
|
||||||
bottomNavigationView.visibility = if (toggle) View.GONE else View.VISIBLE
|
lightNavigationBar = enabled
|
||||||
}
|
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||||
|
super.setLightNavigationBar(enabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getBottomNavigationView(): BottomNavigationBarTinted {
|
override fun setNavigationbarColor(color: Int) {
|
||||||
return bottomNavigationView
|
navigationBarColor = color
|
||||||
}
|
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||||
|
if (navigationBarColorAnimator != null) navigationBarColorAnimator!!.cancel()
|
||||||
|
super.setNavigationbarColor(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun hideBottomBar(hide: Boolean) {
|
override fun setTaskDescriptionColor(color: Int) {
|
||||||
val heightOfBar = resources.getDimensionPixelSize(R.dimen.mini_player_height)
|
taskColor = color
|
||||||
val heightOfBarWithTabs = resources.getDimensionPixelSize(R.dimen.mini_player_height_expanded)
|
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||||
|
super.setTaskDescriptionColor(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (hide) {
|
private fun updateTabs() {
|
||||||
bottomSheetBehavior.isHideable = true
|
bottomNavigationView.menu.clear()
|
||||||
bottomSheetBehavior.peekHeight = 0
|
val currentTabs = PreferenceUtil.getInstance(this).libraryCategoryInfos
|
||||||
collapsePanel()
|
for (tab in currentTabs) {
|
||||||
bottomNavigationView.elevation = DensityUtil.dip2px(this, 10f).toFloat()
|
if (tab.visible) {
|
||||||
} else {
|
val menu = tab.category
|
||||||
if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
|
bottomNavigationView.menu.add(
|
||||||
slidingPanel.cardElevation = DensityUtil.dip2px(this, 10f).toFloat()
|
0, menu.id, 0, menu.stringRes
|
||||||
bottomNavigationView.elevation = DensityUtil.dip2px(this, 10f).toFloat()
|
).setIcon(menu.icon)
|
||||||
bottomSheetBehavior.isHideable = false
|
}
|
||||||
bottomSheetBehavior.peekHeight = if (bottomNavigationView.visibility == View.VISIBLE) heightOfBarWithTabs else heightOfBar
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setBottomBarVisibility(gone: Int) {
|
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
|
||||||
bottomNavigationView.visibility = gone
|
if (ev?.action == MotionEvent.ACTION_DOWN) {
|
||||||
hideBottomBar(false)
|
if (panelState == BottomSheetBehavior.STATE_EXPANDED) {
|
||||||
}
|
val outRect = Rect()
|
||||||
|
slidingPanel.getGlobalVisibleRect(outRect)
|
||||||
private fun chooseFragmentForTheme() {
|
if (!outRect.contains(ev.rawX.toInt(), ev.rawY.toInt())) {
|
||||||
currentNowPlayingScreen = PreferenceUtil.getInstance(this).nowPlayingScreen
|
bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
|
||||||
|
}
|
||||||
val fragment: Fragment = when (currentNowPlayingScreen) {
|
}
|
||||||
BLUR -> BlurPlayerFragment()
|
}
|
||||||
ADAPTIVE -> AdaptiveFragment()
|
return super.dispatchTouchEvent(ev)
|
||||||
NORMAL -> PlayerFragment()
|
}
|
||||||
CARD -> CardFragment()
|
|
||||||
BLUR_CARD -> CardBlurFragment()
|
|
||||||
FIT -> FitFragment()
|
|
||||||
FLAT -> FlatPlayerFragment()
|
|
||||||
FULL -> FullPlayerFragment()
|
|
||||||
PLAIN -> PlainPlayerFragment()
|
|
||||||
SIMPLE -> SimplePlayerFragment()
|
|
||||||
MATERIAL -> MaterialFragment()
|
|
||||||
COLOR -> ColorFragment()
|
|
||||||
TINY -> TinyPlayerFragment()
|
|
||||||
PEAK -> PeakPlayerFragment()
|
|
||||||
else -> PlayerFragment()
|
|
||||||
} // must implement AbsPlayerFragment
|
|
||||||
supportFragmentManager.beginTransaction().replace(R.id.playerFragmentContainer, fragment).commit()
|
|
||||||
supportFragmentManager.executePendingTransactions()
|
|
||||||
|
|
||||||
playerFragment = supportFragmentManager.findFragmentById(R.id.playerFragmentContainer) as AbsPlayerFragment
|
|
||||||
miniPlayerFragment = supportFragmentManager.findFragmentById(R.id.miniPlayerFragment) as MiniPlayerFragment
|
|
||||||
miniPlayerFragment!!.view!!.setOnClickListener { expandPanel() }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onServiceConnected() {
|
|
||||||
super.onServiceConnected()
|
|
||||||
if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
|
|
||||||
slidingPanel.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
|
|
||||||
override fun onGlobalLayout() {
|
|
||||||
slidingPanel.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
|
||||||
hideBottomBar(false)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} // don't call hideBottomBar(true) here as it causes a bug with the SlidingUpPanelLayout
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onQueueChanged() {
|
|
||||||
super.onQueueChanged()
|
|
||||||
hideBottomBar(MusicPlayerRemote.playingQueue.isEmpty())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBackPressed() {
|
|
||||||
if (!handleBackPress())
|
|
||||||
super.onBackPressed()
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun handleBackPress(): Boolean {
|
|
||||||
if (bottomSheetBehavior.peekHeight != 0 && playerFragment!!.onBackPressed())
|
|
||||||
return true
|
|
||||||
if (panelState == BottomSheetBehavior.STATE_EXPANDED) {
|
|
||||||
collapsePanel()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPaletteColorChanged() {
|
|
||||||
if (panelState == BottomSheetBehavior.STATE_EXPANDED) {
|
|
||||||
val paletteColor = playerFragment!!.paletteColor
|
|
||||||
super.setTaskDescriptionColor(paletteColor)
|
|
||||||
|
|
||||||
val isColorLight = ColorUtil.isColorLight(paletteColor)
|
|
||||||
|
|
||||||
if (PreferenceUtil.getInstance(this).adaptiveColor &&
|
|
||||||
(currentNowPlayingScreen == NORMAL || currentNowPlayingScreen == FLAT)) {
|
|
||||||
super.setLightNavigationBar(true)
|
|
||||||
super.setLightStatusbar(isColorLight)
|
|
||||||
} else if (currentNowPlayingScreen == FULL || currentNowPlayingScreen == CARD ||
|
|
||||||
currentNowPlayingScreen == FIT || currentNowPlayingScreen == BLUR || currentNowPlayingScreen == BLUR_CARD) {
|
|
||||||
super.setLightStatusbar(false)
|
|
||||||
super.setLightNavigationBar(true)
|
|
||||||
} else if (currentNowPlayingScreen == COLOR || currentNowPlayingScreen == TINY) {
|
|
||||||
super.setNavigationbarColor(paletteColor)
|
|
||||||
super.setLightNavigationBar(isColorLight)
|
|
||||||
super.setLightStatusbar(isColorLight)
|
|
||||||
} else {
|
|
||||||
super.setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
|
|
||||||
super.setLightNavigationBar(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setLightStatusbar(enabled: Boolean) {
|
|
||||||
lightStatusBar = enabled
|
|
||||||
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
|
||||||
super.setLightStatusbar(enabled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setLightNavigationBar(enabled: Boolean) {
|
|
||||||
lightNavigationBar = enabled
|
|
||||||
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
|
||||||
super.setLightNavigationBar(enabled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setNavigationbarColor(color: Int) {
|
|
||||||
navigationBarColor = color
|
|
||||||
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
|
||||||
if (navigationBarColorAnimator != null) navigationBarColorAnimator!!.cancel()
|
|
||||||
super.setNavigationbarColor(color)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setTaskDescriptionColor(color: Int) {
|
|
||||||
taskColor = color
|
|
||||||
if (panelState == BottomSheetBehavior.STATE_COLLAPSED) {
|
|
||||||
super.setTaskDescriptionColor(color)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun updateTabs() {
|
|
||||||
bottomNavigationView.menu.clear()
|
|
||||||
val currentTabs = PreferenceUtil.getInstance(this).libraryCategoryInfos
|
|
||||||
for (tab in currentTabs) {
|
|
||||||
if (tab.visible) {
|
|
||||||
val menu = tab.category
|
|
||||||
bottomNavigationView.menu.add(0, menu.id, 0, menu.stringRes)
|
|
||||||
.setIcon(menu.icon)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
|
|
||||||
if (ev?.action == MotionEvent.ACTION_DOWN) {
|
|
||||||
if (panelState == BottomSheetBehavior.STATE_EXPANDED) {
|
|
||||||
val outRect = Rect()
|
|
||||||
slidingPanel.getGlobalVisibleRect(outRect)
|
|
||||||
if (!outRect.contains(ev.rawX.toInt(), ev.rawY.toInt())) {
|
|
||||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.dispatchTouchEvent(ev)
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -2,207 +2,199 @@ package code.name.monkey.retromusic.activities.base
|
||||||
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.Bundle
|
import android.os.*
|
||||||
import android.os.Handler
|
import android.view.*
|
||||||
import android.view.KeyEvent
|
|
||||||
import android.view.View
|
|
||||||
import android.view.WindowManager
|
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import code.name.monkey.appthemehelper.ATH
|
import code.name.monkey.appthemehelper.*
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
|
||||||
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
|
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
|
||||||
import code.name.monkey.appthemehelper.util.TintHelper
|
|
||||||
import code.name.monkey.appthemehelper.util.VersionUtils
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.RetroUtil
|
|
||||||
import code.name.monkey.retromusic.util.ThemeManager
|
|
||||||
|
|
||||||
abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
|
abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
|
||||||
|
|
||||||
private val handler = Handler()
|
private val handler = Handler()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setTheme(ThemeManager.getThemeResValue(this))
|
setTheme(ThemeManager.getThemeResValue(this))
|
||||||
hideStatusBar()
|
hideStatusBar()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
changeBackgroundShape()
|
changeBackgroundShape()
|
||||||
setImmersiveFullscreen()
|
setImmersiveFullscreen()
|
||||||
registerSystemUiVisibility()
|
registerSystemUiVisibility()
|
||||||
toggleScreenOn()
|
toggleScreenOn()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toggleScreenOn() {
|
private fun toggleScreenOn() {
|
||||||
if (PreferenceUtil.getInstance(this).isScreenOnEnabled) {
|
if (PreferenceUtil.getInstance(this).isScreenOnEnabled) {
|
||||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
} else {
|
} else {
|
||||||
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onWindowFocusChanged(hasFocus: Boolean) {
|
override fun onWindowFocusChanged(hasFocus: Boolean) {
|
||||||
super.onWindowFocusChanged(hasFocus)
|
super.onWindowFocusChanged(hasFocus)
|
||||||
if (hasFocus) {
|
if (hasFocus) {
|
||||||
hideStatusBar()
|
hideStatusBar()
|
||||||
handler.removeCallbacks(this)
|
handler.removeCallbacks(this)
|
||||||
handler.postDelayed(this, 300)
|
handler.postDelayed(this, 300)
|
||||||
} else {
|
} else {
|
||||||
handler.removeCallbacks(this)
|
handler.removeCallbacks(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hideStatusBar() {
|
fun hideStatusBar() {
|
||||||
hideStatusBar(PreferenceUtil.getInstance(this).fullScreenMode)
|
hideStatusBar(PreferenceUtil.getInstance(this).fullScreenMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hideStatusBar(fullscreen: Boolean) {
|
private fun hideStatusBar(fullscreen: Boolean) {
|
||||||
val statusBar = window.decorView.rootView.findViewById<View>(R.id.status_bar)
|
val statusBar = window.decorView.rootView.findViewById<View>(R.id.status_bar)
|
||||||
if (statusBar != null) {
|
if (statusBar != null) {
|
||||||
statusBar.visibility = if (fullscreen) View.GONE else View.VISIBLE
|
statusBar.visibility = if (fullscreen) View.GONE else View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun changeBackgroundShape() {
|
||||||
|
var background: Drawable? = if (PreferenceUtil.getInstance(this).isRoundCorners) ContextCompat.getDrawable(
|
||||||
|
this,
|
||||||
|
R.drawable.round_window
|
||||||
|
)
|
||||||
|
else ContextCompat.getDrawable(this, R.drawable.square_window)
|
||||||
|
background = TintHelper.createTintedDrawable(
|
||||||
|
background,
|
||||||
|
ATHUtil.resolveColor(this, R.attr.colorPrimary)
|
||||||
|
)
|
||||||
|
window.setBackgroundDrawable(background)
|
||||||
|
}
|
||||||
|
|
||||||
private fun changeBackgroundShape() {
|
fun setDrawUnderStatusBar() {
|
||||||
var background: Drawable? = if (PreferenceUtil.getInstance(this).isRoundCorners)
|
RetroUtil.setAllowDrawUnderStatusBar(window)
|
||||||
ContextCompat.getDrawable(this, R.drawable.round_window)
|
}
|
||||||
else
|
|
||||||
ContextCompat.getDrawable(this, R.drawable.square_window)
|
|
||||||
background = TintHelper.createTintedDrawable(background, ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
|
||||||
window.setBackgroundDrawable(background)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setDrawUnderStatusBar() {
|
fun setDrawUnderNavigationBar() {
|
||||||
RetroUtil.setAllowDrawUnderStatusBar(window)
|
RetroUtil.setAllowDrawUnderNavigationBar(window)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setDrawUnderNavigationBar() {
|
/**
|
||||||
RetroUtil.setAllowDrawUnderNavigationBar(window)
|
* This will set the color of the view with the id "status_bar" on KitKat and Lollipop. On
|
||||||
}
|
* Lollipop if no such view is found it will set the statusbar color using the native method.
|
||||||
|
*
|
||||||
|
* @param color the new statusbar color (will be shifted down on Lollipop and above)
|
||||||
|
*/
|
||||||
|
fun setStatusbarColor(color: Int) {
|
||||||
|
val statusBar = window.decorView.rootView.findViewById<View>(R.id.status_bar)
|
||||||
|
if (statusBar != null) {
|
||||||
|
when {
|
||||||
|
VersionUtils.hasMarshmallow() -> window.statusBarColor = color
|
||||||
|
VersionUtils.hasLollipop() -> statusBar.setBackgroundColor(
|
||||||
|
ColorUtil.darkenColor(
|
||||||
|
color
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else -> statusBar.setBackgroundColor(color)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
when {
|
||||||
|
VersionUtils.hasMarshmallow() -> window.statusBarColor = color
|
||||||
|
else -> window.statusBarColor = ColorUtil.darkenColor(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setLightStatusbarAuto(color)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
fun setStatusbarColorAuto() {
|
||||||
* This will set the color of the view with the id "status_bar" on KitKat and Lollipop. On
|
// we don't want to use statusbar color because we are doing the color darkening on our own to support KitKat
|
||||||
* Lollipop if no such view is found it will set the statusbar color using the native method.
|
setStatusbarColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
||||||
*
|
}
|
||||||
* @param color the new statusbar color (will be shifted down on Lollipop and above)
|
|
||||||
*/
|
|
||||||
fun setStatusbarColor(color: Int) {
|
|
||||||
val statusBar = window.decorView.rootView.findViewById<View>(R.id.status_bar)
|
|
||||||
if (statusBar != null) {
|
|
||||||
when {
|
|
||||||
VersionUtils.hasMarshmallow() -> window.statusBarColor = color
|
|
||||||
VersionUtils.hasLollipop() -> statusBar.setBackgroundColor(ColorUtil.darkenColor(color))
|
|
||||||
else -> statusBar.setBackgroundColor(color)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
when {
|
|
||||||
VersionUtils.hasMarshmallow() -> window.statusBarColor = color
|
|
||||||
else -> window.statusBarColor = ColorUtil.darkenColor(color)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setLightStatusbarAuto(color)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setStatusbarColorAuto() {
|
open fun setTaskDescriptionColor(@ColorInt color: Int) {
|
||||||
// we don't want to use statusbar color because we are doing the color darkening on our own to support KitKat
|
ATH.setTaskDescriptionColor(this, color)
|
||||||
setStatusbarColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
}
|
||||||
}
|
|
||||||
|
|
||||||
open fun setTaskDescriptionColor(@ColorInt color: Int) {
|
fun setTaskDescriptionColorAuto() {
|
||||||
ATH.setTaskDescriptionColor(this, color)
|
setTaskDescriptionColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setTaskDescriptionColorAuto() {
|
open fun setNavigationbarColor(color: Int) {
|
||||||
setTaskDescriptionColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
if (ThemeStore.coloredNavigationBar(this)) {
|
||||||
}
|
ATH.setNavigationbarColor(this, color)
|
||||||
|
} else {
|
||||||
|
ATH.setNavigationbarColor(this, Color.BLACK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open fun setNavigationbarColor(color: Int) {
|
open fun setNavigationBarColorPrimary() {
|
||||||
if (ThemeStore.coloredNavigationBar(this)) {
|
ATH.setNavigationbarColor(this, ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
||||||
ATH.setNavigationbarColor(this, color)
|
}
|
||||||
} else {
|
|
||||||
ATH.setNavigationbarColor(this, Color.BLACK)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun setNavigationBarColorPrimary() {
|
fun setNavigationbarColorAuto() {
|
||||||
ATH.setNavigationbarColor(this, ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
setNavigationbarColor(ATHUtil.resolveColor(this, R.attr.colorSecondary))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setNavigationbarColorAuto() {
|
open fun setLightStatusbar(enabled: Boolean) {
|
||||||
setNavigationbarColor(ATHUtil.resolveColor(this, R.attr.colorSecondary))
|
ATH.setLightStatusbar(this, enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun setLightStatusbar(enabled: Boolean) {
|
fun setLightStatusbarAuto(bgColor: Int) {
|
||||||
ATH.setLightStatusbar(this, enabled)
|
setLightStatusbar(ColorUtil.isColorLight(bgColor))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setLightStatusbarAuto(bgColor: Int) {
|
open fun setLightNavigationBar(enabled: Boolean) {
|
||||||
setLightStatusbar(ColorUtil.isColorLight(bgColor))
|
if (!ATHUtil.isWindowBackgroundDark(this) and ThemeStore.coloredNavigationBar(this)) {
|
||||||
}
|
ATH.setLightNavigationbar(this, enabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open fun setLightNavigationBar(enabled: Boolean) {
|
private fun registerSystemUiVisibility() {
|
||||||
if (!ATHUtil.isWindowBackgroundDark(this) and ThemeStore.coloredNavigationBar(this)) {
|
val decorView = window.decorView
|
||||||
ATH.setLightNavigationbar(this, enabled)
|
decorView.setOnSystemUiVisibilityChangeListener { visibility ->
|
||||||
}
|
if (visibility and View.SYSTEM_UI_FLAG_FULLSCREEN == 0) {
|
||||||
}
|
setImmersiveFullscreen()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun registerSystemUiVisibility() {
|
private fun unregisterSystemUiVisibility() {
|
||||||
val decorView = window.decorView
|
val decorView = window.decorView
|
||||||
decorView.setOnSystemUiVisibilityChangeListener { visibility ->
|
decorView.setOnSystemUiVisibilityChangeListener(null)
|
||||||
if (visibility and View.SYSTEM_UI_FLAG_FULLSCREEN == 0) {
|
}
|
||||||
setImmersiveFullscreen()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun unregisterSystemUiVisibility() {
|
private fun setImmersiveFullscreen() {
|
||||||
val decorView = window.decorView
|
val flags = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
|
||||||
decorView.setOnSystemUiVisibilityChangeListener(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setImmersiveFullscreen() {
|
if (PreferenceUtil.getInstance(this).fullScreenMode) {
|
||||||
val flags = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
window.decorView.systemUiVisibility = flags
|
||||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
}
|
||||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
}
|
||||||
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
|
||||||
or View.SYSTEM_UI_FLAG_FULLSCREEN
|
|
||||||
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
|
|
||||||
|
|
||||||
if (PreferenceUtil.getInstance(this).fullScreenMode) {
|
private fun exitFullscreen() {
|
||||||
window.decorView.systemUiVisibility = flags
|
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun exitFullscreen() {
|
override fun run() {
|
||||||
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE
|
setImmersiveFullscreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun run() {
|
override fun onStop() {
|
||||||
setImmersiveFullscreen()
|
handler.removeCallbacks(this)
|
||||||
}
|
super.onStop()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onStop() {
|
public override fun onDestroy() {
|
||||||
handler.removeCallbacks(this)
|
super.onDestroy()
|
||||||
super.onStop()
|
unregisterSystemUiVisibility()
|
||||||
}
|
exitFullscreen()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun onDestroy() {
|
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
|
||||||
super.onDestroy()
|
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
|
||||||
unregisterSystemUiVisibility()
|
handler.removeCallbacks(this)
|
||||||
exitFullscreen()
|
handler.postDelayed(this, 500)
|
||||||
}
|
}
|
||||||
|
return super.onKeyDown(keyCode, event)
|
||||||
|
|
||||||
|
}
|
||||||
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
|
|
||||||
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
|
|
||||||
handler.removeCallbacks(this)
|
|
||||||
handler.postDelayed(this, 500)
|
|
||||||
}
|
|
||||||
return super.onKeyDown(keyCode, event)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,32 +1,21 @@
|
||||||
package code.name.monkey.retromusic.activities.bugreport
|
package code.name.monkey.retromusic.activities.bugreport
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.*
|
||||||
import android.app.Dialog
|
import android.content.*
|
||||||
import android.content.ClipData
|
|
||||||
import android.content.ClipboardManager
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.annotation.StringDef
|
import androidx.annotation.*
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
|
||||||
import code.name.monkey.appthemehelper.util.TintHelper
|
|
||||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.activities.base.AbsThemeActivity
|
import code.name.monkey.retromusic.activities.base.AbsThemeActivity
|
||||||
import code.name.monkey.retromusic.activities.bugreport.model.DeviceInfo
|
import code.name.monkey.retromusic.activities.bugreport.model.*
|
||||||
import code.name.monkey.retromusic.activities.bugreport.model.Report
|
import code.name.monkey.retromusic.activities.bugreport.model.github.*
|
||||||
import code.name.monkey.retromusic.activities.bugreport.model.github.ExtraInfo
|
|
||||||
import code.name.monkey.retromusic.activities.bugreport.model.github.GithubLogin
|
|
||||||
import code.name.monkey.retromusic.activities.bugreport.model.github.GithubTarget
|
|
||||||
import code.name.monkey.retromusic.misc.DialogAsyncTask
|
import code.name.monkey.retromusic.misc.DialogAsyncTask
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import com.afollestad.materialdialogs.callbacks.onCancel
|
import com.afollestad.materialdialogs.callbacks.onCancel
|
||||||
|
@ -36,8 +25,7 @@ import kotlinx.android.synthetic.main.activity_bug_report.*
|
||||||
import kotlinx.android.synthetic.main.bug_report_card_device_info.*
|
import kotlinx.android.synthetic.main.bug_report_card_device_info.*
|
||||||
import kotlinx.android.synthetic.main.bug_report_card_report.*
|
import kotlinx.android.synthetic.main.bug_report_card_report.*
|
||||||
import org.eclipse.egit.github.core.Issue
|
import org.eclipse.egit.github.core.Issue
|
||||||
import org.eclipse.egit.github.core.client.GitHubClient
|
import org.eclipse.egit.github.core.client.*
|
||||||
import org.eclipse.egit.github.core.client.RequestException
|
|
||||||
import org.eclipse.egit.github.core.service.IssueService
|
import org.eclipse.egit.github.core.service.IssueService
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
|
@ -47,268 +35,285 @@ private const val RESULT_INVALID_TOKEN = "RESULT_INVALID_TOKEN"
|
||||||
private const val RESULT_ISSUES_NOT_ENABLED = "RESULT_ISSUES_NOT_ENABLED"
|
private const val RESULT_ISSUES_NOT_ENABLED = "RESULT_ISSUES_NOT_ENABLED"
|
||||||
private const val RESULT_UNKNOWN = "RESULT_UNKNOWN"
|
private const val RESULT_UNKNOWN = "RESULT_UNKNOWN"
|
||||||
|
|
||||||
@StringDef(RESULT_SUCCESS, RESULT_BAD_CREDENTIALS, RESULT_INVALID_TOKEN, RESULT_ISSUES_NOT_ENABLED, RESULT_UNKNOWN)
|
@StringDef(
|
||||||
|
RESULT_SUCCESS,
|
||||||
|
RESULT_BAD_CREDENTIALS,
|
||||||
|
RESULT_INVALID_TOKEN,
|
||||||
|
RESULT_ISSUES_NOT_ENABLED,
|
||||||
|
RESULT_UNKNOWN
|
||||||
|
)
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
private annotation class Result
|
private annotation class Result
|
||||||
|
|
||||||
open class BugReportActivity : AbsThemeActivity() {
|
open class BugReportActivity : AbsThemeActivity() {
|
||||||
|
|
||||||
private var deviceInfo: DeviceInfo? = null
|
private var deviceInfo: DeviceInfo? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_bug_report)
|
setContentView(R.layout.activity_bug_report)
|
||||||
|
|
||||||
setStatusbarColorAuto()
|
setStatusbarColorAuto()
|
||||||
setNavigationbarColorAuto()
|
setNavigationbarColorAuto()
|
||||||
setTaskDescriptionColorAuto()
|
setTaskDescriptionColorAuto()
|
||||||
|
|
||||||
initViews()
|
initViews()
|
||||||
|
|
||||||
if (TextUtils.isEmpty(title))
|
if (TextUtils.isEmpty(title)) setTitle(R.string.report_an_issue)
|
||||||
setTitle(R.string.report_an_issue)
|
|
||||||
|
|
||||||
deviceInfo = DeviceInfo(this)
|
deviceInfo = DeviceInfo(this)
|
||||||
airTextDeviceInfo.text = deviceInfo.toString()
|
airTextDeviceInfo.text = deviceInfo.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initViews() {
|
private fun initViews() {
|
||||||
val accentColor = ThemeStore.accentColor(this)
|
val accentColor = ThemeStore.accentColor(this)
|
||||||
val primaryColor = ATHUtil.resolveColor(this, R.attr.colorPrimary)
|
val primaryColor = ATHUtil.resolveColor(this, R.attr.colorPrimary)
|
||||||
toolbar.setBackgroundColor(primaryColor)
|
toolbar.setBackgroundColor(primaryColor)
|
||||||
setSupportActionBar(toolbar)
|
setSupportActionBar(toolbar)
|
||||||
ToolbarContentTintHelper.colorBackButton(toolbar)
|
ToolbarContentTintHelper.colorBackButton(toolbar)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
TintHelper.setTintAuto(optionUseAccount, accentColor, false)
|
TintHelper.setTintAuto(optionUseAccount, accentColor, false)
|
||||||
optionUseAccount?.setOnClickListener {
|
optionUseAccount?.setOnClickListener {
|
||||||
inputTitle.isEnabled = true
|
inputTitle.isEnabled = true
|
||||||
inputDescription.isEnabled = true
|
inputDescription.isEnabled = true
|
||||||
inputUsername.isEnabled = true
|
inputUsername.isEnabled = true
|
||||||
inputPassword.isEnabled = true
|
inputPassword.isEnabled = true
|
||||||
|
|
||||||
optionAnonymous.isChecked = false
|
optionAnonymous.isChecked = false
|
||||||
sendFab.hide(object : FloatingActionButton.OnVisibilityChangedListener() {
|
sendFab.hide(object : FloatingActionButton.OnVisibilityChangedListener() {
|
||||||
override fun onHidden(fab: FloatingActionButton?) {
|
override fun onHidden(fab: FloatingActionButton?) {
|
||||||
super.onHidden(fab)
|
super.onHidden(fab)
|
||||||
sendFab.setImageResource(R.drawable.ic_send_white_24dp)
|
sendFab.setImageResource(R.drawable.ic_send_white_24dp)
|
||||||
sendFab.show()
|
sendFab.show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
TintHelper.setTintAuto(optionAnonymous, accentColor, false)
|
TintHelper.setTintAuto(optionAnonymous, accentColor, false)
|
||||||
optionAnonymous.setOnClickListener {
|
optionAnonymous.setOnClickListener {
|
||||||
inputTitle.isEnabled = false
|
inputTitle.isEnabled = false
|
||||||
inputDescription.isEnabled = false
|
inputDescription.isEnabled = false
|
||||||
inputUsername.isEnabled = false
|
inputUsername.isEnabled = false
|
||||||
inputPassword.isEnabled = false
|
inputPassword.isEnabled = false
|
||||||
|
|
||||||
optionUseAccount.isChecked = false
|
optionUseAccount.isChecked = false
|
||||||
sendFab.hide(object : FloatingActionButton.OnVisibilityChangedListener() {
|
sendFab.hide(object : FloatingActionButton.OnVisibilityChangedListener() {
|
||||||
override fun onHidden(fab: FloatingActionButton?) {
|
override fun onHidden(fab: FloatingActionButton?) {
|
||||||
super.onHidden(fab)
|
super.onHidden(fab)
|
||||||
sendFab.setImageResource(R.drawable.ic_open_in_browser_white_24dp)
|
sendFab.setImageResource(R.drawable.ic_open_in_browser_white_24dp)
|
||||||
sendFab.show()
|
sendFab.show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
inputPassword.setOnEditorActionListener { _, actionId, _ ->
|
inputPassword.setOnEditorActionListener { _, actionId, _ ->
|
||||||
if (actionId == EditorInfo.IME_ACTION_SEND) {
|
if (actionId == EditorInfo.IME_ACTION_SEND) {
|
||||||
reportIssue()
|
reportIssue()
|
||||||
return@setOnEditorActionListener true
|
return@setOnEditorActionListener true
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
airTextDeviceInfo.setOnClickListener { copyDeviceInfoToClipBoard() }
|
airTextDeviceInfo.setOnClickListener { copyDeviceInfoToClipBoard() }
|
||||||
|
|
||||||
TintHelper.setTintAuto(sendFab, accentColor, true)
|
TintHelper.setTintAuto(sendFab, accentColor, true)
|
||||||
sendFab.setOnClickListener { reportIssue() }
|
sendFab.setOnClickListener { reportIssue() }
|
||||||
|
|
||||||
MaterialUtil.setTint(inputLayoutTitle, false)
|
MaterialUtil.setTint(inputLayoutTitle, false)
|
||||||
MaterialUtil.setTint(inputLayoutDescription, false)
|
MaterialUtil.setTint(inputLayoutDescription, false)
|
||||||
MaterialUtil.setTint(inputLayoutUsername, false)
|
MaterialUtil.setTint(inputLayoutUsername, false)
|
||||||
MaterialUtil.setTint(inputLayoutPassword, false)
|
MaterialUtil.setTint(inputLayoutPassword, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reportIssue() {
|
private fun reportIssue() {
|
||||||
if (optionUseAccount.isChecked) {
|
if (optionUseAccount.isChecked) {
|
||||||
if (!validateInput()) return
|
if (!validateInput()) return
|
||||||
val username = inputUsername.text.toString()
|
val username = inputUsername.text.toString()
|
||||||
val password = inputPassword.text.toString()
|
val password = inputPassword.text.toString()
|
||||||
sendBugReport(GithubLogin(username, password))
|
sendBugReport(GithubLogin(username, password))
|
||||||
} else {
|
} else {
|
||||||
copyDeviceInfoToClipBoard()
|
copyDeviceInfoToClipBoard()
|
||||||
|
|
||||||
val i = Intent(Intent.ACTION_VIEW)
|
val i = Intent(Intent.ACTION_VIEW)
|
||||||
i.data = Uri.parse(ISSUE_TRACKER_LINK)
|
i.data = Uri.parse(ISSUE_TRACKER_LINK)
|
||||||
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
startActivity(i)
|
startActivity(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun copyDeviceInfoToClipBoard() {
|
private fun copyDeviceInfoToClipBoard() {
|
||||||
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
val clip = ClipData.newPlainText(getString(R.string.device_info), deviceInfo?.toMarkdown())
|
val clip = ClipData.newPlainText(getString(R.string.device_info), deviceInfo?.toMarkdown())
|
||||||
clipboard.primaryClip = clip
|
clipboard.primaryClip = clip
|
||||||
Toast.makeText(this@BugReportActivity, R.string.copied_device_info_to_clipboard, Toast.LENGTH_LONG).show()
|
Toast.makeText(
|
||||||
}
|
this@BugReportActivity,
|
||||||
|
R.string.copied_device_info_to_clipboard,
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
|
||||||
private fun validateInput(): Boolean {
|
private fun validateInput(): Boolean {
|
||||||
var hasErrors = false
|
var hasErrors = false
|
||||||
|
|
||||||
if (optionUseAccount.isChecked) {
|
if (optionUseAccount.isChecked) {
|
||||||
if (TextUtils.isEmpty(inputUsername.text)) {
|
if (TextUtils.isEmpty(inputUsername.text)) {
|
||||||
setError(inputLayoutUsername, R.string.bug_report_no_username)
|
setError(inputLayoutUsername, R.string.bug_report_no_username)
|
||||||
hasErrors = true
|
hasErrors = true
|
||||||
} else {
|
} else {
|
||||||
removeError(inputLayoutUsername)
|
removeError(inputLayoutUsername)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TextUtils.isEmpty(inputPassword.text)) {
|
if (TextUtils.isEmpty(inputPassword.text)) {
|
||||||
setError(inputLayoutPassword, R.string.bug_report_no_password)
|
setError(inputLayoutPassword, R.string.bug_report_no_password)
|
||||||
hasErrors = true
|
hasErrors = true
|
||||||
} else {
|
} else {
|
||||||
removeError(inputLayoutPassword)
|
removeError(inputLayoutPassword)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TextUtils.isEmpty(inputTitle.text)) {
|
if (TextUtils.isEmpty(inputTitle.text)) {
|
||||||
setError(inputLayoutTitle, R.string.bug_report_no_title)
|
setError(inputLayoutTitle, R.string.bug_report_no_title)
|
||||||
hasErrors = true
|
hasErrors = true
|
||||||
} else {
|
} else {
|
||||||
removeError(inputLayoutTitle)
|
removeError(inputLayoutTitle)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TextUtils.isEmpty(inputDescription.text)) {
|
if (TextUtils.isEmpty(inputDescription.text)) {
|
||||||
setError(inputLayoutDescription, R.string.bug_report_no_description)
|
setError(inputLayoutDescription, R.string.bug_report_no_description)
|
||||||
hasErrors = true
|
hasErrors = true
|
||||||
} else {
|
} else {
|
||||||
removeError(inputLayoutDescription)
|
removeError(inputLayoutDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
return !hasErrors
|
return !hasErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setError(editTextLayout: TextInputLayout, @StringRes errorRes: Int) {
|
private fun setError(editTextLayout: TextInputLayout, @StringRes errorRes: Int) {
|
||||||
editTextLayout.error = getString(errorRes)
|
editTextLayout.error = getString(errorRes)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun removeError(editTextLayout: TextInputLayout) {
|
private fun removeError(editTextLayout: TextInputLayout) {
|
||||||
editTextLayout.error = null
|
editTextLayout.error = null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendBugReport(login: GithubLogin) {
|
private fun sendBugReport(login: GithubLogin) {
|
||||||
if (!validateInput()) return
|
if (!validateInput()) return
|
||||||
|
|
||||||
val bugTitle = inputTitle.text.toString()
|
val bugTitle = inputTitle.text.toString()
|
||||||
val bugDescription = inputDescription.text.toString()
|
val bugDescription = inputDescription.text.toString()
|
||||||
|
|
||||||
val extraInfo = ExtraInfo()
|
val extraInfo = ExtraInfo()
|
||||||
onSaveExtraInfo()
|
onSaveExtraInfo()
|
||||||
|
|
||||||
val report = Report(bugTitle, bugDescription, deviceInfo, extraInfo)
|
val report = Report(bugTitle, bugDescription, deviceInfo, extraInfo)
|
||||||
val target = GithubTarget("h4h13", "RetroMusicPlayer")
|
val target = GithubTarget("h4h13", "RetroMusicPlayer")
|
||||||
|
|
||||||
ReportIssueAsyncTask.report(this, report, target, login)
|
ReportIssueAsyncTask.report(this, report, target, login)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onSaveExtraInfo() {}
|
private fun onSaveExtraInfo() {}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
if (item.itemId == android.R.id.home) {
|
if (item.itemId == android.R.id.home) {
|
||||||
onBackPressed()
|
onBackPressed()
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item)
|
return super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ReportIssueAsyncTask private constructor(activity: Activity, private val report: Report, private val target: GithubTarget,
|
private class ReportIssueAsyncTask private constructor(
|
||||||
private val login: GithubLogin) : DialogAsyncTask<Void, Void, String>(activity) {
|
activity: Activity,
|
||||||
override fun createDialog(context: Context): Dialog {
|
private val report: Report,
|
||||||
return AlertDialog.Builder(context)
|
private val target: GithubTarget,
|
||||||
.show()
|
private val login: GithubLogin
|
||||||
}
|
) : DialogAsyncTask<Void, Void, String>(activity) {
|
||||||
|
override fun createDialog(context: Context): Dialog {
|
||||||
|
return AlertDialog.Builder(context).show()
|
||||||
|
}
|
||||||
|
|
||||||
@Result
|
@Result
|
||||||
override fun doInBackground(vararg params: Void): String {
|
override fun doInBackground(vararg params: Void): String {
|
||||||
val client: GitHubClient = if (login.shouldUseApiToken()) {
|
val client: GitHubClient = if (login.shouldUseApiToken()) {
|
||||||
GitHubClient().setOAuth2Token(login.apiToken)
|
GitHubClient().setOAuth2Token(login.apiToken)
|
||||||
} else {
|
} else {
|
||||||
GitHubClient().setCredentials(login.username, login.password)
|
GitHubClient().setCredentials(login.username, login.password)
|
||||||
}
|
}
|
||||||
|
|
||||||
val issue = Issue().setTitle(report.title).setBody(report.description)
|
val issue = Issue().setTitle(report.title).setBody(report.description)
|
||||||
try {
|
try {
|
||||||
IssueService(client).createIssue(target.username, target.repository, issue)
|
IssueService(client).createIssue(target.username, target.repository, issue)
|
||||||
return RESULT_SUCCESS
|
return RESULT_SUCCESS
|
||||||
} catch (e: RequestException) {
|
} catch (e: RequestException) {
|
||||||
return when (e.status) {
|
return when (e.status) {
|
||||||
STATUS_BAD_CREDENTIALS -> {
|
STATUS_BAD_CREDENTIALS -> {
|
||||||
if (login.shouldUseApiToken()) RESULT_INVALID_TOKEN else RESULT_BAD_CREDENTIALS
|
if (login.shouldUseApiToken()) RESULT_INVALID_TOKEN else RESULT_BAD_CREDENTIALS
|
||||||
}
|
}
|
||||||
STATUS_ISSUES_NOT_ENABLED -> RESULT_ISSUES_NOT_ENABLED
|
STATUS_ISSUES_NOT_ENABLED -> RESULT_ISSUES_NOT_ENABLED
|
||||||
else -> {
|
else -> {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
RESULT_UNKNOWN
|
RESULT_UNKNOWN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
return RESULT_UNKNOWN
|
return RESULT_UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPostExecute(@Result result: String) {
|
override fun onPostExecute(@Result result: String) {
|
||||||
super.onPostExecute(result)
|
super.onPostExecute(result)
|
||||||
|
|
||||||
val context = context ?: return
|
val context = context ?: return
|
||||||
|
|
||||||
when (result) {
|
when (result) {
|
||||||
RESULT_SUCCESS -> tryToFinishActivity()
|
RESULT_SUCCESS -> tryToFinishActivity()
|
||||||
RESULT_BAD_CREDENTIALS -> MaterialDialog(context).show {
|
RESULT_BAD_CREDENTIALS -> MaterialDialog(context).show {
|
||||||
title(R.string.bug_report_failed)
|
title(R.string.bug_report_failed)
|
||||||
message(R.string.bug_report_failed_wrong_credentials)
|
message(R.string.bug_report_failed_wrong_credentials)
|
||||||
positiveButton(android.R.string.ok)
|
positiveButton(android.R.string.ok)
|
||||||
}
|
}
|
||||||
RESULT_INVALID_TOKEN -> MaterialDialog(context).show {
|
RESULT_INVALID_TOKEN -> MaterialDialog(context).show {
|
||||||
title(R.string.bug_report_failed)
|
title(R.string.bug_report_failed)
|
||||||
message(R.string.bug_report_failed_invalid_token)
|
message(R.string.bug_report_failed_invalid_token)
|
||||||
positiveButton(android.R.string.ok)
|
positiveButton(android.R.string.ok)
|
||||||
}
|
}
|
||||||
RESULT_ISSUES_NOT_ENABLED -> MaterialDialog(context).show {
|
RESULT_ISSUES_NOT_ENABLED -> MaterialDialog(context).show {
|
||||||
title(R.string.bug_report_failed)
|
title(R.string.bug_report_failed)
|
||||||
message(R.string.bug_report_failed_issues_not_available)
|
message(R.string.bug_report_failed_issues_not_available)
|
||||||
positiveButton(android.R.string.ok)
|
positiveButton(android.R.string.ok)
|
||||||
}
|
}
|
||||||
else -> MaterialDialog(context).show {
|
else -> MaterialDialog(context).show {
|
||||||
title(R.string.bug_report_failed)
|
title(R.string.bug_report_failed)
|
||||||
message(R.string.bug_report_failed_unknown)
|
message(R.string.bug_report_failed_unknown)
|
||||||
positiveButton(android.R.string.ok) { tryToFinishActivity() }
|
positiveButton(android.R.string.ok) { tryToFinishActivity() }
|
||||||
onCancel { tryToFinishActivity() }
|
onCancel { tryToFinishActivity() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryToFinishActivity() {
|
private fun tryToFinishActivity() {
|
||||||
val context = context
|
val context = context
|
||||||
if (context is Activity && !context.isFinishing) {
|
if (context is Activity && !context.isFinishing) {
|
||||||
context.finish()
|
context.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun report(activity: Activity, report: Report, target: GithubTarget, login: GithubLogin) {
|
fun report(
|
||||||
ReportIssueAsyncTask(activity, report, target, login).execute()
|
activity: Activity,
|
||||||
}
|
report: Report,
|
||||||
}
|
target: GithubTarget,
|
||||||
}
|
login: GithubLogin
|
||||||
|
) {
|
||||||
|
ReportIssueAsyncTask(activity, report, target, login).execute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private const val STATUS_BAD_CREDENTIALS = 401
|
private const val STATUS_BAD_CREDENTIALS = 401
|
||||||
private const val STATUS_ISSUES_NOT_ENABLED = 410
|
private const val STATUS_ISSUES_NOT_ENABLED = 410
|
||||||
private const val ISSUE_TRACKER_LINK = "https://github.com/h4h13/RetroMusicPlayer"
|
private const val ISSUE_TRACKER_LINK = "https://github.com/h4h13/RetroMusicPlayer"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
package code.name.monkey.retromusic.activities.bugreport
import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.bugreport.model.DeviceInfo
import kotlinx.android.synthetic.main.activity_error_handler.*
class ErrorHandlerActivity : AppCompatActivity() {
private var deviceInfo: DeviceInfo? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_error_handler)
deviceInfo = DeviceInfo(this)
clearAppData.setOnClickListener {
try {
val intent = Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data = Uri.parse("package:$packageName")
startActivity(intent)
} catch (e: ActivityNotFoundException) {
val intent = Intent(android.provider.Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS)
startActivity(intent)
}
}
sendCrashLog.setOnClickListener {
val sendIntent = Intent(Intent.ACTION_SEND)
val subject = "Error report"
val body = intent.getStringExtra("error") + "\n" + deviceInfo!!.toString()
sendIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf("monkeycodeapp@gmail.com"))
sendIntent.putExtra(Intent.EXTRA_TEXT, body)
sendIntent.putExtra(Intent.EXTRA_SUBJECT, subject)
sendIntent.type = "message/rfc822"
startActivity(Intent.createChooser(sendIntent, "Send crash log"))
deleteFile("stack.trace")
}
showCrashError.text = String.format("%s", intent.getStringExtra("error"))
showCrashError.append(deviceInfo!!.toString())
}
}
|
|
|
@ -6,9 +6,10 @@ import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
|
import androidx.annotation.IntRange;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import androidx.annotation.IntRange;
|
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||||
|
|
||||||
public class DeviceInfo {
|
public class DeviceInfo {
|
||||||
|
|
|
@ -1,405 +1,416 @@
|
||||||
package code.name.monkey.retromusic.activities.tageditor
|
package code.name.monkey.retromusic.activities.tageditor
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.*
|
||||||
import android.app.SearchManager
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.Bitmap
|
import android.graphics.*
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.*
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.MenuItem
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import android.view.animation.OvershootInterpolator
|
import android.view.animation.OvershootInterpolator
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
|
||||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
|
||||||
import code.name.monkey.appthemehelper.util.TintHelper
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
||||||
import code.name.monkey.retromusic.activities.saf.SAFGuideActivity
|
import code.name.monkey.retromusic.activities.saf.SAFGuideActivity
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.RetroUtil
|
import com.afollestad.materialdialogs.*
|
||||||
import code.name.monkey.retromusic.util.SAFUtil
|
|
||||||
import com.afollestad.materialdialogs.LayoutMode
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
|
||||||
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
||||||
import com.afollestad.materialdialogs.list.listItems
|
import com.afollestad.materialdialogs.list.listItems
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import kotlinx.android.synthetic.main.activity_album_tag_editor.*
|
import kotlinx.android.synthetic.main.activity_album_tag_editor.*
|
||||||
import org.jaudiotagger.audio.AudioFile
|
import org.jaudiotagger.audio.*
|
||||||
import org.jaudiotagger.audio.AudioFileIO
|
|
||||||
import org.jaudiotagger.tag.FieldKey
|
import org.jaudiotagger.tag.FieldKey
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
|
|
||||||
|
protected var id: Int = 0
|
||||||
|
private set
|
||||||
|
private var paletteColorPrimary: Int = 0
|
||||||
|
private var isInNoImageMode: Boolean = false
|
||||||
|
private var songPaths: List<String>? = null
|
||||||
|
lateinit var saveFab: MaterialButton
|
||||||
|
|
||||||
protected var id: Int = 0
|
private var savedSongPaths: List<String>? = null
|
||||||
private set
|
private val currentSongPath: String? = null
|
||||||
private var paletteColorPrimary: Int = 0
|
private var savedTags: Map<FieldKey, String>? = null
|
||||||
private var isInNoImageMode: Boolean = false
|
private var savedArtworkInfo: ArtworkInfo? = null
|
||||||
private var songPaths: List<String>? = null
|
|
||||||
lateinit var saveFab: MaterialButton
|
|
||||||
|
|
||||||
private var savedSongPaths: List<String>? = null
|
protected val show: MaterialDialog
|
||||||
private val currentSongPath: String? = null
|
get() = MaterialDialog(this, BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
||||||
private var savedTags: Map<FieldKey, String>? = null
|
cornerRadius(PreferenceUtil.getInstance(this@AbsTagEditorActivity).dialogCorner)
|
||||||
private var savedArtworkInfo: ArtworkInfo? = null
|
title(R.string.update_image)
|
||||||
|
listItems(items = items) { _, position, _ ->
|
||||||
|
when (position) {
|
||||||
|
0 -> startImagePicker()
|
||||||
|
1 -> searchImageOnWeb()
|
||||||
|
2 -> deleteImage()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected abstract val contentViewLayout: Int
|
||||||
|
|
||||||
protected val show: MaterialDialog
|
internal val albumArtist: String?
|
||||||
get() = MaterialDialog(this, BottomSheet(LayoutMode.WRAP_CONTENT))
|
get() {
|
||||||
.show {
|
return try {
|
||||||
cornerRadius(PreferenceUtil.getInstance(this@AbsTagEditorActivity).dialogCorner)
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ALBUM_ARTIST)
|
||||||
title(R.string.update_image)
|
} catch (ignored: Exception) {
|
||||||
listItems(items = items) { _, position, _ ->
|
null
|
||||||
when (position) {
|
}
|
||||||
0 -> startImagePicker()
|
|
||||||
1 -> searchImageOnWeb()
|
|
||||||
2 -> deleteImage()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
protected abstract val contentViewLayout: Int
|
|
||||||
|
|
||||||
internal val albumArtist: String?
|
}
|
||||||
get() {
|
|
||||||
return try {
|
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault
|
|
||||||
.getFirst(FieldKey.ALBUM_ARTIST)
|
|
||||||
} catch (ignored: Exception) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
protected val songTitle: String?
|
||||||
|
get() {
|
||||||
|
return try {
|
||||||
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.TITLE)
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
protected val songTitle: String?
|
}
|
||||||
get() {
|
protected val composer: String?
|
||||||
return try {
|
get() {
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.TITLE)
|
return try {
|
||||||
} catch (ignored: Exception) {
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.COMPOSER)
|
||||||
null
|
} catch (ignored: Exception) {
|
||||||
}
|
null
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
protected val composer: String?
|
|
||||||
get() {
|
|
||||||
return try {
|
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.COMPOSER)
|
|
||||||
} catch (ignored: Exception) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
protected val albumTitle: String?
|
||||||
|
get() {
|
||||||
|
return try {
|
||||||
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ALBUM)
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
protected val albumTitle: String?
|
}
|
||||||
get() {
|
|
||||||
return try {
|
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ALBUM)
|
|
||||||
} catch (ignored: Exception) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
protected val artistName: String?
|
||||||
|
get() {
|
||||||
|
return try {
|
||||||
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ARTIST)
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
protected val artistName: String?
|
}
|
||||||
get() {
|
|
||||||
return try {
|
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ARTIST)
|
|
||||||
} catch (ignored: Exception) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
protected val albumArtistName: String?
|
||||||
|
get() {
|
||||||
|
return try {
|
||||||
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ALBUM_ARTIST)
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
protected val albumArtistName: String?
|
}
|
||||||
get() {
|
|
||||||
return try {
|
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault
|
|
||||||
.getFirst(FieldKey.ALBUM_ARTIST)
|
|
||||||
} catch (ignored: Exception) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
protected val genreName: String?
|
||||||
|
get() {
|
||||||
|
return try {
|
||||||
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.GENRE)
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
protected val genreName: String?
|
}
|
||||||
get() {
|
|
||||||
return try {
|
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.GENRE)
|
|
||||||
} catch (ignored: Exception) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
protected val songYear: String?
|
||||||
|
get() {
|
||||||
|
return try {
|
||||||
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.YEAR)
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
protected val songYear: String?
|
}
|
||||||
get() {
|
|
||||||
return try {
|
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.YEAR)
|
|
||||||
} catch (ignored: Exception) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
protected val trackNumber: String?
|
||||||
|
get() {
|
||||||
|
return try {
|
||||||
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.TRACK)
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
protected val trackNumber: String?
|
}
|
||||||
get() {
|
|
||||||
return try {
|
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.TRACK)
|
|
||||||
} catch (ignored: Exception) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
protected val lyrics: String?
|
||||||
|
get() {
|
||||||
|
return try {
|
||||||
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.LYRICS)
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
protected val lyrics: String?
|
}
|
||||||
get() {
|
|
||||||
return try {
|
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.LYRICS)
|
|
||||||
} catch (ignored: Exception) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
protected val albumArt: Bitmap?
|
||||||
|
get() {
|
||||||
|
try {
|
||||||
|
val artworkTag = getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.firstArtwork
|
||||||
|
if (artworkTag != null) {
|
||||||
|
val artworkBinaryData = artworkTag.binaryData
|
||||||
|
return BitmapFactory.decodeByteArray(
|
||||||
|
artworkBinaryData,
|
||||||
|
0,
|
||||||
|
artworkBinaryData.size
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(contentViewLayout)
|
||||||
|
|
||||||
|
saveFab = findViewById(R.id.saveTags)
|
||||||
|
getIntentExtras()
|
||||||
|
|
||||||
|
songPaths = getSongPaths()
|
||||||
|
if (songPaths!!.isEmpty()) {
|
||||||
|
finish()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setUpViews()
|
||||||
|
|
||||||
|
|
||||||
protected val albumArt: Bitmap?
|
setNavigationbarColorAuto()
|
||||||
get() {
|
setTaskDescriptionColorAuto()
|
||||||
try {
|
}
|
||||||
val artworkTag = getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault
|
|
||||||
.firstArtwork
|
|
||||||
if (artworkTag != null) {
|
|
||||||
val artworkBinaryData = artworkTag.binaryData
|
|
||||||
return BitmapFactory.decodeByteArray(artworkBinaryData, 0, artworkBinaryData.size)
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
} catch (ignored: Exception) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
private fun setUpViews() {
|
||||||
|
setUpScrollView()
|
||||||
|
setUpFab()
|
||||||
|
setUpImageView()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
private fun setUpScrollView() {
|
||||||
super.onCreate(savedInstanceState)
|
//observableScrollView.setScrollViewCallbacks(observableScrollViewCallbacks);
|
||||||
setContentView(contentViewLayout)
|
}
|
||||||
|
|
||||||
saveFab = findViewById(R.id.saveTags)
|
private lateinit var items: List<String>
|
||||||
getIntentExtras()
|
|
||||||
|
|
||||||
songPaths = getSongPaths()
|
private fun setUpImageView() {
|
||||||
if (songPaths!!.isEmpty()) {
|
loadCurrentImage()
|
||||||
finish()
|
items = listOf(
|
||||||
return
|
getString(code.name.monkey.retromusic.R.string.pick_from_local_storage),
|
||||||
}
|
getString(code.name.monkey.retromusic.R.string.web_search),
|
||||||
|
getString(code.name.monkey.retromusic.R.string.remove_cover)
|
||||||
|
)
|
||||||
|
editorImage?.setOnClickListener { show }
|
||||||
|
}
|
||||||
|
|
||||||
setUpViews()
|
private fun startImagePicker() {
|
||||||
|
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||||
|
intent.type = "image/*"
|
||||||
|
startActivityForResult(
|
||||||
|
Intent.createChooser(
|
||||||
|
intent,
|
||||||
|
getString(code.name.monkey.retromusic.R.string.pick_from_local_storage)
|
||||||
|
), REQUEST_CODE_SELECT_IMAGE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun loadCurrentImage()
|
||||||
|
|
||||||
setNavigationbarColorAuto()
|
protected abstract fun searchImageOnWeb()
|
||||||
setTaskDescriptionColorAuto()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setUpViews() {
|
protected abstract fun deleteImage()
|
||||||
setUpScrollView()
|
|
||||||
setUpFab()
|
|
||||||
setUpImageView()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setUpScrollView() {
|
private fun setUpFab() {
|
||||||
//observableScrollView.setScrollViewCallbacks(observableScrollViewCallbacks);
|
saveFab.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
|
||||||
}
|
ColorStateList.valueOf(
|
||||||
|
MaterialValueHelper.getPrimaryTextColor(
|
||||||
|
this,
|
||||||
|
ColorUtil.isColorLight(
|
||||||
|
ThemeStore.accentColor(
|
||||||
|
this
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).apply {
|
||||||
|
saveFab.setTextColor(this)
|
||||||
|
saveFab.iconTint = this
|
||||||
|
}
|
||||||
|
saveFab.apply {
|
||||||
|
scaleX = 0f
|
||||||
|
scaleY = 0f
|
||||||
|
isEnabled = false
|
||||||
|
setOnClickListener { save() }
|
||||||
|
TintHelper.setTintAuto(this, ThemeStore.accentColor(this@AbsTagEditorActivity), true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private lateinit var items: List<String>
|
protected abstract fun save()
|
||||||
|
|
||||||
private fun setUpImageView() {
|
private fun getIntentExtras() {
|
||||||
loadCurrentImage()
|
val intentExtras = intent.extras
|
||||||
items = listOf(getString(code.name.monkey.retromusic.R.string.pick_from_local_storage), getString(code.name.monkey.retromusic.R.string.web_search), getString(code.name.monkey.retromusic.R.string.remove_cover))
|
if (intentExtras != null) {
|
||||||
editorImage?.setOnClickListener { show }
|
id = intentExtras.getInt(EXTRA_ID)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun startImagePicker() {
|
protected abstract fun getSongPaths(): List<String>
|
||||||
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
|
||||||
intent.type = "image/*"
|
|
||||||
startActivityForResult(Intent.createChooser(intent, getString(code.name.monkey.retromusic.R.string.pick_from_local_storage)), REQUEST_CODE_SELECT_IMAGE)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun loadCurrentImage()
|
protected fun searchWebFor(vararg keys: String) {
|
||||||
|
val stringBuilder = StringBuilder()
|
||||||
|
for (key in keys) {
|
||||||
|
stringBuilder.append(key)
|
||||||
|
stringBuilder.append(" ")
|
||||||
|
}
|
||||||
|
val intent = Intent(Intent.ACTION_WEB_SEARCH)
|
||||||
|
intent.putExtra(SearchManager.QUERY, stringBuilder.toString())
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
|
||||||
protected abstract fun searchImageOnWeb()
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract fun deleteImage()
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
when (item.itemId) {
|
||||||
|
android.R.id.home -> {
|
||||||
|
super.onBackPressed()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
|
||||||
private fun setUpFab() {
|
protected fun setNoImageMode() {
|
||||||
saveFab.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
|
isInNoImageMode = true
|
||||||
ColorStateList.valueOf(MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(ThemeStore.accentColor(this)))).apply {
|
imageContainer?.visibility = View.GONE
|
||||||
saveFab.setTextColor(this)
|
editorImage?.visibility = View.GONE
|
||||||
saveFab.iconTint = this
|
editorImage?.isEnabled = false
|
||||||
}
|
|
||||||
saveFab.apply {
|
|
||||||
scaleX = 0f
|
|
||||||
scaleY = 0f
|
|
||||||
isEnabled = false
|
|
||||||
setOnClickListener { save() }
|
|
||||||
TintHelper.setTintAuto(this, ThemeStore.accentColor(this@AbsTagEditorActivity), true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun save()
|
setColors(
|
||||||
|
intent.getIntExtra(
|
||||||
|
EXTRA_PALETTE,
|
||||||
|
ATHUtil.resolveColor(this, R.attr.colorPrimary)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun getIntentExtras() {
|
protected fun dataChanged() {
|
||||||
val intentExtras = intent.extras
|
showFab()
|
||||||
if (intentExtras != null) {
|
}
|
||||||
id = intentExtras.getInt(EXTRA_ID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun getSongPaths(): List<String>
|
private fun showFab() {
|
||||||
|
saveFab.animate().setDuration(500).setInterpolator(OvershootInterpolator()).scaleX(1f)
|
||||||
|
.scaleY(1f).start()
|
||||||
|
saveFab.isEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
protected fun searchWebFor(vararg keys: String) {
|
private fun hideFab() {
|
||||||
val stringBuilder = StringBuilder()
|
saveFab.animate().setDuration(500).setInterpolator(OvershootInterpolator()).scaleX(0.0f)
|
||||||
for (key in keys) {
|
.scaleY(0.0f).start()
|
||||||
stringBuilder.append(key)
|
saveFab.isEnabled = false
|
||||||
stringBuilder.append(" ")
|
}
|
||||||
}
|
|
||||||
val intent = Intent(Intent.ACTION_WEB_SEARCH)
|
|
||||||
intent.putExtra(SearchManager.QUERY, stringBuilder.toString())
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
|
|
||||||
startActivity(intent)
|
protected fun setImageBitmap(bitmap: Bitmap?, bgColor: Int) {
|
||||||
}
|
if (bitmap == null) {
|
||||||
|
editorImage.setImageResource(code.name.monkey.retromusic.R.drawable.default_album_art)
|
||||||
|
} else {
|
||||||
|
editorImage.setImageBitmap(bitmap)
|
||||||
|
}
|
||||||
|
setColors(bgColor)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
protected open fun setColors(color: Int) {
|
||||||
when (item.itemId) {
|
paletteColorPrimary = color
|
||||||
android.R.id.home -> {
|
}
|
||||||
super.onBackPressed()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun setNoImageMode() {
|
protected fun writeValuesToFiles(
|
||||||
isInNoImageMode = true
|
fieldKeyValueMap: Map<FieldKey, String>, artworkInfo: ArtworkInfo?
|
||||||
imageContainer?.visibility = View.GONE
|
) {
|
||||||
editorImage?.visibility = View.GONE
|
RetroUtil.hideSoftKeyboard(this)
|
||||||
editorImage?.isEnabled = false
|
|
||||||
|
|
||||||
setColors(intent.getIntExtra(EXTRA_PALETTE, ATHUtil.resolveColor(this, R.attr.colorPrimary)))
|
hideFab()
|
||||||
}
|
|
||||||
|
|
||||||
protected fun dataChanged() {
|
savedSongPaths = getSongPaths()
|
||||||
showFab()
|
savedTags = fieldKeyValueMap
|
||||||
}
|
savedArtworkInfo = artworkInfo
|
||||||
|
|
||||||
private fun showFab() {
|
if (!SAFUtil.isSAFRequired(savedSongPaths)) {
|
||||||
saveFab.animate()
|
writeTags(savedSongPaths)
|
||||||
.setDuration(500)
|
} else {
|
||||||
.setInterpolator(OvershootInterpolator())
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
.scaleX(1f)
|
if (SAFUtil.isSDCardAccessGranted(this)) {
|
||||||
.scaleY(1f)
|
writeTags(savedSongPaths)
|
||||||
.start()
|
} else {
|
||||||
saveFab.isEnabled = true
|
startActivityForResult(
|
||||||
}
|
Intent(this, SAFGuideActivity::class.java),
|
||||||
|
SAFGuideActivity.REQUEST_CODE_SAF_GUIDE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun hideFab() {
|
private fun writeTags(paths: List<String>?) {
|
||||||
saveFab.animate()
|
WriteTagsAsyncTask(this).execute(
|
||||||
.setDuration(500)
|
WriteTagsAsyncTask.LoadingInfo(
|
||||||
.setInterpolator(OvershootInterpolator())
|
paths,
|
||||||
.scaleX(0.0f)
|
savedTags,
|
||||||
.scaleY(0.0f)
|
savedArtworkInfo
|
||||||
.start()
|
)
|
||||||
saveFab.isEnabled = false
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun setImageBitmap(bitmap: Bitmap?, bgColor: Int) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
|
||||||
if (bitmap == null) {
|
super.onActivityResult(requestCode, resultCode, intent)
|
||||||
editorImage.setImageResource(code.name.monkey.retromusic.R.drawable.default_album_art)
|
when (requestCode) {
|
||||||
} else {
|
REQUEST_CODE_SELECT_IMAGE -> if (resultCode == Activity.RESULT_OK) {
|
||||||
editorImage.setImageBitmap(bitmap)
|
intent?.data?.let {
|
||||||
}
|
loadImageFromFile(it)
|
||||||
setColors(bgColor)
|
}
|
||||||
}
|
}
|
||||||
|
SAFGuideActivity.REQUEST_CODE_SAF_GUIDE -> {
|
||||||
|
SAFUtil.openTreePicker(this)
|
||||||
|
}
|
||||||
|
SAFUtil.REQUEST_SAF_PICK_TREE -> {
|
||||||
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
|
SAFUtil.saveTreeUri(this, intent)
|
||||||
|
writeTags(savedSongPaths)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SAFUtil.REQUEST_SAF_PICK_FILE -> {
|
||||||
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
|
writeTags(Collections.singletonList(currentSongPath + SAFUtil.SEPARATOR + intent!!.dataString))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected open fun setColors(color: Int) {
|
protected abstract fun loadImageFromFile(selectedFile: Uri?)
|
||||||
paletteColorPrimary = color
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun writeValuesToFiles(fieldKeyValueMap: Map<FieldKey, String>,
|
private fun getAudioFile(path: String): AudioFile {
|
||||||
artworkInfo: ArtworkInfo?) {
|
return try {
|
||||||
RetroUtil.hideSoftKeyboard(this)
|
AudioFileIO.read(File(path))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Could not read audio file $path", e)
|
||||||
|
AudioFile()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hideFab()
|
class ArtworkInfo constructor(val albumId: Int, val artwork: Bitmap?)
|
||||||
|
|
||||||
savedSongPaths = getSongPaths()
|
companion object {
|
||||||
savedTags = fieldKeyValueMap
|
|
||||||
savedArtworkInfo = artworkInfo
|
|
||||||
|
|
||||||
if (!SAFUtil.isSAFRequired(savedSongPaths)) {
|
const val EXTRA_ID = "extra_id"
|
||||||
writeTags(savedSongPaths)
|
const val EXTRA_PALETTE = "extra_palette"
|
||||||
} else {
|
private val TAG = AbsTagEditorActivity::class.java.simpleName
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
private const val REQUEST_CODE_SELECT_IMAGE = 1000
|
||||||
if (SAFUtil.isSDCardAccessGranted(this)) {
|
}
|
||||||
writeTags(savedSongPaths)
|
|
||||||
} else {
|
|
||||||
startActivityForResult(Intent(this, SAFGuideActivity::class.java), SAFGuideActivity.REQUEST_CODE_SAF_GUIDE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun writeTags(paths: List<String>?) {
|
|
||||||
WriteTagsAsyncTask(this).execute(WriteTagsAsyncTask.LoadingInfo(paths, savedTags, savedArtworkInfo))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, intent)
|
|
||||||
when (requestCode) {
|
|
||||||
REQUEST_CODE_SELECT_IMAGE -> if (resultCode == Activity.RESULT_OK) {
|
|
||||||
intent?.data?.let {
|
|
||||||
loadImageFromFile(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SAFGuideActivity.REQUEST_CODE_SAF_GUIDE -> {
|
|
||||||
SAFUtil.openTreePicker(this)
|
|
||||||
}
|
|
||||||
SAFUtil.REQUEST_SAF_PICK_TREE -> {
|
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
|
||||||
SAFUtil.saveTreeUri(this, intent)
|
|
||||||
writeTags(savedSongPaths)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SAFUtil.REQUEST_SAF_PICK_FILE -> {
|
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
|
||||||
writeTags(Collections.singletonList(currentSongPath + SAFUtil.SEPARATOR + intent!!.dataString))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun loadImageFromFile(selectedFile: Uri?)
|
|
||||||
|
|
||||||
private fun getAudioFile(path: String): AudioFile {
|
|
||||||
return try {
|
|
||||||
AudioFileIO.read(File(path))
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e(TAG, "Could not read audio file $path", e)
|
|
||||||
AudioFile()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ArtworkInfo constructor(val albumId: Int, val artwork: Bitmap?)
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
const val EXTRA_ID = "extra_id"
|
|
||||||
const val EXTRA_PALETTE = "extra_palette"
|
|
||||||
private val TAG = AbsTagEditorActivity::class.java.simpleName
|
|
||||||
private const val REQUEST_CODE_SELECT_IMAGE = 1000
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,27 +2,20 @@ package code.name.monkey.retromusic.activities.tageditor
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.Bitmap
|
import android.graphics.*
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Editable
|
import android.text.*
|
||||||
import android.text.TextUtils
|
|
||||||
import android.text.TextWatcher
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.extensions.appHandleColor
|
import code.name.monkey.retromusic.extensions.appHandleColor
|
||||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
|
import code.name.monkey.retromusic.glide.palette.*
|
||||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
|
||||||
import code.name.monkey.retromusic.loaders.AlbumLoader
|
import code.name.monkey.retromusic.loaders.AlbumLoader
|
||||||
import code.name.monkey.retromusic.rest.LastFMRestClient
|
import code.name.monkey.retromusic.rest.LastFMRestClient
|
||||||
import code.name.monkey.retromusic.rest.model.LastFmAlbum
|
import code.name.monkey.retromusic.rest.model.LastFmAlbum
|
||||||
import code.name.monkey.retromusic.util.ImageUtil
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.LastFMUtil
|
|
||||||
import code.name.monkey.retromusic.util.RetroColorUtil.generatePalette
|
import code.name.monkey.retromusic.util.RetroColorUtil.generatePalette
|
||||||
import code.name.monkey.retromusic.util.RetroColorUtil.getColor
|
import code.name.monkey.retromusic.util.RetroColorUtil.getColor
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
|
@ -34,181 +27,224 @@ import kotlinx.android.synthetic.main.activity_album_tag_editor.*
|
||||||
import org.jaudiotagger.tag.FieldKey
|
import org.jaudiotagger.tag.FieldKey
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
override val contentViewLayout: Int
|
override val contentViewLayout: Int
|
||||||
get() = R.layout.activity_album_tag_editor
|
get() = R.layout.activity_album_tag_editor
|
||||||
|
|
||||||
override fun loadImageFromFile(selectedFileUri: Uri?) {
|
override fun loadImageFromFile(selectedFileUri: Uri?) {
|
||||||
|
|
||||||
Glide.with(this@AlbumTagEditorActivity)
|
Glide.with(this@AlbumTagEditorActivity).load(selectedFileUri).asBitmap()
|
||||||
.load(selectedFileUri)
|
.transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java)
|
||||||
.asBitmap()
|
.diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true)
|
||||||
.transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java)
|
.into(object : SimpleTarget<BitmapPaletteWrapper>() {
|
||||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
override fun onResourceReady(
|
||||||
.skipMemoryCache(true)
|
resource: BitmapPaletteWrapper?,
|
||||||
.into(object : SimpleTarget<BitmapPaletteWrapper>() {
|
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?
|
||||||
override fun onResourceReady(resource: BitmapPaletteWrapper?, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
|
) {
|
||||||
getColor(resource?.palette, Color.TRANSPARENT)
|
getColor(resource?.palette, Color.TRANSPARENT)
|
||||||
albumArtBitmap = resource?.bitmap?.let { ImageUtil.resizeBitmap(it, 2048) }
|
albumArtBitmap = resource?.bitmap?.let { ImageUtil.resizeBitmap(it, 2048) }
|
||||||
setImageBitmap(albumArtBitmap, getColor(resource?.palette, ATHUtil.resolveColor(this@AlbumTagEditorActivity, R.attr.defaultFooterColor)))
|
setImageBitmap(
|
||||||
deleteAlbumArt = false
|
albumArtBitmap,
|
||||||
dataChanged()
|
getColor(
|
||||||
setResult(Activity.RESULT_OK)
|
resource?.palette,
|
||||||
}
|
ATHUtil.resolveColor(
|
||||||
|
this@AlbumTagEditorActivity,
|
||||||
|
R.attr.defaultFooterColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
deleteAlbumArt = false
|
||||||
|
dataChanged()
|
||||||
|
setResult(Activity.RESULT_OK)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
|
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
|
||||||
super.onLoadFailed(e, errorDrawable)
|
super.onLoadFailed(e, errorDrawable)
|
||||||
Toast.makeText(this@AlbumTagEditorActivity, e.toString(), Toast.LENGTH_LONG).show()
|
Toast.makeText(this@AlbumTagEditorActivity, e.toString(), Toast.LENGTH_LONG)
|
||||||
}
|
.show()
|
||||||
})
|
}
|
||||||
}
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private var albumArtBitmap: Bitmap? = null
|
private var albumArtBitmap: Bitmap? = null
|
||||||
private var deleteAlbumArt: Boolean = false
|
private var deleteAlbumArt: Boolean = false
|
||||||
private var lastFMRestClient: LastFMRestClient? = null
|
private var lastFMRestClient: LastFMRestClient? = null
|
||||||
private val disposable = CompositeDisposable()
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
private fun setupToolbar() {
|
private fun setupToolbar() {
|
||||||
toolbar.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
toolbar.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
||||||
setSupportActionBar(toolbar)
|
setSupportActionBar(toolbar)
|
||||||
supportActionBar?.setDisplayShowHomeEnabled(true)
|
supportActionBar?.setDisplayShowHomeEnabled(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setDrawUnderStatusBar()
|
setDrawUnderStatusBar()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
lastFMRestClient = LastFMRestClient(this)
|
lastFMRestClient = LastFMRestClient(this)
|
||||||
|
|
||||||
setUpViews()
|
setUpViews()
|
||||||
setupToolbar()
|
setupToolbar()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setUpViews() {
|
||||||
|
fillViewsWithFileTags()
|
||||||
|
|
||||||
private fun setUpViews() {
|
MaterialUtil.setTint(yearContainer, false)
|
||||||
fillViewsWithFileTags()
|
MaterialUtil.setTint(genreContainer, false)
|
||||||
|
MaterialUtil.setTint(albumTitleContainer, false)
|
||||||
|
MaterialUtil.setTint(albumArtistContainer, false)
|
||||||
|
|
||||||
MaterialUtil.setTint(yearContainer, false)
|
albumText.appHandleColor().addTextChangedListener(this)
|
||||||
MaterialUtil.setTint(genreContainer, false)
|
albumArtistText.appHandleColor().addTextChangedListener(this)
|
||||||
MaterialUtil.setTint(albumTitleContainer, false)
|
genreTitle.appHandleColor().addTextChangedListener(this)
|
||||||
MaterialUtil.setTint(albumArtistContainer, false)
|
yearTitle.appHandleColor().addTextChangedListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
albumText.appHandleColor().addTextChangedListener(this)
|
private fun fillViewsWithFileTags() {
|
||||||
albumArtistText.appHandleColor().addTextChangedListener(this)
|
albumText.setText(albumTitle)
|
||||||
genreTitle.appHandleColor().addTextChangedListener(this)
|
albumArtistText.setText(albumArtistName)
|
||||||
yearTitle.appHandleColor().addTextChangedListener(this)
|
genreTitle.setText(genreName)
|
||||||
}
|
yearTitle.setText(songYear)
|
||||||
|
}
|
||||||
|
|
||||||
private fun fillViewsWithFileTags() {
|
override fun loadCurrentImage() {
|
||||||
albumText.setText(albumTitle)
|
val bitmap = albumArt
|
||||||
albumArtistText.setText(albumArtistName)
|
setImageBitmap(
|
||||||
genreTitle.setText(genreName)
|
bitmap,
|
||||||
yearTitle.setText(songYear)
|
getColor(
|
||||||
}
|
generatePalette(bitmap),
|
||||||
|
ATHUtil.resolveColor(this, R.attr.defaultFooterColor)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
deleteAlbumArt = false
|
||||||
|
}
|
||||||
|
|
||||||
override fun loadCurrentImage() {
|
override fun onPause() {
|
||||||
val bitmap = albumArt
|
super.onPause()
|
||||||
setImageBitmap(bitmap, getColor(generatePalette(bitmap), ATHUtil.resolveColor(this, R.attr.defaultFooterColor)))
|
disposable.clear()
|
||||||
deleteAlbumArt = false
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPause() {
|
private fun extractDetails(lastFmAlbum: LastFmAlbum) {
|
||||||
super.onPause()
|
if (lastFmAlbum.album != null) {
|
||||||
disposable.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun extractDetails(lastFmAlbum: LastFmAlbum) {
|
val url = LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.album.image)
|
||||||
if (lastFmAlbum.album != null) {
|
|
||||||
|
|
||||||
val url = LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.album.image)
|
if (!TextUtils.isEmpty(url) && url.trim { it <= ' ' }.isNotEmpty()) {
|
||||||
|
Glide.with(this@AlbumTagEditorActivity).load(url).asBitmap()
|
||||||
|
.transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java)
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.SOURCE).error(R.drawable.default_album_art)
|
||||||
|
.into(object : SimpleTarget<BitmapPaletteWrapper>() {
|
||||||
|
override fun onLoadFailed(
|
||||||
|
e: java.lang.Exception?,
|
||||||
|
errorDrawable: Drawable?
|
||||||
|
) {
|
||||||
|
super.onLoadFailed(e, errorDrawable)
|
||||||
|
Toast.makeText(
|
||||||
|
this@AlbumTagEditorActivity,
|
||||||
|
e.toString(),
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(url) && url.trim { it <= ' ' }.isNotEmpty()) {
|
override fun onResourceReady(
|
||||||
Glide.with(this@AlbumTagEditorActivity)
|
resource: BitmapPaletteWrapper?,
|
||||||
.load(url)
|
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?
|
||||||
.asBitmap()
|
) {
|
||||||
.transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java)
|
albumArtBitmap = resource?.bitmap?.let {
|
||||||
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
|
ImageUtil.resizeBitmap(
|
||||||
.error(R.drawable.default_album_art)
|
it,
|
||||||
.into(object : SimpleTarget<BitmapPaletteWrapper>() {
|
2048
|
||||||
override fun onLoadFailed(e: java.lang.Exception?, errorDrawable: Drawable?) {
|
)
|
||||||
super.onLoadFailed(e, errorDrawable)
|
}
|
||||||
Toast.makeText(this@AlbumTagEditorActivity, e.toString(), Toast.LENGTH_LONG).show()
|
setImageBitmap(
|
||||||
}
|
albumArtBitmap,
|
||||||
|
getColor(
|
||||||
|
resource?.palette,
|
||||||
|
ATHUtil.resolveColor(
|
||||||
|
this@AlbumTagEditorActivity,
|
||||||
|
R.attr.defaultFooterColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
deleteAlbumArt = false
|
||||||
|
dataChanged()
|
||||||
|
setResult(RESULT_OK)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (lastFmAlbum.album.tags.tag.size > 0) {
|
||||||
|
genreTitle.setText(lastFmAlbum.album.tags.tag[0].name)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onResourceReady(resource: BitmapPaletteWrapper?, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
|
}
|
||||||
albumArtBitmap = resource?.bitmap?.let { ImageUtil.resizeBitmap(it, 2048) }
|
toastLoadingFailed()
|
||||||
setImageBitmap(albumArtBitmap, getColor(resource?.palette, ATHUtil.resolveColor(this@AlbumTagEditorActivity, R.attr.defaultFooterColor)))
|
}
|
||||||
deleteAlbumArt = false
|
|
||||||
dataChanged()
|
|
||||||
setResult(RESULT_OK)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (lastFmAlbum.album.tags.tag.size > 0) {
|
|
||||||
genreTitle.setText(lastFmAlbum.album.tags.tag[0].name)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
private fun toastLoadingFailed() {
|
||||||
toastLoadingFailed()
|
Toast.makeText(
|
||||||
}
|
this@AlbumTagEditorActivity,
|
||||||
|
R.string.could_not_download_album_cover,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
|
||||||
private fun toastLoadingFailed() {
|
override fun searchImageOnWeb() {
|
||||||
Toast.makeText(this@AlbumTagEditorActivity, R.string.could_not_download_album_cover, Toast.LENGTH_SHORT).show()
|
searchWebFor(albumText.text.toString(), albumArtistText.text.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchImageOnWeb() {
|
override fun deleteImage() {
|
||||||
searchWebFor(albumText.text.toString(), albumArtistText.text.toString())
|
setImageBitmap(
|
||||||
}
|
BitmapFactory.decodeResource(resources, R.drawable.default_album_art),
|
||||||
|
ATHUtil.resolveColor(this, R.attr.defaultFooterColor)
|
||||||
|
)
|
||||||
|
deleteAlbumArt = true
|
||||||
|
dataChanged()
|
||||||
|
}
|
||||||
|
|
||||||
override fun deleteImage() {
|
override fun save() {
|
||||||
setImageBitmap(BitmapFactory.decodeResource(resources, R.drawable.default_album_art), ATHUtil.resolveColor(this, R.attr.defaultFooterColor))
|
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
||||||
deleteAlbumArt = true
|
fieldKeyValueMap[FieldKey.ALBUM] = albumText.text.toString()
|
||||||
dataChanged()
|
//android seems not to recognize album_artist field so we additionally write the normal artist field
|
||||||
}
|
fieldKeyValueMap[FieldKey.ARTIST] = albumArtistText.text.toString()
|
||||||
|
fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = albumArtistText.text.toString()
|
||||||
|
fieldKeyValueMap[FieldKey.GENRE] = genreTitle.text.toString()
|
||||||
|
fieldKeyValueMap[FieldKey.YEAR] = yearTitle.text.toString()
|
||||||
|
|
||||||
override fun save() {
|
writeValuesToFiles(
|
||||||
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
fieldKeyValueMap, if (deleteAlbumArt) ArtworkInfo(id, null)
|
||||||
fieldKeyValueMap[FieldKey.ALBUM] = albumText.text.toString()
|
else if (albumArtBitmap == null) null else ArtworkInfo(id, albumArtBitmap!!)
|
||||||
//android seems not to recognize album_artist field so we additionally write the normal artist field
|
)
|
||||||
fieldKeyValueMap[FieldKey.ARTIST] = albumArtistText.text.toString()
|
}
|
||||||
fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = albumArtistText.text.toString()
|
|
||||||
fieldKeyValueMap[FieldKey.GENRE] = genreTitle.text.toString()
|
|
||||||
fieldKeyValueMap[FieldKey.YEAR] = yearTitle.text.toString()
|
|
||||||
|
|
||||||
writeValuesToFiles(fieldKeyValueMap, if (deleteAlbumArt) ArtworkInfo(id, null)
|
override fun getSongPaths(): List<String> {
|
||||||
else if (albumArtBitmap == null) null else ArtworkInfo(id, albumArtBitmap!!))
|
val songs = AlbumLoader.getAlbum(this, id).songs
|
||||||
}
|
val paths = ArrayList<String>(songs!!.size)
|
||||||
|
for (song in songs) {
|
||||||
|
paths.add(song.data)
|
||||||
|
}
|
||||||
|
return paths
|
||||||
|
}
|
||||||
|
|
||||||
override fun getSongPaths(): List<String> {
|
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
||||||
val songs = AlbumLoader.getAlbum(this, id).songs
|
|
||||||
val paths = ArrayList<String>(songs!!.size)
|
|
||||||
for (song in songs) {
|
|
||||||
paths.add(song.data)
|
|
||||||
}
|
|
||||||
return paths
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
override fun afterTextChanged(s: Editable) {
|
||||||
|
dataChanged()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
override fun setColors(color: Int) {
|
||||||
|
super.setColors(color)
|
||||||
|
saveFab.backgroundTintList = ColorStateList.valueOf(color)
|
||||||
|
}
|
||||||
|
|
||||||
override fun afterTextChanged(s: Editable) {
|
companion object {
|
||||||
dataChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setColors(color: Int) {
|
val TAG: String = AlbumTagEditorActivity::class.java.simpleName
|
||||||
super.setColors(color)
|
}
|
||||||
saveFab.backgroundTintList = ColorStateList.valueOf(color)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
val TAG: String = AlbumTagEditorActivity::class.java.simpleName
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,10 @@ package code.name.monkey.retromusic.activities.tageditor
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Editable
|
import android.text.*
|
||||||
import android.text.TextWatcher
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
|
||||||
import code.name.monkey.appthemehelper.util.TintHelper
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.extensions.appHandleColor
|
import code.name.monkey.retromusic.extensions.appHandleColor
|
||||||
import code.name.monkey.retromusic.loaders.SongLoader
|
import code.name.monkey.retromusic.loaders.SongLoader
|
||||||
|
@ -16,118 +13,127 @@ import kotlinx.android.synthetic.main.activity_song_tag_editor.*
|
||||||
import org.jaudiotagger.tag.FieldKey
|
import org.jaudiotagger.tag.FieldKey
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
|
|
||||||
override val contentViewLayout: Int
|
override val contentViewLayout: Int
|
||||||
get() = R.layout.activity_song_tag_editor
|
get() = R.layout.activity_song_tag_editor
|
||||||
|
|
||||||
private fun setupToolbar() {
|
private fun setupToolbar() {
|
||||||
appBarLayout.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
appBarLayout.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
||||||
toolbar.apply {
|
toolbar.apply {
|
||||||
setBackgroundColor(ATHUtil.resolveColor(this@SongTagEditorActivity, R.attr.colorPrimary))
|
setBackgroundColor(
|
||||||
navigationIcon = TintHelper.createTintedDrawable(ContextCompat.getDrawable(context, R.drawable.ic_keyboard_backspace_black_24dp), ThemeStore.textColorPrimary(context))
|
ATHUtil.resolveColor(
|
||||||
setNavigationOnClickListener { onBackPressed() }
|
this@SongTagEditorActivity,
|
||||||
setSupportActionBar(toolbar)
|
R.attr.colorPrimary
|
||||||
}
|
)
|
||||||
title = null
|
)
|
||||||
}
|
navigationIcon = TintHelper.createTintedDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
context,
|
||||||
|
R.drawable.ic_keyboard_backspace_black_24dp
|
||||||
|
), ThemeStore.textColorPrimary(context)
|
||||||
|
)
|
||||||
|
setNavigationOnClickListener { onBackPressed() }
|
||||||
|
setSupportActionBar(toolbar)
|
||||||
|
}
|
||||||
|
title = null
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
setNoImageMode()
|
setNoImageMode()
|
||||||
setUpViews()
|
setUpViews()
|
||||||
setupToolbar()
|
setupToolbar()
|
||||||
setStatusbarColorAuto()
|
setStatusbarColorAuto()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpViews() {
|
private fun setUpViews() {
|
||||||
fillViewsWithFileTags()
|
fillViewsWithFileTags()
|
||||||
MaterialUtil.setTint(songTextContainer, false)
|
MaterialUtil.setTint(songTextContainer, false)
|
||||||
MaterialUtil.setTint(composerContainer, false)
|
MaterialUtil.setTint(composerContainer, false)
|
||||||
MaterialUtil.setTint(albumTextContainer, false)
|
MaterialUtil.setTint(albumTextContainer, false)
|
||||||
MaterialUtil.setTint(artistContainer, false)
|
MaterialUtil.setTint(artistContainer, false)
|
||||||
MaterialUtil.setTint(albumArtistContainer, false)
|
MaterialUtil.setTint(albumArtistContainer, false)
|
||||||
MaterialUtil.setTint(yearContainer, false)
|
MaterialUtil.setTint(yearContainer, false)
|
||||||
MaterialUtil.setTint(genreContainer, false)
|
MaterialUtil.setTint(genreContainer, false)
|
||||||
MaterialUtil.setTint(trackNumberContainer, false)
|
MaterialUtil.setTint(trackNumberContainer, false)
|
||||||
MaterialUtil.setTint(lyricsContainer, false)
|
MaterialUtil.setTint(lyricsContainer, false)
|
||||||
|
|
||||||
songText.appHandleColor().addTextChangedListener(this)
|
songText.appHandleColor().addTextChangedListener(this)
|
||||||
albumText.appHandleColor().addTextChangedListener(this)
|
albumText.appHandleColor().addTextChangedListener(this)
|
||||||
albumArtistText.appHandleColor().addTextChangedListener(this)
|
albumArtistText.appHandleColor().addTextChangedListener(this)
|
||||||
artistText.appHandleColor().addTextChangedListener(this)
|
artistText.appHandleColor().addTextChangedListener(this)
|
||||||
genreText.appHandleColor().addTextChangedListener(this)
|
genreText.appHandleColor().addTextChangedListener(this)
|
||||||
yearText.appHandleColor().addTextChangedListener(this)
|
yearText.appHandleColor().addTextChangedListener(this)
|
||||||
trackNumberText.appHandleColor().addTextChangedListener(this)
|
trackNumberText.appHandleColor().addTextChangedListener(this)
|
||||||
lyricsText.appHandleColor().addTextChangedListener(this)
|
lyricsText.appHandleColor().addTextChangedListener(this)
|
||||||
songComposerText.appHandleColor().addTextChangedListener(this)
|
songComposerText.appHandleColor().addTextChangedListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fillViewsWithFileTags() {
|
private fun fillViewsWithFileTags() {
|
||||||
songText.setText(songTitle)
|
songText.setText(songTitle)
|
||||||
albumArtistText.setText(albumArtist)
|
albumArtistText.setText(albumArtist)
|
||||||
albumText.setText(albumTitle)
|
albumText.setText(albumTitle)
|
||||||
artistText.setText(artistName)
|
artistText.setText(artistName)
|
||||||
genreText.setText(genreName)
|
genreText.setText(genreName)
|
||||||
yearText.setText(songYear)
|
yearText.setText(songYear)
|
||||||
trackNumberText.setText(trackNumber)
|
trackNumberText.setText(trackNumber)
|
||||||
lyricsText.setText(lyrics)
|
lyricsText.setText(lyrics)
|
||||||
songComposerText.setText(composer)
|
songComposerText.setText(composer)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadCurrentImage() {
|
override fun loadCurrentImage() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchImageOnWeb() {
|
override fun searchImageOnWeb() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deleteImage() {
|
override fun deleteImage() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun save() {
|
override fun save() {
|
||||||
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
||||||
fieldKeyValueMap[FieldKey.TITLE] = songText.text.toString()
|
fieldKeyValueMap[FieldKey.TITLE] = songText.text.toString()
|
||||||
fieldKeyValueMap[FieldKey.ALBUM] = albumText.text.toString()
|
fieldKeyValueMap[FieldKey.ALBUM] = albumText.text.toString()
|
||||||
fieldKeyValueMap[FieldKey.ARTIST] = artistText.text.toString()
|
fieldKeyValueMap[FieldKey.ARTIST] = artistText.text.toString()
|
||||||
fieldKeyValueMap[FieldKey.GENRE] = genreText.text.toString()
|
fieldKeyValueMap[FieldKey.GENRE] = genreText.text.toString()
|
||||||
fieldKeyValueMap[FieldKey.YEAR] = yearText.text.toString()
|
fieldKeyValueMap[FieldKey.YEAR] = yearText.text.toString()
|
||||||
fieldKeyValueMap[FieldKey.TRACK] = trackNumberText.text.toString()
|
fieldKeyValueMap[FieldKey.TRACK] = trackNumberText.text.toString()
|
||||||
fieldKeyValueMap[FieldKey.LYRICS] = lyricsText.text.toString()
|
fieldKeyValueMap[FieldKey.LYRICS] = lyricsText.text.toString()
|
||||||
fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = albumArtistText.text.toString()
|
fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = albumArtistText.text.toString()
|
||||||
fieldKeyValueMap[FieldKey.COMPOSER] = songComposerText.text.toString()
|
fieldKeyValueMap[FieldKey.COMPOSER] = songComposerText.text.toString()
|
||||||
writeValuesToFiles(fieldKeyValueMap, null)
|
writeValuesToFiles(fieldKeyValueMap, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSongPaths(): List<String> {
|
override fun getSongPaths(): List<String> {
|
||||||
val paths = ArrayList<String>(1)
|
val paths = ArrayList<String>(1)
|
||||||
paths.add(SongLoader.getSong(this, id).data)
|
paths.add(SongLoader.getSong(this, id).data)
|
||||||
return paths
|
return paths
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadImageFromFile(selectedFile: Uri?) {
|
override fun loadImageFromFile(selectedFile: Uri?) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun afterTextChanged(s: Editable) {
|
override fun afterTextChanged(s: Editable) {
|
||||||
dataChanged()
|
dataChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val TAG: String = SongTagEditorActivity::class.java.simpleName
|
val TAG: String = SongTagEditorActivity::class.java.simpleName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package code.name.monkey.retromusic.adapter
|
package code.name.monkey.retromusic.adapter
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
|
@ -13,56 +11,64 @@ import code.name.monkey.retromusic.views.CircularImageView
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
|
|
||||||
class ContributorAdapter(
|
class ContributorAdapter(
|
||||||
private var contributors: List<Contributor>
|
private var contributors: List<Contributor>
|
||||||
) : RecyclerView.Adapter<ContributorAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<ContributorAdapter.ViewHolder>() {
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
return if (viewType == HEADER) {
|
return if (viewType == HEADER) {
|
||||||
ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_contributor_header, parent, false))
|
ViewHolder(
|
||||||
} else
|
LayoutInflater.from(parent.context).inflate(
|
||||||
ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_contributor, parent, false))
|
R.layout.item_contributor_header,
|
||||||
}
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else ViewHolder(
|
||||||
|
LayoutInflater.from(parent.context).inflate(
|
||||||
|
R.layout.item_contributor,
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val HEADER: Int = 0
|
const val HEADER: Int = 0
|
||||||
const val ITEM: Int = 1
|
const val ITEM: Int = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
return if (position == 0) {
|
return if (position == 0) {
|
||||||
HEADER
|
HEADER
|
||||||
} else {
|
} else {
|
||||||
ITEM
|
ITEM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val contributor = contributors[position]
|
val contributor = contributors[position]
|
||||||
holder.bindData(contributor)
|
holder.bindData(contributor)
|
||||||
holder.itemView.setOnClickListener {
|
holder.itemView.setOnClickListener {
|
||||||
openUrl(it?.context as Activity, contributors[position].link)
|
openUrl(it?.context as Activity, contributors[position].link)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return contributors.size
|
return contributors.size
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
val title: TextView = itemView.findViewById(R.id.title)
|
val title: TextView = itemView.findViewById(R.id.title)
|
||||||
val text: TextView = itemView.findViewById(R.id.text)
|
val text: TextView = itemView.findViewById(R.id.text)
|
||||||
val image: CircularImageView = itemView.findViewById(R.id.icon)
|
val image: CircularImageView = itemView.findViewById(R.id.icon)
|
||||||
|
|
||||||
internal fun bindData(contributor: Contributor) {
|
internal fun bindData(contributor: Contributor) {
|
||||||
title.text = contributor.name
|
title.text = contributor.name
|
||||||
text.text = contributor.summary
|
text.text = contributor.summary
|
||||||
println(contributor.profileImage)
|
println(contributor.profileImage)
|
||||||
Glide.with(image.context)
|
Glide.with(image.context).load(contributor.profileImage)
|
||||||
.load(contributor.profileImage)
|
.error(R.drawable.ic_account_white_24dp)
|
||||||
.error(R.drawable.ic_account_white_24dp)
|
.placeholder(R.drawable.ic_account_white_24dp).dontAnimate().into(image)
|
||||||
.placeholder(R.drawable.ic_account_white_24dp)
|
}
|
||||||
.dontAnimate()
|
}
|
||||||
.into(image)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package code.name.monkey.retromusic.adapter
|
package code.name.monkey.retromusic.adapter
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
||||||
|
@ -16,48 +14,49 @@ import java.util.*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class GenreAdapter(
|
class GenreAdapter(
|
||||||
private val mActivity: Activity,
|
private val activity: Activity, dataSet: ArrayList<Genre>, private val mItemLayoutRes: Int
|
||||||
dataSet: ArrayList<Genre>,
|
|
||||||
private val mItemLayoutRes: Int
|
|
||||||
) : RecyclerView.Adapter<GenreAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<GenreAdapter.ViewHolder>() {
|
||||||
var dataSet = ArrayList<Genre>()
|
var dataSet = ArrayList<Genre>()
|
||||||
private set
|
private set
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.dataSet = dataSet
|
this.dataSet = dataSet
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
return ViewHolder(LayoutInflater.from(mActivity).inflate(mItemLayoutRes, parent, false))
|
return ViewHolder(LayoutInflater.from(activity).inflate(mItemLayoutRes, parent, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val genre = dataSet[position]
|
val genre = dataSet[position]
|
||||||
if (holder.title != null) {
|
if (holder.title != null) {
|
||||||
holder.title!!.text = genre.name
|
holder.title!!.text = genre.name
|
||||||
}
|
}
|
||||||
if (holder.text != null) {
|
if (holder.text != null) {
|
||||||
holder.text!!.text = String.format(Locale.getDefault(), "%d %s", genre.songCount, if (genre.songCount > 1)
|
holder.text!!.text = String.format(
|
||||||
mActivity.getString(R.string.songs)
|
Locale.getDefault(),
|
||||||
else
|
"%d %s",
|
||||||
mActivity.getString(R.string.song))
|
genre.songCount,
|
||||||
}
|
if (genre.songCount > 1) activity.getString(R.string.songs)
|
||||||
}
|
else activity.getString(R.string.song)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return dataSet.size
|
return dataSet.size
|
||||||
}
|
}
|
||||||
|
|
||||||
fun swapDataSet(list: ArrayList<Genre>) {
|
fun swapDataSet(list: ArrayList<Genre>) {
|
||||||
dataSet = list
|
dataSet = list
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
||||||
override fun onClick(v: View?) {
|
override fun onClick(v: View?) {
|
||||||
super.onClick(v)
|
super.onClick(v)
|
||||||
val genre = dataSet[adapterPosition]
|
val genre = dataSet[adapterPosition]
|
||||||
NavigationUtil.goToGenre(mActivity, genre)
|
NavigationUtil.goToGenre(activity, genre)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,181 +1,221 @@
|
||||||
package code.name.monkey.retromusic.adapter
|
package code.name.monkey.retromusic.adapter
|
||||||
|
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.annotation.IntDef
|
import androidx.annotation.IntDef
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.*
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.adapter.album.AlbumFullWidthAdapter
|
import code.name.monkey.retromusic.adapter.album.AlbumFullWidthAdapter
|
||||||
import code.name.monkey.retromusic.adapter.artist.ArtistAdapter
|
import code.name.monkey.retromusic.adapter.artist.ArtistAdapter
|
||||||
import code.name.monkey.retromusic.adapter.song.SongAdapter
|
import code.name.monkey.retromusic.adapter.song.SongAdapter
|
||||||
import code.name.monkey.retromusic.extensions.show
|
import code.name.monkey.retromusic.extensions.show
|
||||||
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
|
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
|
||||||
import code.name.monkey.retromusic.model.Album
|
import code.name.monkey.retromusic.model.*
|
||||||
import code.name.monkey.retromusic.model.Artist
|
|
||||||
import code.name.monkey.retromusic.model.Home
|
|
||||||
import code.name.monkey.retromusic.model.Playlist
|
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
import com.google.android.material.textview.MaterialTextView
|
import com.google.android.material.textview.MaterialTextView
|
||||||
|
|
||||||
|
|
||||||
class HomeAdapter(
|
class HomeAdapter(
|
||||||
private val activity: AppCompatActivity,
|
private val activity: AppCompatActivity, private val displayMetrics: DisplayMetrics
|
||||||
private val displayMetrics: DisplayMetrics
|
|
||||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
|
||||||
private var list = ArrayList<Home>()
|
private var list = ArrayList<Home>()
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
return list[position].homeSection
|
return list[position].homeSection
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
val layout = LayoutInflater.from(activity).inflate(R.layout.section_recycler_view, parent, false)
|
val layout = LayoutInflater.from(activity)
|
||||||
return when (viewType) {
|
.inflate(R.layout.section_recycler_view, parent, false)
|
||||||
RECENT_ARTISTS, TOP_ARTISTS -> ArtistViewHolder(layout)
|
return when (viewType) {
|
||||||
PLAYLISTS -> PlaylistViewHolder(layout)
|
RECENT_ARTISTS, TOP_ARTISTS -> ArtistViewHolder(layout)
|
||||||
else -> {
|
PLAYLISTS -> PlaylistViewHolder(layout)
|
||||||
AlbumViewHolder(LayoutInflater.from(activity).inflate(R.layout.metal_section_recycler_view, parent, false))
|
else -> {
|
||||||
}
|
AlbumViewHolder(
|
||||||
}
|
LayoutInflater.from(activity).inflate(
|
||||||
}
|
R.layout.metal_section_recycler_view,
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
println("ViewType ${getItemViewType(position)}")
|
println("ViewType ${getItemViewType(position)}")
|
||||||
when (getItemViewType(position)) {
|
when (getItemViewType(position)) {
|
||||||
RECENT_ALBUMS -> {
|
RECENT_ALBUMS -> {
|
||||||
val viewHolder = holder as AlbumViewHolder
|
val viewHolder = holder as AlbumViewHolder
|
||||||
viewHolder.bindView(list[position].arrayList.toAlbums(), R.string.recent_albums, R.string.recent_added_albums)
|
viewHolder.bindView(
|
||||||
}
|
list[position].arrayList.toAlbums(),
|
||||||
TOP_ALBUMS -> {
|
R.string.recent_albums,
|
||||||
val viewHolder = holder as AlbumViewHolder
|
R.string.recent_added_albums
|
||||||
viewHolder.bindView(list[position].arrayList.toAlbums(), R.string.top_albums, R.string.most_played_albums)
|
)
|
||||||
}
|
}
|
||||||
RECENT_ARTISTS -> {
|
TOP_ALBUMS -> {
|
||||||
val viewHolder = holder as ArtistViewHolder
|
val viewHolder = holder as AlbumViewHolder
|
||||||
viewHolder.bindView(list[position].arrayList.toArtists(), R.string.recent_artists, R.string.recent_added_artists)
|
viewHolder.bindView(
|
||||||
}
|
list[position].arrayList.toAlbums(),
|
||||||
TOP_ARTISTS -> {
|
R.string.top_albums,
|
||||||
val viewHolder = holder as ArtistViewHolder
|
R.string.most_played_albums
|
||||||
|
)
|
||||||
|
}
|
||||||
|
RECENT_ARTISTS -> {
|
||||||
|
val viewHolder = holder as ArtistViewHolder
|
||||||
|
viewHolder.bindView(
|
||||||
|
list[position].arrayList.toArtists(),
|
||||||
|
R.string.recent_artists,
|
||||||
|
R.string.recent_added_artists
|
||||||
|
)
|
||||||
|
}
|
||||||
|
TOP_ARTISTS -> {
|
||||||
|
val viewHolder = holder as ArtistViewHolder
|
||||||
|
|
||||||
viewHolder.bindView(list[position].arrayList.toArtists(), R.string.top_artists, R.string.most_played_artists)
|
viewHolder.bindView(
|
||||||
}
|
list[position].arrayList.toArtists(),
|
||||||
PLAYLISTS -> {
|
R.string.top_artists,
|
||||||
val viewHolder = holder as PlaylistViewHolder
|
R.string.most_played_artists
|
||||||
viewHolder.bindView(list[position].arrayList.toPlaylist(), R.string.favorites, R.string.favorites_songs)
|
)
|
||||||
}
|
}
|
||||||
}
|
PLAYLISTS -> {
|
||||||
}
|
val viewHolder = holder as PlaylistViewHolder
|
||||||
|
viewHolder.bindView(
|
||||||
|
list[position].arrayList.toPlaylist(),
|
||||||
|
R.string.favorites,
|
||||||
|
R.string.favorites_songs
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return list.size
|
return list.size
|
||||||
}
|
}
|
||||||
|
|
||||||
fun swapData(sections: ArrayList<Home>) {
|
fun swapData(sections: ArrayList<Home>) {
|
||||||
list = sections
|
list = sections
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
@IntDef(RECENT_ALBUMS, TOP_ALBUMS, RECENT_ARTISTS, TOP_ARTISTS, PLAYLISTS)
|
@IntDef(RECENT_ALBUMS, TOP_ALBUMS, RECENT_ARTISTS, TOP_ARTISTS, PLAYLISTS)
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
annotation class HomeSection
|
annotation class HomeSection
|
||||||
|
|
||||||
const val RECENT_ALBUMS = 3
|
const val RECENT_ALBUMS = 3
|
||||||
const val TOP_ALBUMS = 1
|
const val TOP_ALBUMS = 1
|
||||||
const val RECENT_ARTISTS = 2
|
const val RECENT_ARTISTS = 2
|
||||||
const val TOP_ARTISTS = 0
|
const val TOP_ARTISTS = 0
|
||||||
const val PLAYLISTS = 4
|
const val PLAYLISTS = 4
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class AlbumViewHolder(view: View) : AbsHomeViewItem(view) {
|
private inner class AlbumViewHolder(view: View) : AbsHomeViewItem(view) {
|
||||||
fun bindView(list: ArrayList<Album>, titleRes: Int, subtitleRes: Int) {
|
fun bindView(list: ArrayList<Album>, titleRes: Int, subtitleRes: Int) {
|
||||||
if (list.isNotEmpty()) {
|
if (list.isNotEmpty()) {
|
||||||
recyclerView.apply {
|
recyclerView.apply {
|
||||||
show()
|
show()
|
||||||
adapter = AlbumFullWidthAdapter(activity, list, displayMetrics)
|
adapter = AlbumFullWidthAdapter(activity, list, displayMetrics)
|
||||||
}
|
}
|
||||||
titleContainer.show()
|
titleContainer.show()
|
||||||
title.text = activity.getString(titleRes)
|
title.text = activity.getString(titleRes)
|
||||||
text.text = activity.getString(subtitleRes)
|
text.text = activity.getString(subtitleRes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class ArtistViewHolder(view: View) : AbsHomeViewItem(view) {
|
inner class ArtistViewHolder(view: View) : AbsHomeViewItem(view) {
|
||||||
fun bindView(list: ArrayList<Artist>, titleRes: Int, subtitleRes: Int) {
|
fun bindView(list: ArrayList<Artist>, titleRes: Int, subtitleRes: Int) {
|
||||||
if (list.isNotEmpty()) {
|
if (list.isNotEmpty()) {
|
||||||
recyclerView.apply {
|
recyclerView.apply {
|
||||||
show()
|
show()
|
||||||
layoutManager = GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
|
layoutManager = GridLayoutManager(
|
||||||
val artistAdapter = ArtistAdapter(activity, list,
|
activity,
|
||||||
PreferenceUtil.getInstance(activity).getHomeGridStyle(activity), false, null)
|
1,
|
||||||
adapter = artistAdapter
|
GridLayoutManager.HORIZONTAL,
|
||||||
}
|
false
|
||||||
titleContainer.show()
|
)
|
||||||
title.text = activity.getString(titleRes)
|
val artistAdapter = ArtistAdapter(
|
||||||
text.text = activity.getString(subtitleRes)
|
activity,
|
||||||
}
|
list,
|
||||||
}
|
PreferenceUtil.getInstance(activity).getHomeGridStyle(activity),
|
||||||
}
|
false,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
adapter = artistAdapter
|
||||||
|
}
|
||||||
|
titleContainer.show()
|
||||||
|
title.text = activity.getString(titleRes)
|
||||||
|
text.text = activity.getString(subtitleRes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private inner class PlaylistViewHolder(view: View) : AbsHomeViewItem(view) {
|
private inner class PlaylistViewHolder(view: View) : AbsHomeViewItem(view) {
|
||||||
fun bindView(arrayList: ArrayList<Playlist>, titleRes: Int, subtitleRes: Int) {
|
fun bindView(arrayList: ArrayList<Playlist>, titleRes: Int, subtitleRes: Int) {
|
||||||
if (arrayList.isNotEmpty()) {
|
if (arrayList.isNotEmpty()) {
|
||||||
val songs = PlaylistSongsLoader.getPlaylistSongList(activity, arrayList[0])
|
val songs = PlaylistSongsLoader.getPlaylistSongList(activity, arrayList[0])
|
||||||
if (songs.isNotEmpty()) {
|
if (songs.isNotEmpty()) {
|
||||||
recyclerView.apply {
|
recyclerView.apply {
|
||||||
show()
|
show()
|
||||||
val songAdapter = SongAdapter(activity, songs, R.layout.item_album_card, false, null)
|
val songAdapter = SongAdapter(
|
||||||
layoutManager = GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
|
activity,
|
||||||
adapter = songAdapter
|
songs,
|
||||||
|
R.layout.item_album_card,
|
||||||
|
false,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
layoutManager = GridLayoutManager(
|
||||||
|
activity,
|
||||||
|
1,
|
||||||
|
GridLayoutManager.HORIZONTAL,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
adapter = songAdapter
|
||||||
|
|
||||||
}
|
}
|
||||||
titleContainer.show()
|
titleContainer.show()
|
||||||
title.text = activity.getString(titleRes)
|
title.text = activity.getString(titleRes)
|
||||||
text.text = activity.getString(subtitleRes)
|
text.text = activity.getString(subtitleRes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open inner class AbsHomeViewItem(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
open inner class AbsHomeViewItem(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
val recyclerView: RecyclerView = itemView.findViewById(R.id.recyclerView)
|
val recyclerView: RecyclerView = itemView.findViewById(R.id.recyclerView)
|
||||||
val titleContainer: View = itemView.findViewById(R.id.titleContainer)
|
val titleContainer: View = itemView.findViewById(R.id.titleContainer)
|
||||||
val title: MaterialTextView = itemView.findViewById(R.id.title)
|
val title: MaterialTextView = itemView.findViewById(R.id.title)
|
||||||
val text: MaterialTextView = itemView.findViewById(R.id.text)
|
val text: MaterialTextView = itemView.findViewById(R.id.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <E> ArrayList<E>.toAlbums(): ArrayList<Album> {
|
private fun <E> ArrayList<E>.toAlbums(): ArrayList<Album> {
|
||||||
val arrayList = ArrayList<Album>()
|
val arrayList = ArrayList<Album>()
|
||||||
for (x in this) {
|
for (x in this) {
|
||||||
arrayList.add(x as Album)
|
arrayList.add(x as Album)
|
||||||
}
|
}
|
||||||
return arrayList;
|
return arrayList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <E> ArrayList<E>.toArtists(): ArrayList<Artist> {
|
private fun <E> ArrayList<E>.toArtists(): ArrayList<Artist> {
|
||||||
val arrayList = ArrayList<Artist>()
|
val arrayList = ArrayList<Artist>()
|
||||||
for (x in this) {
|
for (x in this) {
|
||||||
arrayList.add(x as Artist)
|
arrayList.add(x as Artist)
|
||||||
}
|
}
|
||||||
return arrayList;
|
return arrayList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <E> ArrayList<E>.toPlaylist(): ArrayList<Playlist> {
|
private fun <E> ArrayList<E>.toPlaylist(): ArrayList<Playlist> {
|
||||||
val arrayList = ArrayList<Playlist>()
|
val arrayList = ArrayList<Playlist>()
|
||||||
for (x in this) {
|
for (x in this) {
|
||||||
arrayList.add(x as Playlist)
|
arrayList.add(x as Playlist)
|
||||||
}
|
}
|
||||||
return arrayList;
|
return arrayList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,129 +1,140 @@
|
||||||
package code.name.monkey.retromusic.adapter
|
package code.name.monkey.retromusic.adapter
|
||||||
|
|
||||||
import android.app.ActivityOptions
|
import android.app.ActivityOptions
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
||||||
import code.name.monkey.retromusic.glide.ArtistGlideRequest
|
import code.name.monkey.retromusic.glide.*
|
||||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.helper.menu.SongMenuHelper
|
import code.name.monkey.retromusic.helper.menu.SongMenuHelper
|
||||||
import code.name.monkey.retromusic.model.Album
|
import code.name.monkey.retromusic.model.*
|
||||||
import code.name.monkey.retromusic.model.Artist
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.model.Song
|
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import android.util.Pair as UtilPair
|
import android.util.Pair as UtilPair
|
||||||
|
|
||||||
class SearchAdapter(
|
class SearchAdapter(
|
||||||
private val activity: AppCompatActivity,
|
private val activity: AppCompatActivity, private var dataSet: List<Any>?
|
||||||
private var dataSet: List<Any>?
|
|
||||||
) : RecyclerView.Adapter<SearchAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<SearchAdapter.ViewHolder>() {
|
||||||
|
|
||||||
fun swapDataSet(dataSet: MutableList<Any>) {
|
fun swapDataSet(dataSet: MutableList<Any>) {
|
||||||
this.dataSet = dataSet
|
this.dataSet = dataSet
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
if (dataSet!![position] is Album) return ALBUM
|
if (dataSet!![position] is Album) return ALBUM
|
||||||
if (dataSet!![position] is Artist) return ARTIST
|
if (dataSet!![position] is Artist) return ARTIST
|
||||||
return if (dataSet!![position] is Song) SONG else HEADER
|
return if (dataSet!![position] is Song) SONG else HEADER
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
return if (viewType == HEADER) ViewHolder(LayoutInflater.from(activity).inflate(R.layout.sub_header, parent, false), viewType) else ViewHolder(LayoutInflater.from(activity).inflate(R.layout.item_list, parent, false), viewType)
|
return if (viewType == HEADER) ViewHolder(
|
||||||
}
|
LayoutInflater.from(activity).inflate(
|
||||||
|
R.layout.sub_header,
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
), viewType
|
||||||
|
) else ViewHolder(
|
||||||
|
LayoutInflater.from(activity).inflate(R.layout.item_list, parent, false),
|
||||||
|
viewType
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
when (getItemViewType(position)) {
|
when (getItemViewType(position)) {
|
||||||
ALBUM -> {
|
ALBUM -> {
|
||||||
val album = dataSet?.get(position) as Album
|
val album = dataSet?.get(position) as Album
|
||||||
holder.title?.text = album.title
|
holder.title?.text = album.title
|
||||||
holder.text?.text = album.artistName
|
holder.text?.text = album.artistName
|
||||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||||
.checkIgnoreMediaStore(activity).build()
|
.checkIgnoreMediaStore(activity).build().into(holder.image)
|
||||||
.into(holder.image)
|
}
|
||||||
}
|
ARTIST -> {
|
||||||
ARTIST -> {
|
val artist = dataSet?.get(position) as Artist
|
||||||
val artist = dataSet?.get(position) as Artist
|
holder.title?.text = artist.name
|
||||||
holder.title?.text = artist.name
|
holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
|
||||||
holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
|
ArtistGlideRequest.Builder.from(Glide.with(activity), artist).build()
|
||||||
ArtistGlideRequest.Builder.from(Glide.with(activity), artist)
|
.into(holder.image)
|
||||||
.build().into(holder.image)
|
}
|
||||||
}
|
SONG -> {
|
||||||
SONG -> {
|
val song = dataSet?.get(position) as Song
|
||||||
val song = dataSet?.get(position) as Song
|
holder.title?.text = song.title
|
||||||
holder.title?.text = song.title
|
holder.text?.text = song.albumName
|
||||||
holder.text?.text = song.albumName
|
}
|
||||||
}
|
else -> {
|
||||||
else -> {
|
holder.title?.text = dataSet?.get(position).toString()
|
||||||
holder.title?.text = dataSet?.get(position).toString()
|
holder.title?.setTextColor(ThemeStore.accentColor(activity))
|
||||||
holder.title?.setTextColor(ThemeStore.accentColor(activity))
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return dataSet!!.size
|
return dataSet!!.size
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View, itemViewType: Int) : MediaEntryViewHolder(itemView) {
|
inner class ViewHolder(itemView: View, itemViewType: Int) : MediaEntryViewHolder(itemView) {
|
||||||
init {
|
init {
|
||||||
itemView.setOnLongClickListener(null)
|
itemView.setOnLongClickListener(null)
|
||||||
|
|
||||||
if (itemViewType == SONG) {
|
if (itemViewType == SONG) {
|
||||||
menu?.visibility = View.VISIBLE
|
menu?.visibility = View.VISIBLE
|
||||||
menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
|
menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
|
||||||
override val song: Song
|
override val song: Song
|
||||||
get() = dataSet!![adapterPosition] as Song
|
get() = dataSet!![adapterPosition] as Song
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
menu?.visibility = View.GONE
|
menu?.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
when (itemViewType) {
|
when (itemViewType) {
|
||||||
ALBUM -> setImageTransitionName(activity.getString(R.string.transition_album_art))
|
ALBUM -> setImageTransitionName(activity.getString(R.string.transition_album_art))
|
||||||
ARTIST -> setImageTransitionName(activity.getString(R.string.transition_artist_image))
|
ARTIST -> setImageTransitionName(activity.getString(R.string.transition_artist_image))
|
||||||
else -> {
|
else -> {
|
||||||
val container = itemView.findViewById<View>(R.id.imageContainer)
|
val container = itemView.findViewById<View>(R.id.imageContainer)
|
||||||
container?.visibility = View.GONE
|
container?.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClick(v: View?) {
|
override fun onClick(v: View?) {
|
||||||
val item = dataSet!![adapterPosition]
|
val item = dataSet!![adapterPosition]
|
||||||
when (itemViewType) {
|
when (itemViewType) {
|
||||||
ALBUM -> {
|
ALBUM -> {
|
||||||
val options = ActivityOptions.makeSceneTransitionAnimation(activity,
|
val options = ActivityOptions.makeSceneTransitionAnimation(
|
||||||
UtilPair.create(image, activity.getString(R.string.transition_album_art)))
|
activity,
|
||||||
NavigationUtil.goToAlbumOptions(activity, (item as Album).id, options)
|
UtilPair.create(
|
||||||
}
|
image,
|
||||||
ARTIST -> {
|
activity.getString(R.string.transition_album_art)
|
||||||
val options = ActivityOptions.makeSceneTransitionAnimation(activity,
|
)
|
||||||
UtilPair.create(image, activity.getString(R.string.transition_artist_image)))
|
)
|
||||||
NavigationUtil.goToArtistOptions(activity, (item as Artist).id, options)
|
NavigationUtil.goToAlbumOptions(activity, (item as Album).id, options)
|
||||||
}
|
}
|
||||||
SONG -> {
|
ARTIST -> {
|
||||||
val playList = ArrayList<Song>()
|
val options = ActivityOptions.makeSceneTransitionAnimation(
|
||||||
playList.add(item as Song)
|
activity,
|
||||||
MusicPlayerRemote.openQueue(playList, 0, true)
|
UtilPair.create(
|
||||||
}
|
image,
|
||||||
}
|
activity.getString(R.string.transition_artist_image)
|
||||||
}
|
)
|
||||||
}
|
)
|
||||||
|
NavigationUtil.goToArtistOptions(activity, (item as Artist).id, options)
|
||||||
|
}
|
||||||
|
SONG -> {
|
||||||
|
val playList = ArrayList<Song>()
|
||||||
|
playList.add(item as Song)
|
||||||
|
MusicPlayerRemote.openQueue(playList, 0, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val HEADER = 0
|
private const val HEADER = 0
|
||||||
private const val ALBUM = 1
|
private const val ALBUM = 1
|
||||||
private const val ARTIST = 2
|
private const val ARTIST = 2
|
||||||
private const val SONG = 3
|
private const val SONG = 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
package code.name.monkey.retromusic.adapter
|
package code.name.monkey.retromusic.adapter
|
||||||
|
|
||||||
import android.graphics.PorterDuff
|
import android.graphics.PorterDuff
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
|
import code.name.monkey.retromusic.adapter.base.*
|
||||||
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
|
||||||
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
|
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.util.RetroUtil
|
import code.name.monkey.retromusic.util.RetroUtil
|
||||||
|
@ -20,162 +16,164 @@ import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.math.log10
|
import kotlin.math.*
|
||||||
import kotlin.math.pow
|
|
||||||
|
|
||||||
|
|
||||||
class SongFileAdapter(
|
class SongFileAdapter(
|
||||||
private val activity: AppCompatActivity,
|
private val activity: AppCompatActivity,
|
||||||
private var dataSet: List<File>?,
|
private var dataSet: List<File>?,
|
||||||
private val itemLayoutRes: Int,
|
private val itemLayoutRes: Int,
|
||||||
private val callbacks: Callbacks?,
|
private val callbacks: Callbacks?,
|
||||||
cabHolder: CabHolder?
|
cabHolder: CabHolder?
|
||||||
) : AbsMultiSelectAdapter<SongFileAdapter.ViewHolder, File>(activity, cabHolder, R.menu.menu_media_selection), FastScrollRecyclerView.SectionedAdapter {
|
) : AbsMultiSelectAdapter<SongFileAdapter.ViewHolder, File>(
|
||||||
|
activity, cabHolder, R.menu.menu_media_selection
|
||||||
|
), FastScrollRecyclerView.SectionedAdapter {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.setHasStableIds(true)
|
this.setHasStableIds(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
return if (dataSet!![position].isDirectory) FOLDER else FILE
|
return if (dataSet!![position].isDirectory) FOLDER else FILE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemId(position: Int): Long {
|
override fun getItemId(position: Int): Long {
|
||||||
return dataSet!![position].hashCode().toLong()
|
return dataSet!![position].hashCode().toLong()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun swapDataSet(songFiles: List<File>) {
|
fun swapDataSet(songFiles: List<File>) {
|
||||||
this.dataSet = songFiles
|
this.dataSet = songFiles
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
return ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false))
|
return ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, index: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, index: Int) {
|
||||||
val file = dataSet!![index]
|
val file = dataSet!![index]
|
||||||
holder.itemView.isActivated = isChecked(file)
|
holder.itemView.isActivated = isChecked(file)
|
||||||
holder.title?.text = getFileTitle(file)
|
holder.title?.text = getFileTitle(file)
|
||||||
if (holder.text != null) {
|
if (holder.text != null) {
|
||||||
if (holder.itemViewType == FILE) {
|
if (holder.itemViewType == FILE) {
|
||||||
holder.text!!.text = getFileText(file)
|
holder.text?.text = getFileText(file)
|
||||||
} else {
|
} else {
|
||||||
holder.text!!.visibility = View.GONE
|
holder.text?.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (holder.image != null) {
|
if (holder.image != null) {
|
||||||
loadFileImage(file, holder)
|
loadFileImage(file, holder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFileTitle(file: File): String {
|
private fun getFileTitle(file: File): String {
|
||||||
return file.name
|
return file.name
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFileText(file: File): String? {
|
private fun getFileText(file: File): String? {
|
||||||
return if (file.isDirectory) null else readableFileSize(file.length())
|
return if (file.isDirectory) null else readableFileSize(file.length())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadFileImage(file: File, holder: ViewHolder) {
|
private fun loadFileImage(file: File, holder: ViewHolder) {
|
||||||
val iconColor = ATHUtil.resolveColor(activity, R.attr.iconColor)
|
val iconColor = ATHUtil.resolveColor(activity, R.attr.iconColor)
|
||||||
if (file.isDirectory) {
|
if (file.isDirectory) {
|
||||||
holder.image?.let {
|
holder.image?.let {
|
||||||
it.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN)
|
it.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN)
|
||||||
it.setImageResource(R.drawable.ic_folder_white_24dp)
|
it.setImageResource(R.drawable.ic_folder_white_24dp)
|
||||||
}
|
}
|
||||||
holder.imageTextContainer?.setCardBackgroundColor(ATHUtil.resolveColor(activity, R.attr.colorPrimary))
|
holder.imageTextContainer?.setCardBackgroundColor(
|
||||||
|
ATHUtil.resolveColor(
|
||||||
|
activity, R.attr.colorPrimary
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
val error = RetroUtil.getTintedVectorDrawable(activity, R.drawable.ic_file_music_white_24dp, iconColor)
|
val error = RetroUtil.getTintedVectorDrawable(
|
||||||
Glide.with(activity)
|
activity, R.drawable.ic_file_music_white_24dp, iconColor
|
||||||
.load(AudioFileCover(file.path))
|
)
|
||||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
Glide.with(activity).load(AudioFileCover(file.path))
|
||||||
.error(error)
|
.diskCacheStrategy(DiskCacheStrategy.NONE).error(error).placeholder(error)
|
||||||
.placeholder(error)
|
.animate(android.R.anim.fade_in)
|
||||||
.animate(android.R.anim.fade_in)
|
.signature(MediaStoreSignature("", file.lastModified(), 0)).into(holder.image)
|
||||||
.signature(MediaStoreSignature("", file.lastModified(), 0))
|
}
|
||||||
.into(holder.image)
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return dataSet!!.size
|
return dataSet!!.size
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIdentifier(position: Int): File? {
|
override fun getIdentifier(position: Int): File? {
|
||||||
return dataSet!![position]
|
return dataSet!![position]
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(`object`: File): String {
|
override fun getName(`object`: File): String {
|
||||||
return getFileTitle(`object`)
|
return getFileTitle(`object`)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMultipleItemAction(menuItem: MenuItem, selection: ArrayList<File>) {
|
override fun onMultipleItemAction(menuItem: MenuItem, selection: ArrayList<File>) {
|
||||||
if (callbacks == null) return
|
if (callbacks == null) return
|
||||||
callbacks.onMultipleItemAction(menuItem, selection)
|
callbacks.onMultipleItemAction(menuItem, selection)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSectionName(position: Int): String {
|
override fun getSectionName(position: Int): String {
|
||||||
return dataSet!![position].name[0].toString().toUpperCase()
|
return dataSet!![position].name[0].toString().toUpperCase()
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Callbacks {
|
interface Callbacks {
|
||||||
fun onFileSelected(file: File)
|
fun onFileSelected(file: File)
|
||||||
|
|
||||||
fun onFileMenuClicked(file: File, view: View)
|
fun onFileMenuClicked(file: File, view: View)
|
||||||
|
|
||||||
fun onMultipleItemAction(item: MenuItem, files: ArrayList<File>)
|
fun onMultipleItemAction(item: MenuItem, files: ArrayList<File>)
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (menu != null && callbacks != null) {
|
if (menu != null && callbacks != null) {
|
||||||
menu!!.setOnClickListener { v ->
|
menu!!.setOnClickListener { v ->
|
||||||
val position = adapterPosition
|
val position = adapterPosition
|
||||||
if (isPositionInRange(position)) {
|
if (isPositionInRange(position)) {
|
||||||
callbacks.onFileMenuClicked(dataSet!![position], v)
|
callbacks.onFileMenuClicked(dataSet!![position], v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (imageTextContainer != null) {
|
if (imageTextContainer != null) {
|
||||||
imageTextContainer?.cardElevation = 0f
|
imageTextContainer?.cardElevation = 0f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClick(v: View?) {
|
override fun onClick(v: View?) {
|
||||||
val position = adapterPosition
|
val position = adapterPosition
|
||||||
if (isPositionInRange(position)) {
|
if (isPositionInRange(position)) {
|
||||||
if (isInQuickSelectMode) {
|
if (isInQuickSelectMode) {
|
||||||
toggleChecked(position)
|
toggleChecked(position)
|
||||||
} else {
|
} else {
|
||||||
callbacks?.onFileSelected(dataSet!![position])
|
callbacks?.onFileSelected(dataSet!![position])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLongClick(v: View?): Boolean {
|
override fun onLongClick(v: View?): Boolean {
|
||||||
val position = adapterPosition
|
val position = adapterPosition
|
||||||
return isPositionInRange(position) && toggleChecked(position)
|
return isPositionInRange(position) && toggleChecked(position)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isPositionInRange(position: Int): Boolean {
|
private fun isPositionInRange(position: Int): Boolean {
|
||||||
return position >= 0 && position < dataSet!!.size
|
return position >= 0 && position < dataSet!!.size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private const val FILE = 0
|
private const val FILE = 0
|
||||||
private const val FOLDER = 1
|
private const val FOLDER = 1
|
||||||
|
|
||||||
fun readableFileSize(size: Long): String {
|
fun readableFileSize(size: Long): String {
|
||||||
if (size <= 0) return "$size B"
|
if (size <= 0) return "$size B"
|
||||||
val units = arrayOf("B", "KB", "MB", "GB", "TB")
|
val units = arrayOf("B", "KB", "MB", "GB", "TB")
|
||||||
val digitGroups = (log10(size.toDouble()) / log10(1024.0)).toInt()
|
val digitGroups = (log10(size.toDouble()) / log10(1024.0)).toInt()
|
||||||
return DecimalFormat("#,##0.##").format(size / 1024.0.pow(digitGroups.toDouble())) + " " + units[digitGroups]
|
return DecimalFormat("#,##0.##").format(size / 1024.0.pow(digitGroups.toDouble())) + " " + units[digitGroups]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,186 +3,198 @@ package code.name.monkey.retromusic.adapter.album
|
||||||
import android.app.ActivityOptions
|
import android.app.ActivityOptions
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.annotation.LayoutRes
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
|
import code.name.monkey.retromusic.adapter.base.*
|
||||||
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
import code.name.monkey.retromusic.glide.*
|
||||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
import code.name.monkey.retromusic.helper.*
|
||||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
|
||||||
import code.name.monkey.retromusic.helper.SortOrder
|
|
||||||
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
|
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.model.Album
|
import code.name.monkey.retromusic.model.*
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
||||||
|
|
||||||
|
open class AlbumAdapter(
|
||||||
|
protected val activity: AppCompatActivity,
|
||||||
|
dataSet: ArrayList<Album>,
|
||||||
|
protected var itemLayoutRes: Int,
|
||||||
|
usePalette: Boolean,
|
||||||
|
cabHolder: CabHolder?
|
||||||
|
) : AbsMultiSelectAdapter<AlbumAdapter.ViewHolder, Album>(
|
||||||
|
activity, cabHolder, code.name.monkey.retromusic.R.menu.menu_media_selection
|
||||||
|
), FastScrollRecyclerView.SectionedAdapter {
|
||||||
|
var dataSet: ArrayList<Album>
|
||||||
|
protected set
|
||||||
|
|
||||||
open class AlbumAdapter(protected val activity: AppCompatActivity,
|
protected var usePalette = false
|
||||||
dataSet: ArrayList<Album>,
|
|
||||||
@param:LayoutRes protected var itemLayoutRes: Int,
|
|
||||||
usePalette: Boolean,
|
|
||||||
cabHolder: CabHolder?) : AbsMultiSelectAdapter<AlbumAdapter.ViewHolder, Album>(activity, cabHolder, code.name.monkey.retromusic.R.menu.menu_media_selection), FastScrollRecyclerView.SectionedAdapter {
|
|
||||||
var dataSet: ArrayList<Album>
|
|
||||||
protected set
|
|
||||||
|
|
||||||
protected var usePalette = false
|
init {
|
||||||
|
this.dataSet = dataSet
|
||||||
|
this.usePalette = usePalette
|
||||||
|
this.setHasStableIds(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun useItemLayout(itemLayoutRes: Int) {
|
||||||
|
this.itemLayoutRes = itemLayoutRes
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
fun usePalette(usePalette: Boolean) {
|
||||||
this.dataSet = dataSet
|
this.usePalette = usePalette
|
||||||
this.usePalette = usePalette
|
notifyDataSetChanged()
|
||||||
this.setHasStableIds(true)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun useItemLayout(itemLayoutRes: Int) {
|
fun swapDataSet(dataSet: ArrayList<Album>) {
|
||||||
this.itemLayoutRes = itemLayoutRes
|
this.dataSet = dataSet
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun usePalette(usePalette: Boolean) {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
this.usePalette = usePalette
|
val view = LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false)
|
||||||
notifyDataSetChanged()
|
return createViewHolder(view, viewType)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun swapDataSet(dataSet: ArrayList<Album>) {
|
protected open fun createViewHolder(view: View, viewType: Int): ViewHolder {
|
||||||
this.dataSet = dataSet
|
return ViewHolder(view)
|
||||||
notifyDataSetChanged()
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
private fun getAlbumTitle(album: Album): String? {
|
||||||
val view = LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false)
|
return album.title
|
||||||
return createViewHolder(view, viewType)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun createViewHolder(view: View, viewType: Int): ViewHolder {
|
protected open fun getAlbumText(album: Album): String? {
|
||||||
return ViewHolder(view)
|
return album.artistName
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAlbumTitle(album: Album): String? {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
return album.title
|
val album = dataSet[position]
|
||||||
}
|
val isChecked = isChecked(album)
|
||||||
|
holder.itemView.isActivated = isChecked
|
||||||
|
holder.title?.text = getAlbumTitle(album)
|
||||||
|
holder.text?.text = getAlbumText(album)
|
||||||
|
holder.playSongs?.setOnClickListener {
|
||||||
|
album.songs?.let { songs ->
|
||||||
|
MusicPlayerRemote.openQueue(
|
||||||
|
songs, 0, true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadAlbumCover(album, holder)
|
||||||
|
}
|
||||||
|
|
||||||
protected open fun getAlbumText(album: Album): String? {
|
protected open fun setColors(color: Int, holder: ViewHolder) {
|
||||||
return album.artistName
|
if (holder.paletteColorContainer != null) {
|
||||||
}
|
holder.title?.setTextColor(
|
||||||
|
MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color))
|
||||||
|
)
|
||||||
|
holder.text?.setTextColor(
|
||||||
|
MaterialValueHelper.getSecondaryTextColor(
|
||||||
|
activity, ColorUtil.isColorLight(
|
||||||
|
color
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
holder.paletteColorContainer?.setBackgroundColor(color)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
holder.mask?.backgroundTintList = ColorStateList.valueOf(color)
|
||||||
val album = dataSet[position]
|
}
|
||||||
val isChecked = isChecked(album)
|
|
||||||
holder.itemView.isActivated = isChecked
|
|
||||||
holder.title?.text = getAlbumTitle(album)
|
|
||||||
holder.text?.text = getAlbumText(album)
|
|
||||||
holder.playSongs?.setOnClickListener { album.songs?.let { songs -> MusicPlayerRemote.openQueue(songs, 0, true) } }
|
|
||||||
loadAlbumCover(album, holder)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun setColors(color: Int, holder: ViewHolder) {
|
protected open fun loadAlbumCover(album: Album, holder: ViewHolder) {
|
||||||
if (holder.paletteColorContainer != null) {
|
if (holder.image == null) {
|
||||||
holder.title?.setTextColor(
|
return
|
||||||
MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color)))
|
}
|
||||||
holder.text?.setTextColor(MaterialValueHelper.getSecondaryTextColor(activity, ColorUtil.isColorLight(color)))
|
|
||||||
holder.paletteColorContainer?.setBackgroundColor(color)
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.mask?.backgroundTintList = ColorStateList.valueOf(color)
|
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||||
}
|
.checkIgnoreMediaStore(activity).generatePalette(activity).build()
|
||||||
|
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
||||||
|
override fun onLoadCleared(placeholder: Drawable?) {
|
||||||
|
super.onLoadCleared(placeholder)
|
||||||
|
setColors(defaultFooterColor, holder)
|
||||||
|
}
|
||||||
|
|
||||||
protected open fun loadAlbumCover(album: Album, holder: ViewHolder) {
|
override fun onColorReady(color: Int) {
|
||||||
if (holder.image == null) {
|
setColors(color, holder)
|
||||||
return
|
}
|
||||||
}
|
})
|
||||||
|
}
|
||||||
|
|
||||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
override fun getItemCount(): Int {
|
||||||
.checkIgnoreMediaStore(activity)
|
return dataSet.size
|
||||||
.generatePalette(activity).build()
|
}
|
||||||
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
|
||||||
override fun onLoadCleared(placeholder: Drawable?) {
|
|
||||||
super.onLoadCleared(placeholder)
|
|
||||||
setColors(defaultFooterColor, holder)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onColorReady(color: Int) {
|
override fun getItemId(position: Int): Long {
|
||||||
setColors(color, holder)
|
return dataSet[position].id.toLong()
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getIdentifier(position: Int): Album? {
|
||||||
return dataSet.size
|
return dataSet[position]
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemId(position: Int): Long {
|
override fun getName(album: Album): String {
|
||||||
return dataSet[position].id.toLong()
|
return album.title!!
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIdentifier(position: Int): Album? {
|
override fun onMultipleItemAction(
|
||||||
return dataSet[position]
|
menuItem: MenuItem, selection: ArrayList<Album>
|
||||||
}
|
) {
|
||||||
|
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getName(album: Album): String {
|
private fun getSongList(albums: List<Album>): ArrayList<Song> {
|
||||||
return album.title!!
|
val songs = ArrayList<Song>()
|
||||||
}
|
for (album in albums) {
|
||||||
|
songs.addAll(album.songs!!)
|
||||||
|
}
|
||||||
|
return songs
|
||||||
|
}
|
||||||
|
|
||||||
override fun onMultipleItemAction(menuItem: MenuItem,
|
override fun getSectionName(position: Int): String {
|
||||||
selection: ArrayList<Album>) {
|
var sectionName: String? = null
|
||||||
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
|
when (PreferenceUtil.getInstance(activity).albumSortOrder) {
|
||||||
}
|
SortOrder.AlbumSortOrder.ALBUM_A_Z, SortOrder.AlbumSortOrder.ALBUM_Z_A -> sectionName = dataSet[position].title
|
||||||
|
SortOrder.AlbumSortOrder.ALBUM_ARTIST -> sectionName = dataSet[position].artistName
|
||||||
|
SortOrder.AlbumSortOrder.ALBUM_YEAR -> return MusicUtil.getYearString(
|
||||||
|
dataSet[position].year
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun getSongList(albums: List<Album>): ArrayList<Song> {
|
return MusicUtil.getSectionName(sectionName)
|
||||||
val songs = ArrayList<Song>()
|
}
|
||||||
for (album in albums) {
|
|
||||||
songs.addAll(album.songs!!)
|
|
||||||
}
|
|
||||||
return songs
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getSectionName(position: Int): String {
|
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
||||||
var sectionName: String? = null
|
|
||||||
when (PreferenceUtil.getInstance(activity).albumSortOrder) {
|
|
||||||
SortOrder.AlbumSortOrder.ALBUM_A_Z, SortOrder.AlbumSortOrder.ALBUM_Z_A -> sectionName = dataSet[position].title
|
|
||||||
SortOrder.AlbumSortOrder.ALBUM_ARTIST -> sectionName = dataSet[position].artistName
|
|
||||||
SortOrder.AlbumSortOrder.ALBUM_YEAR -> return MusicUtil.getYearString(dataSet[position].year)
|
|
||||||
}
|
|
||||||
|
|
||||||
return MusicUtil.getSectionName(sectionName)
|
init {
|
||||||
}
|
setImageTransitionName(activity.getString(R.string.transition_album_art))
|
||||||
|
menu?.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
override fun onClick(v: View?) {
|
||||||
|
super.onClick(v)
|
||||||
|
if (isInQuickSelectMode) {
|
||||||
|
toggleChecked(adapterPosition)
|
||||||
|
} else {
|
||||||
|
val activityOptions = ActivityOptions.makeSceneTransitionAnimation(
|
||||||
|
activity, image, activity.getString(
|
||||||
|
R.string.transition_album_art
|
||||||
|
)
|
||||||
|
)
|
||||||
|
NavigationUtil.goToAlbumOptions(
|
||||||
|
activity, dataSet[adapterPosition].id, activityOptions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
override fun onLongClick(v: View?): Boolean {
|
||||||
setImageTransitionName(activity.getString(R.string.transition_album_art))
|
toggleChecked(adapterPosition)
|
||||||
menu?.visibility = View.GONE
|
return super.onLongClick(v)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onClick(v: View?) {
|
companion object {
|
||||||
super.onClick(v)
|
val TAG: String = AlbumAdapter::class.java.simpleName
|
||||||
if (isInQuickSelectMode) {
|
}
|
||||||
toggleChecked(adapterPosition)
|
|
||||||
} else {
|
|
||||||
val activityOptions = ActivityOptions.makeSceneTransitionAnimation(activity, image, activity.getString(R.string.transition_album_art))
|
|
||||||
NavigationUtil.goToAlbumOptions(activity, dataSet[adapterPosition].id, activityOptions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onLongClick(v: View?): Boolean {
|
|
||||||
toggleChecked(adapterPosition)
|
|
||||||
return super.onLongClick(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val TAG: String = AlbumAdapter::class.java.simpleName
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,166 +1,165 @@
|
||||||
package code.name.monkey.retromusic.adapter.album
|
package code.name.monkey.retromusic.adapter.album
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.*
|
||||||
import androidx.fragment.app.FragmentManager
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.fragments.AlbumCoverStyle
|
import code.name.monkey.retromusic.fragments.AlbumCoverStyle
|
||||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
import code.name.monkey.retromusic.glide.*
|
||||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
|
||||||
import code.name.monkey.retromusic.misc.CustomFragmentStatePagerAdapter
|
import code.name.monkey.retromusic.misc.CustomFragmentStatePagerAdapter
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
class AlbumCoverPagerAdapter(
|
||||||
|
fm: FragmentManager,
|
||||||
|
private val dataSet: ArrayList<Song>
|
||||||
|
) : CustomFragmentStatePagerAdapter(fm) {
|
||||||
|
|
||||||
class AlbumCoverPagerAdapter(fm: FragmentManager, private val dataSet: ArrayList<Song>) : CustomFragmentStatePagerAdapter(fm) {
|
private var currentColorReceiver: AlbumCoverFragment.ColorReceiver? = null
|
||||||
|
private var currentColorReceiverPosition = -1
|
||||||
|
|
||||||
private var currentColorReceiver: AlbumCoverFragment.ColorReceiver? = null
|
override fun getItem(position: Int): Fragment {
|
||||||
private var currentColorReceiverPosition = -1
|
return AlbumCoverFragment.newInstance(dataSet[position])
|
||||||
|
}
|
||||||
|
|
||||||
override fun getItem(position: Int): Fragment {
|
override fun getCount(): Int {
|
||||||
return AlbumCoverFragment.newInstance(dataSet[position])
|
return dataSet.size
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCount(): Int {
|
override fun instantiateItem(container: ViewGroup, position: Int): Any {
|
||||||
return dataSet.size
|
val o = super.instantiateItem(container, position)
|
||||||
}
|
if (currentColorReceiver != null && currentColorReceiverPosition == position) {
|
||||||
|
receiveColor(currentColorReceiver!!, currentColorReceiverPosition)
|
||||||
|
}
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
override fun instantiateItem(container: ViewGroup, position: Int): Any {
|
/**
|
||||||
val o = super.instantiateItem(container, position)
|
* Only the latest passed [AlbumCoverFragment.ColorReceiver] is guaranteed to receive a
|
||||||
if (currentColorReceiver != null && currentColorReceiverPosition == position) {
|
* response
|
||||||
receiveColor(currentColorReceiver!!, currentColorReceiverPosition)
|
*/
|
||||||
}
|
fun receiveColor(colorReceiver: AlbumCoverFragment.ColorReceiver, position: Int) {
|
||||||
return o
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if (getFragment(position) is AlbumCoverFragment) {
|
||||||
* Only the latest passed [AlbumCoverFragment.ColorReceiver] is guaranteed to receive a
|
val fragment = getFragment(position) as AlbumCoverFragment
|
||||||
* response
|
currentColorReceiver = null
|
||||||
*/
|
currentColorReceiverPosition = -1
|
||||||
fun receiveColor(colorReceiver: AlbumCoverFragment.ColorReceiver, position: Int) {
|
fragment.receiveColor(colorReceiver, position)
|
||||||
|
} else {
|
||||||
|
currentColorReceiver = colorReceiver
|
||||||
|
currentColorReceiverPosition = position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (getFragment(position) is AlbumCoverFragment) {
|
class AlbumCoverFragment : Fragment() {
|
||||||
val fragment = getFragment(position) as AlbumCoverFragment
|
|
||||||
currentColorReceiver = null
|
|
||||||
currentColorReceiverPosition = -1
|
|
||||||
fragment.receiveColor(colorReceiver, position)
|
|
||||||
} else {
|
|
||||||
currentColorReceiver = colorReceiver
|
|
||||||
currentColorReceiverPosition = position
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AlbumCoverFragment : Fragment() {
|
lateinit var albumCover: ImageView
|
||||||
|
private var isColorReady: Boolean = false
|
||||||
|
private var color: Int = 0
|
||||||
|
private lateinit var song: Song
|
||||||
|
private var colorReceiver: ColorReceiver? = null
|
||||||
|
private var request: Int = 0
|
||||||
|
|
||||||
lateinit var albumCover: ImageView
|
private val layout: Int
|
||||||
private var isColorReady: Boolean = false
|
get() {
|
||||||
private var color: Int = 0
|
return when (PreferenceUtil.getInstance(activity).albumCoverStyle) {
|
||||||
private lateinit var song: Song
|
AlbumCoverStyle.NORMAL -> R.layout.fragment_album_cover
|
||||||
private var colorReceiver: ColorReceiver? = null
|
AlbumCoverStyle.FLAT -> R.layout.fragment_album_flat_cover
|
||||||
private var request: Int = 0
|
AlbumCoverStyle.CIRCLE -> R.layout.fragment_album_circle_cover
|
||||||
|
AlbumCoverStyle.CARD -> R.layout.fragment_album_card_cover
|
||||||
|
AlbumCoverStyle.MATERIAL -> R.layout.fragment_album_material_cover
|
||||||
|
AlbumCoverStyle.FULL -> R.layout.fragment_album_full_cover
|
||||||
|
AlbumCoverStyle.FULL_CARD -> R.layout.fragment_album_full_card_cover
|
||||||
|
else -> R.layout.fragment_album_cover
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val layout: Int
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
get() {
|
super.onCreate(savedInstanceState)
|
||||||
return when (PreferenceUtil.getInstance(activity).albumCoverStyle) {
|
if (arguments != null) {
|
||||||
AlbumCoverStyle.NORMAL -> R.layout.fragment_album_cover
|
song = arguments!!.getParcelable(SONG_ARG)!!
|
||||||
AlbumCoverStyle.FLAT -> R.layout.fragment_album_flat_cover
|
}
|
||||||
AlbumCoverStyle.CIRCLE -> R.layout.fragment_album_circle_cover
|
}
|
||||||
AlbumCoverStyle.CARD -> R.layout.fragment_album_card_cover
|
|
||||||
AlbumCoverStyle.MATERIAL -> R.layout.fragment_album_material_cover
|
|
||||||
AlbumCoverStyle.FULL -> R.layout.fragment_album_full_cover
|
|
||||||
AlbumCoverStyle.FULL_CARD -> R.layout.fragment_album_full_card_cover
|
|
||||||
else -> R.layout.fragment_album_cover
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreateView(
|
||||||
super.onCreate(savedInstanceState)
|
inflater: LayoutInflater,
|
||||||
if (arguments != null) {
|
container: ViewGroup?,
|
||||||
song = arguments!!.getParcelable(SONG_ARG)!!
|
savedInstanceState: Bundle?
|
||||||
}
|
): View? {
|
||||||
}
|
val finalLayout = when {
|
||||||
|
PreferenceUtil.getInstance(activity).carouselEffect() -> R.layout.fragment_album_carousel_cover
|
||||||
|
else -> layout
|
||||||
|
}
|
||||||
|
val view = inflater.inflate(finalLayout, container, false)
|
||||||
|
albumCover = view.findViewById(R.id.player_image)
|
||||||
|
albumCover.setOnClickListener {
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
NavigationUtil.goToLyrics(requireActivity())
|
||||||
val finalLayout = when {
|
}
|
||||||
PreferenceUtil.getInstance(activity).carouselEffect() -> R.layout.fragment_album_carousel_cover
|
return view
|
||||||
else -> layout
|
}
|
||||||
}
|
|
||||||
val view = inflater.inflate(finalLayout, container, false)
|
|
||||||
albumCover = view.findViewById(R.id.player_image)
|
|
||||||
albumCover.setOnClickListener {
|
|
||||||
|
|
||||||
NavigationUtil.goToLyrics(requireActivity())
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
}
|
super.onViewCreated(view, savedInstanceState)
|
||||||
return view
|
loadAlbumCover()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onDestroyView() {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onDestroyView()
|
||||||
loadAlbumCover()
|
colorReceiver = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun loadAlbumCover() {
|
||||||
|
SongGlideRequest.Builder.from(Glide.with(requireContext()), song)
|
||||||
|
.checkIgnoreMediaStore(activity).generatePalette(activity).build()
|
||||||
|
.into(object : RetroMusicColoredTarget(albumCover) {
|
||||||
|
override fun onColorReady(color: Int) {
|
||||||
|
setColor(color)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
private fun setColor(color: Int) {
|
||||||
super.onDestroyView()
|
this.color = color
|
||||||
colorReceiver = null
|
isColorReady = true
|
||||||
}
|
if (colorReceiver != null) {
|
||||||
|
colorReceiver!!.onColorReady(color, request)
|
||||||
|
colorReceiver = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun loadAlbumCover() {
|
internal fun receiveColor(colorReceiver: ColorReceiver, request: Int) {
|
||||||
SongGlideRequest.Builder.from(Glide.with(requireContext()), song)
|
if (isColorReady) {
|
||||||
.checkIgnoreMediaStore(activity)
|
colorReceiver.onColorReady(color, request)
|
||||||
.generatePalette(activity).build()
|
} else {
|
||||||
.into(object : RetroMusicColoredTarget(albumCover) {
|
this.colorReceiver = colorReceiver
|
||||||
override fun onColorReady(color: Int) {
|
this.request = request
|
||||||
setColor(color)
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setColor(color: Int) {
|
interface ColorReceiver {
|
||||||
this.color = color
|
fun onColorReady(color: Int, request: Int)
|
||||||
isColorReady = true
|
}
|
||||||
if (colorReceiver != null) {
|
|
||||||
colorReceiver!!.onColorReady(color, request)
|
|
||||||
colorReceiver = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun receiveColor(colorReceiver: ColorReceiver, request: Int) {
|
companion object {
|
||||||
if (isColorReady) {
|
|
||||||
colorReceiver.onColorReady(color, request)
|
|
||||||
} else {
|
|
||||||
this.colorReceiver = colorReceiver
|
|
||||||
this.request = request
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ColorReceiver {
|
private const val SONG_ARG = "song"
|
||||||
fun onColorReady(color: Int, request: Int)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
fun newInstance(song: Song): AlbumCoverFragment {
|
||||||
|
val frag = AlbumCoverFragment()
|
||||||
|
val args = Bundle()
|
||||||
|
args.putParcelable(SONG_ARG, song)
|
||||||
|
frag.arguments = args
|
||||||
|
return frag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private const val SONG_ARG = "song"
|
companion object {
|
||||||
|
val TAG: String = AlbumCoverPagerAdapter::class.java.simpleName
|
||||||
fun newInstance(song: Song): AlbumCoverFragment {
|
}
|
||||||
val frag = AlbumCoverFragment()
|
|
||||||
val args = Bundle()
|
|
||||||
args.putParcelable(SONG_ARG, song)
|
|
||||||
frag.arguments = args
|
|
||||||
return frag
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val TAG: String = AlbumCoverPagerAdapter::class.java.simpleName
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,69 +15,87 @@
|
||||||
*/
|
*/
|
||||||
package code.name.monkey.retromusic.adapter.album
|
package code.name.monkey.retromusic.adapter.album
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.*
|
||||||
import android.app.ActivityOptions
|
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
import code.name.monkey.retromusic.glide.*
|
||||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.model.Album
|
import code.name.monkey.retromusic.model.Album
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
import code.name.monkey.retromusic.util.NavigationUtil
|
||||||
import code.name.monkey.retromusic.views.MetalRecyclerViewPager
|
import code.name.monkey.retromusic.views.MetalRecyclerViewPager
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
|
|
||||||
class AlbumFullWidthAdapter(private val activity: Activity, private val dataSet: ArrayList<Album>, metrics: DisplayMetrics) :
|
class AlbumFullWidthAdapter(
|
||||||
MetalRecyclerViewPager.MetalAdapter<AlbumFullWidthAdapter.FullMetalViewHolder>(metrics) {
|
private val activity: Activity,
|
||||||
|
private val dataSet: ArrayList<Album>,
|
||||||
|
metrics: DisplayMetrics
|
||||||
|
) : MetalRecyclerViewPager.MetalAdapter<AlbumFullWidthAdapter.FullMetalViewHolder>(metrics) {
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FullMetalViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FullMetalViewHolder {
|
||||||
return FullMetalViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.pager_item, parent, false))
|
return FullMetalViewHolder(
|
||||||
}
|
LayoutInflater.from(parent.context).inflate(
|
||||||
|
R.layout.pager_item,
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: FullMetalViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: FullMetalViewHolder, position: Int) {
|
||||||
// don't forget about calling supper.onBindViewHolder!
|
// don't forget about calling supper.onBindViewHolder!
|
||||||
super.onBindViewHolder(holder, position)
|
super.onBindViewHolder(holder, position)
|
||||||
val album = dataSet[position]
|
val album = dataSet[position]
|
||||||
holder.title?.text = getAlbumTitle(album)
|
holder.title?.text = getAlbumTitle(album)
|
||||||
holder.text?.text = getAlbumText(album)
|
holder.text?.text = getAlbumText(album)
|
||||||
holder.playSongs?.setOnClickListener { album.songs?.let { songs -> MusicPlayerRemote.openQueue(songs, 0, true) } }
|
holder.playSongs?.setOnClickListener {
|
||||||
loadAlbumCover(album, holder)
|
album.songs?.let { songs ->
|
||||||
}
|
MusicPlayerRemote.openQueue(
|
||||||
|
songs,
|
||||||
|
0,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadAlbumCover(album, holder)
|
||||||
|
}
|
||||||
|
|
||||||
private fun getAlbumTitle(album: Album): String? {
|
private fun getAlbumTitle(album: Album): String? {
|
||||||
return album.title
|
return album.title
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAlbumText(album: Album): String? {
|
private fun getAlbumText(album: Album): String? {
|
||||||
return album.artistName
|
return album.artistName
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadAlbumCover(album: Album, holder: FullMetalViewHolder) {
|
private fun loadAlbumCover(album: Album, holder: FullMetalViewHolder) {
|
||||||
if (holder.image == null) {
|
if (holder.image == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||||
.checkIgnoreMediaStore(activity)
|
.checkIgnoreMediaStore(activity).generatePalette(activity).build()
|
||||||
.generatePalette(activity).build()
|
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
||||||
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
override fun onColorReady(color: Int) {
|
||||||
override fun onColorReady(color: Int) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return dataSet.size
|
return dataSet.size
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class FullMetalViewHolder(itemView: View) : MetalRecyclerViewPager.MetalViewHolder(itemView) {
|
inner class FullMetalViewHolder(itemView: View) : MetalRecyclerViewPager.MetalViewHolder(
|
||||||
|
itemView
|
||||||
|
) {
|
||||||
|
|
||||||
override fun onClick(v: View?) {
|
override fun onClick(v: View?) {
|
||||||
val activityOptions = ActivityOptions.makeSceneTransitionAnimation(activity, image, activity.getString(R.string.transition_album_art))
|
val activityOptions = ActivityOptions.makeSceneTransitionAnimation(
|
||||||
NavigationUtil.goToAlbumOptions(activity, dataSet[adapterPosition].id, activityOptions)
|
activity,
|
||||||
}
|
image,
|
||||||
}
|
activity.getString(R.string.transition_album_art)
|
||||||
|
)
|
||||||
|
NavigationUtil.goToAlbumOptions(activity, dataSet[adapterPosition].id, activityOptions)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,13 +1,10 @@
|
||||||
package code.name.monkey.retromusic.adapter.album
|
package code.name.monkey.retromusic.adapter.album
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.view.View
|
import android.view.*
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
import code.name.monkey.retromusic.glide.*
|
||||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
|
||||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
|
||||||
import code.name.monkey.retromusic.helper.HorizontalAdapterHelper
|
import code.name.monkey.retromusic.helper.HorizontalAdapterHelper
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.model.Album
|
import code.name.monkey.retromusic.model.Album
|
||||||
|
@ -15,65 +12,71 @@ import code.name.monkey.retromusic.util.MusicUtil
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
class HorizontalAlbumAdapter(
|
class HorizontalAlbumAdapter(
|
||||||
activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
dataSet: ArrayList<Album>,
|
dataSet: ArrayList<Album>,
|
||||||
usePalette: Boolean,
|
usePalette: Boolean,
|
||||||
cabHolder: CabHolder?
|
cabHolder: CabHolder?
|
||||||
) : AlbumAdapter(
|
) : AlbumAdapter(
|
||||||
activity,
|
activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, usePalette, cabHolder
|
||||||
dataSet,
|
|
||||||
HorizontalAdapterHelper.LAYOUT_RES,
|
|
||||||
usePalette,
|
|
||||||
cabHolder
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun createViewHolder(view: View, viewType: Int): ViewHolder {
|
override fun createViewHolder(view: View, viewType: Int): ViewHolder {
|
||||||
val params = view.layoutParams as ViewGroup.MarginLayoutParams
|
val params = view.layoutParams as ViewGroup.MarginLayoutParams
|
||||||
HorizontalAdapterHelper.applyMarginToLayoutParams(activity, params, viewType)
|
HorizontalAdapterHelper.applyMarginToLayoutParams(activity, params, viewType)
|
||||||
return ViewHolder(view)
|
return ViewHolder(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setColors(color: Int, holder: ViewHolder) {
|
override fun setColors(color: Int, holder: ViewHolder) {
|
||||||
holder.title?.setTextColor(MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color)))
|
holder.title?.setTextColor(
|
||||||
holder.text?.setTextColor(MaterialValueHelper.getSecondaryTextColor(activity, ColorUtil.isColorLight(color)))
|
MaterialValueHelper.getPrimaryTextColor(
|
||||||
}
|
activity,
|
||||||
|
ColorUtil.isColorLight(
|
||||||
|
color
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
holder.text?.setTextColor(
|
||||||
|
MaterialValueHelper.getSecondaryTextColor(
|
||||||
|
activity,
|
||||||
|
ColorUtil.isColorLight(
|
||||||
|
color
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun loadAlbumCover(album: Album, holder: ViewHolder) {
|
override fun loadAlbumCover(album: Album, holder: ViewHolder) {
|
||||||
if (holder.image == null) return
|
if (holder.image == null) return
|
||||||
|
|
||||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||||
.checkIgnoreMediaStore(activity)
|
.checkIgnoreMediaStore(activity).generatePalette(activity).build()
|
||||||
.generatePalette(activity).build()
|
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
||||||
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
override fun onLoadCleared(placeholder: Drawable?) {
|
||||||
override fun onLoadCleared(placeholder: Drawable?) {
|
super.onLoadCleared(placeholder)
|
||||||
super.onLoadCleared(placeholder)
|
setColors(albumArtistFooterColor, holder)
|
||||||
setColors(albumArtistFooterColor, holder)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onColorReady(color: Int) {
|
override fun onColorReady(color: Int) {
|
||||||
if (usePalette)
|
if (usePalette) setColors(color, holder)
|
||||||
setColors(color, holder)
|
else setColors(albumArtistFooterColor, holder)
|
||||||
else
|
}
|
||||||
setColors(albumArtistFooterColor, holder)
|
})
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getAlbumText(album: Album): String? {
|
override fun getAlbumText(album: Album): String? {
|
||||||
return MusicUtil.getYearString(album.year)
|
return MusicUtil.getYearString(album.year)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
return HorizontalAdapterHelper.getItemViewtype(position, itemCount)
|
return HorizontalAdapterHelper.getItemViewtype(position, itemCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return dataSet.size
|
return dataSet.size
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val TAG: String = AlbumAdapter::class.java.simpleName
|
val TAG: String = AlbumAdapter::class.java.simpleName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,145 +3,150 @@ package code.name.monkey.retromusic.adapter.artist
|
||||||
import android.app.ActivityOptions
|
import android.app.ActivityOptions
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.annotation.LayoutRes
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
|
import code.name.monkey.retromusic.adapter.base.*
|
||||||
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
import code.name.monkey.retromusic.glide.*
|
||||||
import code.name.monkey.retromusic.glide.ArtistGlideRequest
|
|
||||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
|
||||||
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
|
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.model.Artist
|
import code.name.monkey.retromusic.model.*
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
class ArtistAdapter(
|
||||||
|
val activity: AppCompatActivity,
|
||||||
|
var dataSet: ArrayList<Artist>,
|
||||||
|
var itemLayoutRes: Int,
|
||||||
|
var usePalette: Boolean,
|
||||||
|
cabHolder: CabHolder?
|
||||||
|
) : AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist>(
|
||||||
|
activity, cabHolder, R.menu.menu_media_selection
|
||||||
|
), FastScrollRecyclerView.SectionedAdapter {
|
||||||
|
|
||||||
class ArtistAdapter(val activity: AppCompatActivity,
|
fun swapDataSet(dataSet: ArrayList<Artist>) {
|
||||||
var dataSet: ArrayList<Artist>,
|
this.dataSet = dataSet
|
||||||
@LayoutRes var itemLayoutRes: Int,
|
notifyDataSetChanged()
|
||||||
var usePalette: Boolean,
|
}
|
||||||
cabHolder: CabHolder?
|
|
||||||
) : AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist>(activity, cabHolder, R.menu.menu_media_selection), FastScrollRecyclerView.SectionedAdapter {
|
|
||||||
|
|
||||||
fun swapDataSet(dataSet: ArrayList<Artist>) {
|
fun usePalette(usePalette: Boolean) {
|
||||||
this.dataSet = dataSet
|
this.usePalette = usePalette
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun usePalette(usePalette: Boolean) {
|
override fun getItemId(position: Int): Long {
|
||||||
this.usePalette = usePalette
|
return dataSet[position].id.toLong()
|
||||||
notifyDataSetChanged()
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemId(position: Int): Long {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
return dataSet[position].id.toLong()
|
val view = LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false)
|
||||||
}
|
return createViewHolder(view)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
private fun createViewHolder(view: View): ViewHolder {
|
||||||
val view = LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false)
|
return ViewHolder(view)
|
||||||
return createViewHolder(view)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun createViewHolder(view: View): ViewHolder {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
return ViewHolder(view)
|
val artist = dataSet[position]
|
||||||
}
|
val isChecked = isChecked(artist)
|
||||||
|
holder.itemView.isActivated = isChecked
|
||||||
|
holder.title?.text = artist.name
|
||||||
|
holder.text?.visibility = View.GONE
|
||||||
|
loadArtistImage(artist, holder)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
fun setColors(color: Int, holder: ViewHolder) {
|
||||||
val artist = dataSet[position]
|
if (holder.paletteColorContainer != null) {
|
||||||
val isChecked = isChecked(artist)
|
holder.paletteColorContainer?.setBackgroundColor(color)
|
||||||
holder.itemView.isActivated = isChecked
|
holder.title?.setTextColor(
|
||||||
holder.title?.text = artist.name
|
MaterialValueHelper.getPrimaryTextColor(
|
||||||
holder.text?.visibility = View.GONE
|
activity, ColorUtil.isColorLight(
|
||||||
loadArtistImage(artist, holder)
|
color
|
||||||
}
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun setColors(color: Int, holder: ViewHolder) {
|
holder.mask?.backgroundTintList = ColorStateList.valueOf(color)
|
||||||
if (holder.paletteColorContainer != null) {
|
}
|
||||||
holder.paletteColorContainer?.setBackgroundColor(color)
|
|
||||||
holder.title?.setTextColor(MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color)))
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.mask?.backgroundTintList = ColorStateList.valueOf(color)
|
private fun loadArtistImage(artist: Artist, holder: ViewHolder) {
|
||||||
}
|
if (holder.image == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ArtistGlideRequest.Builder.from(Glide.with(activity), artist).generatePalette(activity)
|
||||||
|
.build().into(object : RetroMusicColoredTarget(holder.image!!) {
|
||||||
|
override fun onLoadCleared(placeholder: Drawable?) {
|
||||||
|
super.onLoadCleared(placeholder)
|
||||||
|
setColors(defaultFooterColor, holder)
|
||||||
|
}
|
||||||
|
|
||||||
private fun loadArtistImage(artist: Artist, holder: ViewHolder) {
|
override fun onColorReady(color: Int) {
|
||||||
if (holder.image == null) {
|
setColors(color, holder)
|
||||||
return
|
}
|
||||||
}
|
})
|
||||||
ArtistGlideRequest.Builder.from(Glide.with(activity), artist)
|
}
|
||||||
.generatePalette(activity).build()
|
|
||||||
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
|
||||||
override fun onLoadCleared(placeholder: Drawable?) {
|
|
||||||
super.onLoadCleared(placeholder)
|
|
||||||
setColors(defaultFooterColor, holder)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onColorReady(color: Int) {
|
override fun getItemCount(): Int {
|
||||||
setColors(color, holder)
|
return dataSet.size
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getIdentifier(position: Int): Artist? {
|
||||||
return dataSet.size
|
return dataSet[position]
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIdentifier(position: Int): Artist? {
|
override fun getName(artist: Artist): String {
|
||||||
return dataSet[position]
|
return artist.name
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(artist: Artist): String {
|
override fun onMultipleItemAction(
|
||||||
return artist.name
|
menuItem: MenuItem, selection: ArrayList<Artist>
|
||||||
}
|
) {
|
||||||
|
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onMultipleItemAction(menuItem: MenuItem,
|
private fun getSongList(artists: List<Artist>): ArrayList<Song> {
|
||||||
selection: ArrayList<Artist>) {
|
val songs = ArrayList<Song>()
|
||||||
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
|
for (artist in artists) {
|
||||||
}
|
songs.addAll(artist.songs) // maybe async in future?
|
||||||
|
}
|
||||||
|
return songs
|
||||||
|
}
|
||||||
|
|
||||||
private fun getSongList(artists: List<Artist>): ArrayList<Song> {
|
override fun getSectionName(position: Int): String {
|
||||||
val songs = ArrayList<Song>()
|
return MusicUtil.getSectionName(dataSet[position].name)
|
||||||
for (artist in artists) {
|
}
|
||||||
songs.addAll(artist.songs) // maybe async in future?
|
|
||||||
}
|
|
||||||
return songs
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getSectionName(position: Int): String {
|
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
||||||
return MusicUtil.getSectionName(dataSet[position].name)
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
init {
|
||||||
|
setImageTransitionName(activity.getString(R.string.transition_artist_image))
|
||||||
|
menu?.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
override fun onClick(v: View?) {
|
||||||
setImageTransitionName(activity.getString(R.string.transition_artist_image))
|
super.onClick(v)
|
||||||
menu?.visibility = View.GONE
|
if (isInQuickSelectMode) {
|
||||||
}
|
toggleChecked(adapterPosition)
|
||||||
|
} else {
|
||||||
|
val activityOptions = ActivityOptions.makeSceneTransitionAnimation(
|
||||||
|
activity, image, activity.getString(
|
||||||
|
R.string.transition_artist_image
|
||||||
|
)
|
||||||
|
)
|
||||||
|
NavigationUtil.goToArtistOptions(
|
||||||
|
activity, dataSet[adapterPosition].id, activityOptions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onClick(v: View?) {
|
override fun onLongClick(v: View?): Boolean {
|
||||||
super.onClick(v)
|
toggleChecked(adapterPosition)
|
||||||
if (isInQuickSelectMode) {
|
return super.onLongClick(v)
|
||||||
toggleChecked(adapterPosition)
|
}
|
||||||
} else {
|
}
|
||||||
val activityOptions = ActivityOptions.makeSceneTransitionAnimation(activity, image, activity.getString(R.string.transition_artist_image))
|
|
||||||
NavigationUtil.goToArtistOptions(activity, dataSet[adapterPosition].id, activityOptions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onLongClick(v: View?): Boolean {
|
|
||||||
toggleChecked(adapterPosition)
|
|
||||||
return super.onLongClick(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package code.name.monkey.retromusic.adapter.base;
|
package code.name.monkey.retromusic.adapter.base;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
|
||||||
import androidx.annotation.MenuRes;
|
import androidx.annotation.MenuRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
|
|
||||||
import com.afollestad.materialcab.MaterialCab;
|
import com.afollestad.materialcab.MaterialCab;
|
||||||
|
|
||||||
|
|
|
@ -1,212 +1,222 @@
|
||||||
package code.name.monkey.retromusic.adapter.playlist
|
package code.name.monkey.retromusic.adapter.playlist
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.TintHelper
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
|
import code.name.monkey.retromusic.adapter.base.*
|
||||||
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
import code.name.monkey.retromusic.dialogs.*
|
||||||
import code.name.monkey.retromusic.dialogs.ClearSmartPlaylistDialog
|
import code.name.monkey.retromusic.helper.menu.*
|
||||||
import code.name.monkey.retromusic.dialogs.DeletePlaylistDialog
|
|
||||||
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
|
|
||||||
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
|
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
|
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
|
||||||
import code.name.monkey.retromusic.model.AbsCustomPlaylist
|
import code.name.monkey.retromusic.model.*
|
||||||
import code.name.monkey.retromusic.model.Playlist
|
import code.name.monkey.retromusic.model.smartplaylist.*
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist
|
|
||||||
import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist
|
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
class PlaylistAdapter(
|
||||||
|
private val activity: AppCompatActivity,
|
||||||
|
var dataSet: ArrayList<Playlist>,
|
||||||
|
private var itemLayoutRes: Int,
|
||||||
|
cabHolder: CabHolder?
|
||||||
|
) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist>(
|
||||||
|
activity,
|
||||||
|
cabHolder,
|
||||||
|
R.menu.menu_playlists_selection
|
||||||
|
) {
|
||||||
|
|
||||||
class PlaylistAdapter(private val activity: AppCompatActivity,
|
var songs = ArrayList<Song>()
|
||||||
var dataSet: ArrayList<Playlist>,
|
|
||||||
private var itemLayoutRes: Int,
|
|
||||||
cabHolder: CabHolder?) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist>(activity, cabHolder, R.menu.menu_playlists_selection) {
|
|
||||||
|
|
||||||
var songs = ArrayList<Song>()
|
init {
|
||||||
|
setHasStableIds(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun swapDataSet(dataSet: ArrayList<Playlist>) {
|
||||||
|
this.dataSet = dataSet
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
override fun getItemId(position: Int): Long {
|
||||||
setHasStableIds(true)
|
return dataSet[position].id.toLong()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun swapDataSet(dataSet: ArrayList<Playlist>) {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
this.dataSet = dataSet
|
val view = LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false)
|
||||||
notifyDataSetChanged()
|
return createViewHolder(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemId(position: Int): Long {
|
protected fun createViewHolder(view: View): ViewHolder {
|
||||||
return dataSet[position].id.toLong()
|
return ViewHolder(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
protected fun getPlaylistTitle(playlist: Playlist): String {
|
||||||
val view = LayoutInflater.from(activity)
|
return playlist.name
|
||||||
.inflate(itemLayoutRes, parent, false)
|
}
|
||||||
return createViewHolder(view)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun createViewHolder(view: View): ViewHolder {
|
protected fun getPlaylistText(playlist: Playlist): String {
|
||||||
return ViewHolder(view)
|
return MusicUtil.getPlaylistInfoString(activity, getSongs(playlist))
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun getPlaylistTitle(playlist: Playlist): String {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
return playlist.name
|
val playlist = dataSet[position]
|
||||||
}
|
holder.itemView.isActivated = isChecked(playlist)
|
||||||
|
holder.title?.text = getPlaylistTitle(playlist)
|
||||||
|
holder.text?.text = getPlaylistText(playlist)
|
||||||
|
holder.image?.setImageDrawable(getIconRes(playlist))
|
||||||
|
}
|
||||||
|
|
||||||
protected fun getPlaylistText(playlist: Playlist): String {
|
private fun getIconRes(playlist: Playlist): Drawable {
|
||||||
return MusicUtil.getPlaylistInfoString(activity, getSongs(playlist))
|
if (playlist is AbsSmartPlaylist) {
|
||||||
}
|
return TintHelper.createTintedDrawable(
|
||||||
|
activity,
|
||||||
|
playlist.iconRes,
|
||||||
|
ATHUtil.resolveColor(activity, R.attr.iconColor)
|
||||||
|
)!!
|
||||||
|
}
|
||||||
|
return if (MusicUtil.isFavoritePlaylist(
|
||||||
|
activity,
|
||||||
|
playlist
|
||||||
|
)) TintHelper.createTintedDrawable(
|
||||||
|
activity,
|
||||||
|
R.drawable.ic_favorite_white_24dp,
|
||||||
|
ThemeStore.accentColor(activity)
|
||||||
|
)!!
|
||||||
|
else TintHelper.createTintedDrawable(
|
||||||
|
activity,
|
||||||
|
R.drawable.ic_playlist_play_white_24dp,
|
||||||
|
ATHUtil.resolveColor(activity, R.attr.iconColor)
|
||||||
|
)!!
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun getItemViewType(position: Int): Int {
|
||||||
val playlist = dataSet[position]
|
return if (dataSet[position] is AbsSmartPlaylist) SMART_PLAYLIST else DEFAULT_PLAYLIST
|
||||||
holder.itemView.isActivated = isChecked(playlist)
|
}
|
||||||
holder.title?.text = getPlaylistTitle(playlist)
|
|
||||||
holder.text?.text = getPlaylistText(playlist)
|
|
||||||
holder.image?.setImageDrawable(getIconRes(playlist))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getIconRes(playlist: Playlist): Drawable {
|
override fun getItemCount(): Int {
|
||||||
if (playlist is AbsSmartPlaylist) {
|
return dataSet.size
|
||||||
return TintHelper.createTintedDrawable(activity, playlist.iconRes, ATHUtil.resolveColor(activity, R.attr.iconColor))!!
|
}
|
||||||
}
|
|
||||||
return if (MusicUtil.isFavoritePlaylist(activity, playlist))
|
|
||||||
TintHelper.createTintedDrawable(activity, R.drawable.ic_favorite_white_24dp, ThemeStore.accentColor(activity))!!
|
|
||||||
else
|
|
||||||
TintHelper.createTintedDrawable(activity, R.drawable.ic_playlist_play_white_24dp, ATHUtil.resolveColor(activity, R.attr.iconColor))!!
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getIdentifier(position: Int): Playlist? {
|
||||||
return if (dataSet[position] is AbsSmartPlaylist) SMART_PLAYLIST else DEFAULT_PLAYLIST
|
return dataSet[position]
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getName(playlist: Playlist): String {
|
||||||
return dataSet.size
|
return playlist.name
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIdentifier(position: Int): Playlist? {
|
override fun onMultipleItemAction(menuItem: MenuItem, selection: ArrayList<Playlist>) {
|
||||||
return dataSet[position]
|
when (menuItem.itemId) {
|
||||||
}
|
R.id.action_delete_playlist -> {
|
||||||
|
var i = 0
|
||||||
|
while (i < selection.size) {
|
||||||
|
val playlist = selection[i]
|
||||||
|
if (playlist is AbsSmartPlaylist) {
|
||||||
|
ClearSmartPlaylistDialog.create(playlist).show(
|
||||||
|
activity.supportFragmentManager, "CLEAR_PLAYLIST_" + playlist.name
|
||||||
|
)
|
||||||
|
selection.remove(playlist)
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if (selection.size > 0) {
|
||||||
|
DeletePlaylistDialog.create(selection)
|
||||||
|
.show(activity.supportFragmentManager, "DELETE_PLAYLIST")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> SongsMenuHelper.handleMenuClick(
|
||||||
|
activity,
|
||||||
|
getSongList(selection),
|
||||||
|
menuItem.itemId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun getName(playlist: Playlist): String {
|
private fun getSongList(playlists: List<Playlist>): ArrayList<Song> {
|
||||||
return playlist.name
|
val songs = ArrayList<Song>()
|
||||||
}
|
for (playlist in playlists) {
|
||||||
|
if (playlist is AbsCustomPlaylist) {
|
||||||
|
songs.addAll(playlist.getSongs(activity))
|
||||||
|
} else {
|
||||||
|
songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return songs
|
||||||
|
}
|
||||||
|
|
||||||
override fun onMultipleItemAction(menuItem: MenuItem, selection: ArrayList<Playlist>) {
|
private fun getSongs(playlist: Playlist): ArrayList<Song> {
|
||||||
when (menuItem.itemId) {
|
val songs = ArrayList<Song>()
|
||||||
R.id.action_delete_playlist -> {
|
if (playlist is AbsSmartPlaylist) {
|
||||||
var i = 0
|
songs.addAll(playlist.getSongs(activity))
|
||||||
while (i < selection.size) {
|
} else {
|
||||||
val playlist = selection[i]
|
songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id))
|
||||||
if (playlist is AbsSmartPlaylist) {
|
}
|
||||||
ClearSmartPlaylistDialog.create(playlist)
|
return songs
|
||||||
.show(activity.supportFragmentManager,
|
}
|
||||||
"CLEAR_PLAYLIST_" + playlist.name)
|
|
||||||
selection.remove(playlist)
|
|
||||||
i--
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if (selection.size > 0) {
|
|
||||||
DeletePlaylistDialog.create(selection)
|
|
||||||
.show(activity.supportFragmentManager, "DELETE_PLAYLIST")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.itemId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getSongList(playlists: List<Playlist>): ArrayList<Song> {
|
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
||||||
val songs = ArrayList<Song>()
|
init {
|
||||||
for (playlist in playlists) {
|
|
||||||
if (playlist is AbsCustomPlaylist) {
|
|
||||||
songs.addAll(playlist.getSongs(activity))
|
|
||||||
} else {
|
|
||||||
songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return songs
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getSongs(playlist: Playlist): ArrayList<Song> {
|
image?.apply {
|
||||||
val songs = ArrayList<Song>()
|
val iconPadding = activity.resources.getDimensionPixelSize(R.dimen.list_item_image_icon_padding)
|
||||||
if (playlist is AbsSmartPlaylist) {
|
setPadding(iconPadding, iconPadding, iconPadding, iconPadding)
|
||||||
songs.addAll(playlist.getSongs(activity))
|
//setColorFilter(ATHUtil.resolveColor(activity, R.attr.iconColor), PorterDuff.Mode.SRC_IN)
|
||||||
} else {
|
}
|
||||||
songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id))
|
|
||||||
}
|
|
||||||
return songs
|
|
||||||
}
|
|
||||||
|
|
||||||
|
menu?.setOnClickListener { view ->
|
||||||
|
val playlist = dataSet[adapterPosition]
|
||||||
|
val popupMenu = PopupMenu(activity, view)
|
||||||
|
popupMenu.inflate(
|
||||||
|
if (itemViewType == SMART_PLAYLIST) R.menu.menu_item_smart_playlist
|
||||||
|
else R.menu.menu_item_playlist
|
||||||
|
)
|
||||||
|
if (playlist is LastAddedPlaylist) {
|
||||||
|
popupMenu.menu.findItem(R.id.action_clear_playlist).isVisible = false
|
||||||
|
}
|
||||||
|
popupMenu.setOnMenuItemClickListener { item ->
|
||||||
|
if (item.itemId == R.id.action_clear_playlist) {
|
||||||
|
if (playlist is AbsSmartPlaylist) {
|
||||||
|
ClearSmartPlaylistDialog.create(playlist).show(
|
||||||
|
activity.supportFragmentManager,
|
||||||
|
"CLEAR_SMART_PLAYLIST_" + playlist.name
|
||||||
|
)
|
||||||
|
return@setOnMenuItemClickListener true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlaylistMenuHelper.handleMenuClick(
|
||||||
|
activity, dataSet[adapterPosition], item
|
||||||
|
)
|
||||||
|
}
|
||||||
|
popupMenu.show()
|
||||||
|
}
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
imageTextContainer?.apply {
|
||||||
init {
|
cardElevation = 0f
|
||||||
|
setCardBackgroundColor(ATHUtil.resolveColor(activity, R.attr.colorPrimary))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
image?.apply {
|
override fun onClick(v: View?) {
|
||||||
val iconPadding = activity.resources.getDimensionPixelSize(R.dimen.list_item_image_icon_padding)
|
if (isInQuickSelectMode) {
|
||||||
setPadding(iconPadding, iconPadding, iconPadding, iconPadding)
|
toggleChecked(adapterPosition)
|
||||||
//setColorFilter(ATHUtil.resolveColor(activity, R.attr.iconColor), PorterDuff.Mode.SRC_IN)
|
} else {
|
||||||
}
|
val playlist = dataSet[adapterPosition]
|
||||||
|
NavigationUtil.goToPlaylistNew(activity, playlist)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
menu?.setOnClickListener { view ->
|
override fun onLongClick(v: View?): Boolean {
|
||||||
val playlist = dataSet[adapterPosition]
|
toggleChecked(adapterPosition)
|
||||||
val popupMenu = PopupMenu(activity, view)
|
return true
|
||||||
popupMenu.inflate(if (itemViewType == SMART_PLAYLIST)
|
}
|
||||||
R.menu.menu_item_smart_playlist
|
}
|
||||||
else
|
|
||||||
R.menu.menu_item_playlist)
|
|
||||||
if (playlist is LastAddedPlaylist) {
|
|
||||||
popupMenu.menu.findItem(R.id.action_clear_playlist).isVisible = false
|
|
||||||
}
|
|
||||||
popupMenu.setOnMenuItemClickListener { item ->
|
|
||||||
if (item.itemId == R.id.action_clear_playlist) {
|
|
||||||
if (playlist is AbsSmartPlaylist) {
|
|
||||||
ClearSmartPlaylistDialog.create(playlist)
|
|
||||||
.show(activity.supportFragmentManager,
|
|
||||||
"CLEAR_SMART_PLAYLIST_" + playlist.name)
|
|
||||||
return@setOnMenuItemClickListener true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PlaylistMenuHelper.handleMenuClick(
|
|
||||||
activity, dataSet[adapterPosition], item)
|
|
||||||
}
|
|
||||||
popupMenu.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
imageTextContainer?.apply {
|
companion object {
|
||||||
cardElevation = 0f
|
val TAG: String = PlaylistAdapter::class.java.simpleName
|
||||||
setCardBackgroundColor(ATHUtil.resolveColor(activity, R.attr.colorPrimary))
|
private const val SMART_PLAYLIST = 0
|
||||||
}
|
private const val DEFAULT_PLAYLIST = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClick(v: View?) {
|
|
||||||
if (isInQuickSelectMode) {
|
|
||||||
toggleChecked(adapterPosition)
|
|
||||||
} else {
|
|
||||||
val playlist = dataSet[adapterPosition]
|
|
||||||
NavigationUtil.goToPlaylistNew(activity, playlist)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onLongClick(v: View?): Boolean {
|
|
||||||
toggleChecked(adapterPosition)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val TAG: String = PlaylistAdapter::class.java.simpleName
|
|
||||||
private const val SMART_PLAYLIST = 0
|
|
||||||
private const val DEFAULT_PLAYLIST = 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package code.name.monkey.retromusic.adapter.song
|
package code.name.monkey.retromusic.adapter.song
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.annotation.LayoutRes
|
import androidx.annotation.LayoutRes
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
|
@ -11,75 +9,87 @@ import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
abstract class AbsOffsetSongAdapter : SongAdapter {
|
abstract class AbsOffsetSongAdapter : SongAdapter {
|
||||||
|
|
||||||
constructor(activity: AppCompatActivity, dataSet: ArrayList<Song>, @LayoutRes itemLayoutRes: Int, usePalette: Boolean, cabHolder: CabHolder?) : super(activity, dataSet, itemLayoutRes, usePalette, cabHolder)
|
constructor(
|
||||||
|
activity: AppCompatActivity,
|
||||||
|
dataSet: ArrayList<Song>, @LayoutRes itemLayoutRes: Int,
|
||||||
|
usePalette: Boolean,
|
||||||
|
cabHolder: CabHolder?
|
||||||
|
) : super(activity, dataSet, itemLayoutRes, usePalette, cabHolder)
|
||||||
|
|
||||||
constructor(activity: AppCompatActivity, dataSet: ArrayList<Song>, @LayoutRes itemLayoutRes: Int, usePalette: Boolean, cabHolder: CabHolder?, showSectionName: Boolean) : super(activity, dataSet, itemLayoutRes, usePalette, cabHolder, showSectionName) {}
|
constructor(
|
||||||
|
activity: AppCompatActivity,
|
||||||
|
dataSet: ArrayList<Song>, @LayoutRes itemLayoutRes: Int,
|
||||||
|
usePalette: Boolean,
|
||||||
|
cabHolder: CabHolder?,
|
||||||
|
showSectionName: Boolean
|
||||||
|
) : super(activity, dataSet, itemLayoutRes, usePalette, cabHolder, showSectionName) {
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongAdapter.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongAdapter.ViewHolder {
|
||||||
if (viewType == OFFSET_ITEM) {
|
if (viewType == OFFSET_ITEM) {
|
||||||
val view = LayoutInflater.from(activity).inflate(R.layout.item_list_quick_actions, parent, false)
|
val view = LayoutInflater.from(activity)
|
||||||
return createViewHolder(view)
|
.inflate(R.layout.item_list_quick_actions, parent, false)
|
||||||
}
|
return createViewHolder(view)
|
||||||
return super.onCreateViewHolder(parent, viewType)
|
}
|
||||||
}
|
return super.onCreateViewHolder(parent, viewType)
|
||||||
|
}
|
||||||
|
|
||||||
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
||||||
return ViewHolder(view)
|
return ViewHolder(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemId(position: Int): Long {
|
override fun getItemId(position: Int): Long {
|
||||||
var positionFinal = position
|
var positionFinal = position
|
||||||
positionFinal--
|
positionFinal--
|
||||||
return if (positionFinal < 0) -2 else super.getItemId(positionFinal)
|
return if (positionFinal < 0) -2 else super.getItemId(positionFinal)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIdentifier(position: Int): Song? {
|
override fun getIdentifier(position: Int): Song? {
|
||||||
var positionFinal = position
|
var positionFinal = position
|
||||||
positionFinal--
|
positionFinal--
|
||||||
return if (positionFinal < 0) null else super.getIdentifier(positionFinal)
|
return if (positionFinal < 0) null else super.getIdentifier(positionFinal)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
val superItemCount = super.getItemCount()
|
val superItemCount = super.getItemCount()
|
||||||
return if (superItemCount == 0) 0 else superItemCount + 1
|
return if (superItemCount == 0) 0 else superItemCount + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
return if (position == 0) OFFSET_ITEM else SONG
|
return if (position == 0) OFFSET_ITEM else SONG
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSectionName(position: Int): String {
|
override fun getSectionName(position: Int): String {
|
||||||
var positionF = position
|
var positionF = position
|
||||||
positionF--
|
positionF--
|
||||||
return if (positionF < 0) "" else super.getSectionName(positionF)
|
return if (positionF < 0) "" else super.getSectionName(positionF)
|
||||||
}
|
}
|
||||||
|
|
||||||
open inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) {
|
open inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) {
|
||||||
|
|
||||||
override// could also return null, just to be safe return empty song
|
override // could also return null, just to be safe return empty song
|
||||||
val song: Song
|
val song: Song
|
||||||
get() = if (itemViewType == OFFSET_ITEM) Song.emptySong else dataSet[adapterPosition - 1]
|
get() = if (itemViewType == OFFSET_ITEM) Song.emptySong else dataSet[adapterPosition - 1]
|
||||||
|
|
||||||
override fun onClick(v: View?) {
|
override fun onClick(v: View?) {
|
||||||
if (isInQuickSelectMode && itemViewType != OFFSET_ITEM) {
|
if (isInQuickSelectMode && itemViewType != OFFSET_ITEM) {
|
||||||
toggleChecked(adapterPosition)
|
toggleChecked(adapterPosition)
|
||||||
} else {
|
} else {
|
||||||
MusicPlayerRemote.openQueue(dataSet, adapterPosition - 1, true)
|
MusicPlayerRemote.openQueue(dataSet, adapterPosition - 1, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLongClick(v: View?): Boolean {
|
override fun onLongClick(v: View?): Boolean {
|
||||||
if (itemViewType == OFFSET_ITEM) return false
|
if (itemViewType == OFFSET_ITEM) return false
|
||||||
toggleChecked(adapterPosition)
|
toggleChecked(adapterPosition)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val OFFSET_ITEM = 0
|
const val OFFSET_ITEM = 0
|
||||||
const val SONG = 1
|
const val SONG = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,133 +1,134 @@
|
||||||
package code.name.monkey.retromusic.adapter.song
|
package code.name.monkey.retromusic.adapter.song
|
||||||
|
|
||||||
import android.view.MenuItem
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import androidx.annotation.LayoutRes
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.dialogs.RemoveFromPlaylistDialog
|
import code.name.monkey.retromusic.dialogs.RemoveFromPlaylistDialog
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.model.PlaylistSong
|
import code.name.monkey.retromusic.model.*
|
||||||
import code.name.monkey.retromusic.model.Song
|
|
||||||
import code.name.monkey.retromusic.util.ViewUtil
|
import code.name.monkey.retromusic.util.ViewUtil
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter
|
import com.h6ah4i.android.widget.advrecyclerview.draggable.*
|
||||||
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 com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags
|
||||||
|
|
||||||
|
class OrderablePlaylistSongAdapter(
|
||||||
|
activity: AppCompatActivity,
|
||||||
|
dataSet: ArrayList<Song>,
|
||||||
|
itemLayoutRes: Int,
|
||||||
|
usePalette: Boolean,
|
||||||
|
cabHolder: CabHolder?,
|
||||||
|
private val onMoveItemListener: OnMoveItemListener?
|
||||||
|
) : PlaylistSongAdapter(
|
||||||
|
activity, dataSet, itemLayoutRes, usePalette, cabHolder
|
||||||
|
), DraggableItemAdapter<OrderablePlaylistSongAdapter.ViewHolder> {
|
||||||
|
|
||||||
class OrderablePlaylistSongAdapter(activity: AppCompatActivity,
|
init {
|
||||||
dataSet: ArrayList<Song>,
|
setMultiSelectMenuRes(code.name.monkey.retromusic.R.menu.menu_playlists_songs_selection)
|
||||||
@LayoutRes itemLayoutRes: Int,
|
}
|
||||||
usePalette: Boolean,
|
|
||||||
cabHolder: CabHolder?,
|
|
||||||
private val onMoveItemListener: OnMoveItemListener?) : PlaylistSongAdapter(activity, dataSet, itemLayoutRes, usePalette, cabHolder), DraggableItemAdapter<OrderablePlaylistSongAdapter.ViewHolder> {
|
|
||||||
|
|
||||||
init {
|
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
||||||
setMultiSelectMenuRes(code.name.monkey.retromusic.R.menu.menu_playlists_songs_selection)
|
return ViewHolder(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
override fun getItemId(position: Int): Long {
|
||||||
return ViewHolder(view)
|
var positionFinal = position
|
||||||
}
|
positionFinal--
|
||||||
|
|
||||||
override fun getItemId(position: Int): Long {
|
var long: Long = 0
|
||||||
var positionFinal = position
|
if (positionFinal < 0) {
|
||||||
positionFinal--
|
long = -2
|
||||||
|
} else {
|
||||||
|
if (dataSet[positionFinal] is PlaylistSong) {
|
||||||
|
long = (dataSet[positionFinal] as PlaylistSong).idInPlayList.toLong()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return long
|
||||||
|
}
|
||||||
|
|
||||||
var long: Long = 0
|
override fun onMultipleItemAction(menuItem: MenuItem, selection: ArrayList<Song>) {
|
||||||
if (positionFinal < 0) {
|
when (menuItem.itemId) {
|
||||||
long = -2
|
R.id.action_remove_from_playlist -> {
|
||||||
} else {
|
RemoveFromPlaylistDialog.create(selection as ArrayList<PlaylistSong>)
|
||||||
if (dataSet[positionFinal] is PlaylistSong) {
|
.show(activity.supportFragmentManager, "ADD_PLAYLIST")
|
||||||
long = (dataSet[positionFinal] as PlaylistSong).idInPlayList.toLong()
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return long
|
super.onMultipleItemAction(menuItem, selection)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMultipleItemAction(menuItem: MenuItem, selection: ArrayList<Song>) {
|
override fun onCheckCanStartDrag(holder: ViewHolder, position: Int, x: Int, y: Int): Boolean {
|
||||||
when (menuItem.itemId) {
|
return onMoveItemListener != null && position > 0 && (ViewUtil.hitTest(
|
||||||
R.id.action_remove_from_playlist -> {
|
holder.dragView!!, x, y
|
||||||
RemoveFromPlaylistDialog.create(selection as ArrayList<PlaylistSong>).show(activity.supportFragmentManager, "ADD_PLAYLIST")
|
) || ViewUtil.hitTest(holder.image!!, x, y))
|
||||||
return
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
super.onMultipleItemAction(menuItem, selection)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCheckCanStartDrag(holder: ViewHolder, position: Int, x: Int, y: Int): Boolean {
|
override fun onGetItemDraggableRange(holder: ViewHolder, position: Int): ItemDraggableRange {
|
||||||
return onMoveItemListener != null && position > 0 &&
|
return ItemDraggableRange(1, dataSet.size)
|
||||||
(ViewUtil.hitTest(holder.dragView!!, x, y) || ViewUtil.hitTest(holder.image!!, x, y))
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onGetItemDraggableRange(holder: ViewHolder, position: Int): ItemDraggableRange {
|
override fun onMoveItem(fromPosition: Int, toPosition: Int) {
|
||||||
return ItemDraggableRange(1, dataSet.size)
|
if (onMoveItemListener != null && fromPosition != toPosition) {
|
||||||
}
|
onMoveItemListener.onMoveItem(fromPosition - 1, toPosition - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onMoveItem(fromPosition: Int, toPosition: Int) {
|
override fun onCheckCanDrop(draggingPosition: Int, dropPosition: Int): Boolean {
|
||||||
if (onMoveItemListener != null && fromPosition != toPosition) {
|
return dropPosition > 0
|
||||||
onMoveItemListener.onMoveItem(fromPosition - 1, toPosition - 1)
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCheckCanDrop(draggingPosition: Int, dropPosition: Int): Boolean {
|
override fun onItemDragStarted(position: Int) {
|
||||||
return dropPosition > 0
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemDragStarted(position: Int) {
|
override fun onItemDragFinished(fromPosition: Int, toPosition: Int, result: Boolean) {
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemDragFinished(fromPosition: Int, toPosition: Int, result: Boolean) {
|
interface OnMoveItemListener {
|
||||||
notifyDataSetChanged()
|
fun onMoveItem(fromPosition: Int, toPosition: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OnMoveItemListener {
|
inner class ViewHolder(itemView: View) : PlaylistSongAdapter.ViewHolder(itemView), DraggableItemViewHolder {
|
||||||
fun onMoveItem(fromPosition: Int, toPosition: Int)
|
@DraggableItemStateFlags
|
||||||
}
|
private var mDragStateFlags: Int = 0
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : PlaylistSongAdapter.ViewHolder(itemView), DraggableItemViewHolder {
|
override var songMenuRes: Int
|
||||||
@DraggableItemStateFlags
|
get() = code.name.monkey.retromusic.R.menu.menu_item_playlist_song
|
||||||
private var mDragStateFlags: Int = 0
|
set(value) {
|
||||||
|
super.songMenuRes = value
|
||||||
|
}
|
||||||
|
|
||||||
override var songMenuRes: Int
|
init {
|
||||||
get() = code.name.monkey.retromusic.R.menu.menu_item_playlist_song
|
if (dragView != null) {
|
||||||
set(value) {
|
if (onMoveItemListener != null) {
|
||||||
super.songMenuRes = value
|
dragView?.visibility = View.VISIBLE
|
||||||
}
|
} else {
|
||||||
|
dragView?.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
override fun onSongMenuItemClick(item: MenuItem): Boolean {
|
||||||
if (dragView != null) {
|
when (item.itemId) {
|
||||||
if (onMoveItemListener != null) {
|
code.name.monkey.retromusic.R.id.action_remove_from_playlist -> {
|
||||||
dragView?.visibility = View.VISIBLE
|
RemoveFromPlaylistDialog.create(song as PlaylistSong)
|
||||||
} else {
|
.show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST")
|
||||||
dragView?.visibility = View.GONE
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return super.onSongMenuItemClick(item)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onSongMenuItemClick(item: MenuItem): Boolean {
|
@DraggableItemStateFlags
|
||||||
when (item.itemId) {
|
override fun getDragStateFlags(): Int {
|
||||||
code.name.monkey.retromusic.R.id.action_remove_from_playlist -> {
|
return mDragStateFlags
|
||||||
RemoveFromPlaylistDialog.create(song as PlaylistSong).show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST")
|
}
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onSongMenuItemClick(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
@DraggableItemStateFlags
|
override fun setDragStateFlags(@DraggableItemStateFlags flags: Int) {
|
||||||
override fun getDragStateFlags(): Int {
|
mDragStateFlags = flags
|
||||||
return mDragStateFlags
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setDragStateFlags(@DraggableItemStateFlags flags: Int) {
|
companion object {
|
||||||
mDragStateFlags = flags
|
val TAG: String = OrderablePlaylistSongAdapter::class.java.simpleName
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val TAG: String = OrderablePlaylistSongAdapter::class.java.simpleName
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,171 +1,167 @@
|
||||||
package code.name.monkey.retromusic.adapter.song
|
package code.name.monkey.retromusic.adapter.song
|
||||||
|
|
||||||
import android.graphics.Color
|
import android.graphics.*
|
||||||
import android.graphics.PorterDuff
|
import android.view.*
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.ViewUtil
|
import com.h6ah4i.android.widget.advrecyclerview.draggable.*
|
||||||
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 com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
class PlayingQueueAdapter(
|
||||||
class PlayingQueueAdapter(activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
dataSet: ArrayList<Song>,
|
dataSet: ArrayList<Song>,
|
||||||
private var current: Int,
|
private var current: Int,
|
||||||
itemLayoutRes: Int) : SongAdapter(
|
itemLayoutRes: Int
|
||||||
activity,
|
) : SongAdapter(
|
||||||
dataSet,
|
activity, dataSet, itemLayoutRes, false, null
|
||||||
itemLayoutRes,
|
|
||||||
false,
|
|
||||||
null
|
|
||||||
), DraggableItemAdapter<PlayingQueueAdapter.ViewHolder> {
|
), DraggableItemAdapter<PlayingQueueAdapter.ViewHolder> {
|
||||||
|
|
||||||
private var color = -1
|
private var color = -1
|
||||||
|
|
||||||
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
||||||
return ViewHolder(view)
|
return ViewHolder(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
|
||||||
super.onBindViewHolder(holder, position)
|
super.onBindViewHolder(holder, position)
|
||||||
holder.imageText?.text = (position - current).toString()
|
holder.imageText?.text = (position - current).toString()
|
||||||
holder.time?.text = MusicUtil.getReadableDurationString(dataSet[position].duration)
|
holder.time?.text = MusicUtil.getReadableDurationString(dataSet[position].duration)
|
||||||
if (holder.itemViewType == HISTORY || holder.itemViewType == CURRENT) {
|
if (holder.itemViewType == HISTORY || holder.itemViewType == CURRENT) {
|
||||||
setAlpha(holder, 0.5f)
|
setAlpha(holder, 0.5f)
|
||||||
}
|
}
|
||||||
if (usePalette) {
|
if (usePalette) {
|
||||||
setColor(holder, Color.WHITE)
|
setColor(holder, Color.WHITE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setColor(holder: SongAdapter.ViewHolder, white: Int) {
|
private fun setColor(holder: SongAdapter.ViewHolder, white: Int) {
|
||||||
|
|
||||||
if (holder.title != null) {
|
if (holder.title != null) {
|
||||||
holder.title!!.setTextColor(white)
|
holder.title!!.setTextColor(white)
|
||||||
if (color != -1) {
|
if (color != -1) {
|
||||||
holder.title!!.setTextColor(color)
|
holder.title!!.setTextColor(color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.text?.setTextColor(white)
|
holder.text?.setTextColor(white)
|
||||||
holder.time?.setTextColor(white)
|
holder.time?.setTextColor(white)
|
||||||
holder.imageText?.setTextColor(white)
|
holder.imageText?.setTextColor(white)
|
||||||
if (holder.menu != null) {
|
if (holder.menu != null) {
|
||||||
(holder.menu as ImageView).setColorFilter(white, PorterDuff.Mode.SRC_IN)
|
(holder.menu as ImageView).setColorFilter(white, PorterDuff.Mode.SRC_IN)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun usePalette(usePalette: Boolean) {
|
override fun usePalette(usePalette: Boolean) {
|
||||||
super.usePalette(usePalette)
|
super.usePalette(usePalette)
|
||||||
this.usePalette = usePalette
|
this.usePalette = usePalette
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
if (position < current) {
|
if (position < current) {
|
||||||
return HISTORY
|
return HISTORY
|
||||||
} else if (position > current) {
|
} else if (position > current) {
|
||||||
return UP_NEXT
|
return UP_NEXT
|
||||||
}
|
}
|
||||||
return CURRENT
|
return CURRENT
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadAlbumCover(song: Song, holder: SongAdapter.ViewHolder) {
|
override fun loadAlbumCover(song: Song, holder: SongAdapter.ViewHolder) {
|
||||||
// We don't want to load it in this adapter
|
// We don't want to load it in this adapter
|
||||||
}
|
}
|
||||||
|
|
||||||
fun swapDataSet(dataSet: ArrayList<Song>, position: Int) {
|
fun swapDataSet(dataSet: ArrayList<Song>, position: Int) {
|
||||||
this.dataSet = dataSet
|
this.dataSet = dataSet
|
||||||
current = position
|
current = position
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setCurrent(current: Int) {
|
fun setCurrent(current: Int) {
|
||||||
this.current = current
|
this.current = current
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setAlpha(holder: SongAdapter.ViewHolder, alpha: Float) {
|
private fun setAlpha(holder: SongAdapter.ViewHolder, alpha: Float) {
|
||||||
holder.image?.alpha = alpha
|
holder.image?.alpha = alpha
|
||||||
holder.title?.alpha = alpha
|
holder.title?.alpha = alpha
|
||||||
holder.text?.alpha = alpha
|
holder.text?.alpha = alpha
|
||||||
holder.imageText?.alpha = alpha
|
holder.imageText?.alpha = alpha
|
||||||
holder.paletteColorContainer?.alpha = alpha
|
holder.paletteColorContainer?.alpha = alpha
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCheckCanStartDrag(holder: ViewHolder, position: Int, x: Int, y: Int): Boolean {
|
override fun onCheckCanStartDrag(holder: ViewHolder, position: Int, x: Int, y: Int): Boolean {
|
||||||
return ViewUtil.hitTest(holder.imageText!!, x, y) || ViewUtil.hitTest(holder.dragView!!, x, y)
|
return ViewUtil.hitTest(holder.imageText!!, x, y) || ViewUtil.hitTest(
|
||||||
}
|
holder.dragView!!,
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onGetItemDraggableRange(holder: ViewHolder, position: Int): ItemDraggableRange? {
|
override fun onGetItemDraggableRange(holder: ViewHolder, position: Int): ItemDraggableRange? {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMoveItem(fromPosition: Int, toPosition: Int) {
|
override fun onMoveItem(fromPosition: Int, toPosition: Int) {
|
||||||
MusicPlayerRemote.moveSong(fromPosition, toPosition)
|
MusicPlayerRemote.moveSong(fromPosition, toPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCheckCanDrop(draggingPosition: Int, dropPosition: Int): Boolean {
|
override fun onCheckCanDrop(draggingPosition: Int, dropPosition: Int): Boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemDragStarted(position: Int) {
|
override fun onItemDragStarted(position: Int) {
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemDragFinished(fromPosition: Int, toPosition: Int, result: Boolean) {
|
override fun onItemDragFinished(fromPosition: Int, toPosition: Int, result: Boolean) {
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView), DraggableItemViewHolder {
|
inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView), DraggableItemViewHolder {
|
||||||
|
|
||||||
@DraggableItemStateFlags
|
@DraggableItemStateFlags
|
||||||
private var mDragStateFlags: Int = 0
|
private var mDragStateFlags: Int = 0
|
||||||
|
|
||||||
override var songMenuRes: Int
|
override var songMenuRes: Int
|
||||||
get() = R.menu.menu_item_playing_queue_song
|
get() = R.menu.menu_item_playing_queue_song
|
||||||
set(value: Int) {
|
set(value: Int) {
|
||||||
super.songMenuRes = value
|
super.songMenuRes = value
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
imageText?.visibility = View.VISIBLE
|
imageText?.visibility = View.VISIBLE
|
||||||
dragView?.visibility = View.VISIBLE
|
dragView?.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSongMenuItemClick(item: MenuItem): Boolean {
|
override fun onSongMenuItemClick(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_remove_from_playing_queue -> {
|
R.id.action_remove_from_playing_queue -> {
|
||||||
MusicPlayerRemote.removeFromQueue(adapterPosition)
|
MusicPlayerRemote.removeFromQueue(adapterPosition)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return super.onSongMenuItemClick(item)
|
return super.onSongMenuItemClick(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
@DraggableItemStateFlags
|
@DraggableItemStateFlags
|
||||||
override fun getDragStateFlags(): Int {
|
override fun getDragStateFlags(): Int {
|
||||||
return mDragStateFlags
|
return mDragStateFlags
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setDragStateFlags(@DraggableItemStateFlags flags: Int) {
|
override fun setDragStateFlags(@DraggableItemStateFlags flags: Int) {
|
||||||
mDragStateFlags = flags
|
mDragStateFlags = flags
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private const val HISTORY = 0
|
private const val HISTORY = 0
|
||||||
private const val CURRENT = 1
|
private const val CURRENT = 1
|
||||||
private const val UP_NEXT = 2
|
private const val UP_NEXT = 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,89 +2,95 @@ package code.name.monkey.retromusic.adapter.song
|
||||||
|
|
||||||
import android.app.ActivityOptions
|
import android.app.ActivityOptions
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.view.MenuItem
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import androidx.annotation.LayoutRes
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
open class PlaylistSongAdapter(
|
||||||
|
activity: AppCompatActivity,
|
||||||
|
dataSet: ArrayList<Song>,
|
||||||
|
itemLayoutRes: Int,
|
||||||
|
usePalette: Boolean,
|
||||||
|
cabHolder: CabHolder?
|
||||||
|
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, usePalette, cabHolder, false) {
|
||||||
|
|
||||||
open class PlaylistSongAdapter(activity: AppCompatActivity,
|
init {
|
||||||
dataSet: ArrayList<Song>,
|
this.setMultiSelectMenuRes(R.menu.menu_cannot_delete_single_songs_playlist_songs_selection)
|
||||||
@LayoutRes itemLayoutRes: Int,
|
}
|
||||||
usePalette: Boolean,
|
|
||||||
cabHolder: CabHolder?) :
|
|
||||||
AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, usePalette, cabHolder, false) {
|
|
||||||
|
|
||||||
init {
|
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
||||||
this.setMultiSelectMenuRes(R.menu.menu_cannot_delete_single_songs_playlist_songs_selection)
|
return ViewHolder(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
|
||||||
return ViewHolder(view)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
|
if (holder.itemViewType == OFFSET_ITEM) {
|
||||||
|
|
||||||
if (holder.itemViewType == OFFSET_ITEM) {
|
val buttonColor = RetroColorUtil.toolbarColor(activity)
|
||||||
|
val textColor = MaterialValueHelper.getPrimaryTextColor(
|
||||||
|
activity, ColorUtil.isColorLight(
|
||||||
|
buttonColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val viewHolder = holder as ViewHolder
|
||||||
|
|
||||||
val buttonColor = RetroColorUtil.toolbarColor(activity)
|
viewHolder.playAction?.let {
|
||||||
val textColor = MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(buttonColor))
|
it.backgroundTintList = ColorStateList.valueOf(buttonColor)
|
||||||
val viewHolder = holder as ViewHolder
|
it.setTextColor(textColor)
|
||||||
|
it.iconTint = ColorStateList.valueOf(textColor)
|
||||||
|
it.setOnClickListener {
|
||||||
|
MusicPlayerRemote.openQueue(dataSet, 0, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewHolder.shuffleAction?.let {
|
||||||
|
it.backgroundTintList = ColorStateList.valueOf(buttonColor)
|
||||||
|
it.setTextColor(textColor)
|
||||||
|
it.iconTint = ColorStateList.valueOf(textColor)
|
||||||
|
it.setOnClickListener {
|
||||||
|
MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
viewHolder.playAction?.let {
|
} else {
|
||||||
it.backgroundTintList = ColorStateList.valueOf(buttonColor)
|
super.onBindViewHolder(holder, position - 1)
|
||||||
it.setTextColor(textColor)
|
}
|
||||||
it.iconTint = ColorStateList.valueOf(textColor)
|
}
|
||||||
it.setOnClickListener {
|
|
||||||
MusicPlayerRemote.openQueue(dataSet, 0, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
viewHolder.shuffleAction?.let {
|
|
||||||
it.backgroundTintList = ColorStateList.valueOf(buttonColor)
|
|
||||||
it.setTextColor(textColor)
|
|
||||||
it.iconTint = ColorStateList.valueOf(textColor)
|
|
||||||
it.setOnClickListener {
|
|
||||||
MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
open inner class ViewHolder(itemView: View) : AbsOffsetSongAdapter.ViewHolder(itemView) {
|
||||||
super.onBindViewHolder(holder, position - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open inner class ViewHolder(itemView: View) : AbsOffsetSongAdapter.ViewHolder(itemView) {
|
val playAction: MaterialButton? = itemView.findViewById(R.id.playAction)
|
||||||
|
val shuffleAction: MaterialButton? = itemView.findViewById(R.id.shuffleAction)
|
||||||
|
|
||||||
val playAction: MaterialButton? = itemView.findViewById(R.id.playAction)
|
override var songMenuRes: Int
|
||||||
val shuffleAction: MaterialButton? = itemView.findViewById(R.id.shuffleAction)
|
get() = R.menu.menu_item_cannot_delete_single_songs_playlist_song
|
||||||
|
set(value) {
|
||||||
|
super.songMenuRes = value
|
||||||
|
}
|
||||||
|
|
||||||
override var songMenuRes: Int
|
override fun onSongMenuItemClick(item: MenuItem): Boolean {
|
||||||
get() = R.menu.menu_item_cannot_delete_single_songs_playlist_song
|
if (item.itemId == R.id.action_go_to_album) {
|
||||||
set(value) {
|
val activityOptions = ActivityOptions.makeSceneTransitionAnimation(
|
||||||
super.songMenuRes = value
|
activity, image, activity.getString(
|
||||||
}
|
R.string.transition_album_art
|
||||||
|
)
|
||||||
|
)
|
||||||
|
NavigationUtil.goToAlbumOptions(
|
||||||
|
activity, dataSet[adapterPosition - 1].albumId, activityOptions
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return super.onSongMenuItemClick(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onSongMenuItemClick(item: MenuItem): Boolean {
|
companion object {
|
||||||
if (item.itemId == R.id.action_go_to_album) {
|
val TAG: String = PlaylistSongAdapter::class.java.simpleName
|
||||||
val activityOptions = ActivityOptions.makeSceneTransitionAnimation(activity, image, activity.getString(R.string.transition_album_art))
|
}
|
||||||
NavigationUtil.goToAlbumOptions(activity, dataSet[adapterPosition - 1].albumId, activityOptions)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return super.onSongMenuItemClick(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val TAG: String = PlaylistSongAdapter::class.java.simpleName
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package code.name.monkey.retromusic.adapter.song
|
package code.name.monkey.retromusic.adapter.song
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.annotation.LayoutRes
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
|
@ -10,45 +9,46 @@ import code.name.monkey.retromusic.model.Song
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
class ShuffleButtonSongAdapter(
|
||||||
|
activity: AppCompatActivity,
|
||||||
|
dataSet: ArrayList<Song>,
|
||||||
|
itemLayoutRes: Int,
|
||||||
|
usePalette: Boolean,
|
||||||
|
cabHolder: CabHolder?
|
||||||
|
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, usePalette, cabHolder) {
|
||||||
|
|
||||||
class ShuffleButtonSongAdapter(activity: AppCompatActivity,
|
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
||||||
dataSet: ArrayList<Song>,
|
return ViewHolder(view)
|
||||||
@LayoutRes itemLayoutRes: Int,
|
}
|
||||||
usePalette: Boolean,
|
|
||||||
cabHolder: CabHolder?) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, usePalette, cabHolder) {
|
|
||||||
|
|
||||||
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
|
||||||
return ViewHolder(view)
|
if (holder.itemViewType == OFFSET_ITEM) {
|
||||||
}
|
val viewHolder = holder as ViewHolder
|
||||||
|
viewHolder.playAction?.let {
|
||||||
|
it.setOnClickListener {
|
||||||
|
MusicPlayerRemote.openQueue(dataSet, 0, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewHolder.shuffleAction?.let {
|
||||||
|
it.setOnClickListener {
|
||||||
|
MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
super.onBindViewHolder(holder, position - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
|
inner class ViewHolder(itemView: View) : AbsOffsetSongAdapter.ViewHolder(itemView) {
|
||||||
if (holder.itemViewType == OFFSET_ITEM) {
|
val playAction: MaterialButton? = itemView.findViewById(R.id.playAction)
|
||||||
val viewHolder = holder as ViewHolder
|
val shuffleAction: MaterialButton? = itemView.findViewById(R.id.shuffleAction)
|
||||||
viewHolder.playAction?.let {
|
|
||||||
it.setOnClickListener {
|
|
||||||
MusicPlayerRemote.openQueue(dataSet, 0, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
viewHolder.shuffleAction?.let {
|
|
||||||
it.setOnClickListener {
|
|
||||||
MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
super.onBindViewHolder(holder, position - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : AbsOffsetSongAdapter.ViewHolder(itemView) {
|
override fun onClick(v: View?) {
|
||||||
val playAction: MaterialButton? = itemView.findViewById(R.id.playAction)
|
if (itemViewType == OFFSET_ITEM) {
|
||||||
val shuffleAction: MaterialButton? = itemView.findViewById(R.id.shuffleAction)
|
MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
|
||||||
|
return
|
||||||
override fun onClick(v: View?) {
|
}
|
||||||
if (itemViewType == OFFSET_ITEM) {
|
super.onClick(v)
|
||||||
MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
|
}
|
||||||
return
|
}
|
||||||
}
|
|
||||||
super.onClick(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,38 +1,34 @@
|
||||||
package code.name.monkey.retromusic.adapter.song
|
package code.name.monkey.retromusic.adapter.song
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.annotation.LayoutRes
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
import code.name.monkey.retromusic.util.MusicUtil
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
class SimpleSongAdapter(
|
||||||
|
context: AppCompatActivity, songs: ArrayList<Song>, i: Int
|
||||||
|
) : SongAdapter(context, songs, i, false, null) {
|
||||||
|
|
||||||
class SimpleSongAdapter(context: AppCompatActivity,
|
override fun swapDataSet(dataSet: ArrayList<Song>) {
|
||||||
songs: ArrayList<Song>,
|
this.dataSet.clear()
|
||||||
@LayoutRes i: Int) : SongAdapter(context, songs, i, false, null) {
|
this.dataSet = dataSet
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
return ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false))
|
||||||
|
}
|
||||||
|
|
||||||
override fun swapDataSet(dataSet: ArrayList<Song>) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
this.dataSet.clear()
|
super.onBindViewHolder(holder, position)
|
||||||
this.dataSet = dataSet
|
val fixedTrackNumber = MusicUtil.getFixedTrackNumber(dataSet[position].trackNumber)
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
holder.imageText?.text = if (fixedTrackNumber > 0) fixedTrackNumber.toString() else "-"
|
||||||
return ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false))
|
holder.time?.text = MusicUtil.getReadableDurationString(dataSet[position].duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun getItemCount(): Int {
|
||||||
super.onBindViewHolder(holder, position)
|
return dataSet.size
|
||||||
val fixedTrackNumber = MusicUtil.getFixedTrackNumber(dataSet[position].trackNumber)
|
}
|
||||||
|
|
||||||
holder.imageText?.text = if (fixedTrackNumber > 0) fixedTrackNumber.toString() else "-"
|
|
||||||
holder.time?.text = MusicUtil.getReadableDurationString(dataSet[position].duration)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
|
||||||
return dataSet.size
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,209 +2,214 @@ package code.name.monkey.retromusic.adapter.song
|
||||||
|
|
||||||
import android.app.ActivityOptions
|
import android.app.ActivityOptions
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
|
import code.name.monkey.retromusic.adapter.base.*
|
||||||
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
import code.name.monkey.retromusic.glide.*
|
||||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
import code.name.monkey.retromusic.helper.*
|
||||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
import code.name.monkey.retromusic.helper.menu.*
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
|
||||||
import code.name.monkey.retromusic.helper.SortOrder
|
|
||||||
import code.name.monkey.retromusic.helper.menu.SongMenuHelper
|
|
||||||
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
|
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
|
||||||
import com.afollestad.materialcab.MaterialCab
|
import com.afollestad.materialcab.MaterialCab
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hemanths on 13/08/17.
|
* Created by hemanths on 13/08/17.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
open class SongAdapter @JvmOverloads constructor(
|
open class SongAdapter(
|
||||||
protected val activity: AppCompatActivity,
|
protected val activity: AppCompatActivity,
|
||||||
dataSet: ArrayList<Song>,
|
dataSet: ArrayList<Song>,
|
||||||
protected var itemLayoutRes: Int,
|
protected var itemLayoutRes: Int,
|
||||||
usePalette: Boolean,
|
usePalette: Boolean,
|
||||||
cabHolder: CabHolder?,
|
cabHolder: CabHolder?,
|
||||||
showSectionName: Boolean = true
|
showSectionName: Boolean = true
|
||||||
) : AbsMultiSelectAdapter<SongAdapter.ViewHolder, Song>(activity, cabHolder, R.menu.menu_media_selection), MaterialCab.Callback, FastScrollRecyclerView.SectionedAdapter {
|
) : AbsMultiSelectAdapter<SongAdapter.ViewHolder, Song>(
|
||||||
var dataSet: ArrayList<Song>
|
activity, cabHolder, R.menu.menu_media_selection
|
||||||
|
), MaterialCab.Callback, FastScrollRecyclerView.SectionedAdapter {
|
||||||
|
var dataSet: ArrayList<Song>
|
||||||
|
|
||||||
protected var usePalette = false
|
protected var usePalette = false
|
||||||
private var showSectionName = true
|
private var showSectionName = true
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.dataSet = dataSet
|
this.dataSet = dataSet
|
||||||
this.usePalette = usePalette
|
this.usePalette = usePalette
|
||||||
this.showSectionName = showSectionName
|
this.showSectionName = showSectionName
|
||||||
this.setHasStableIds(true)
|
this.setHasStableIds(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun swapDataSet(dataSet: ArrayList<Song>) {
|
open fun swapDataSet(dataSet: ArrayList<Song>) {
|
||||||
this.dataSet = dataSet
|
this.dataSet = dataSet
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun usePalette(usePalette: Boolean) {
|
open fun usePalette(usePalette: Boolean) {
|
||||||
this.usePalette = usePalette
|
this.usePalette = usePalette
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemId(position: Int): Long {
|
override fun getItemId(position: Int): Long {
|
||||||
return dataSet[position].id.toLong()
|
return dataSet[position].id.toLong()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
val view = LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false)
|
val view = LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false)
|
||||||
return createViewHolder(view)
|
return createViewHolder(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun createViewHolder(view: View): ViewHolder {
|
protected open fun createViewHolder(view: View): ViewHolder {
|
||||||
return ViewHolder(view)
|
return ViewHolder(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val song = dataSet[position]
|
val song = dataSet[position]
|
||||||
val isChecked = isChecked(song)
|
val isChecked = isChecked(song)
|
||||||
holder.itemView.isActivated = isChecked
|
holder.itemView.isActivated = isChecked
|
||||||
holder.title?.text = getSongTitle(song)
|
holder.title?.text = getSongTitle(song)
|
||||||
holder.text?.text = getSongText(song)
|
holder.text?.text = getSongText(song)
|
||||||
loadAlbumCover(song, holder)
|
loadAlbumCover(song, holder)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setColors(color: Int, holder: ViewHolder) {
|
private fun setColors(color: Int, holder: ViewHolder) {
|
||||||
if (holder.paletteColorContainer != null) {
|
if (holder.paletteColorContainer != null) {
|
||||||
holder.paletteColorContainer?.setBackgroundColor(color)
|
holder.paletteColorContainer?.setBackgroundColor(color)
|
||||||
holder.title?.setTextColor(MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color)))
|
holder.title?.setTextColor(
|
||||||
holder.text?.setTextColor(MaterialValueHelper.getSecondaryTextColor(activity, ColorUtil.isColorLight(color)))
|
MaterialValueHelper.getPrimaryTextColor(
|
||||||
}
|
activity, ColorUtil.isColorLight(
|
||||||
}
|
color
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
holder.text?.setTextColor(
|
||||||
|
MaterialValueHelper.getSecondaryTextColor(
|
||||||
|
activity, ColorUtil.isColorLight(
|
||||||
|
color
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected open fun loadAlbumCover(song: Song, holder: ViewHolder) {
|
protected open fun loadAlbumCover(song: Song, holder: ViewHolder) {
|
||||||
if (holder.image == null) {
|
if (holder.image == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
SongGlideRequest.Builder.from(Glide.with(activity), song)
|
SongGlideRequest.Builder.from(Glide.with(activity), song).checkIgnoreMediaStore(activity)
|
||||||
.checkIgnoreMediaStore(activity)
|
.generatePalette(activity).build()
|
||||||
.generatePalette(activity).build()
|
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
||||||
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
override fun onLoadCleared(placeholder: Drawable?) {
|
||||||
override fun onLoadCleared(placeholder: Drawable?) {
|
super.onLoadCleared(placeholder)
|
||||||
super.onLoadCleared(placeholder)
|
setColors(defaultFooterColor, holder)
|
||||||
setColors(defaultFooterColor, holder)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onColorReady(color: Int) {
|
override fun onColorReady(color: Int) {
|
||||||
if (usePalette)
|
if (usePalette) setColors(color, holder)
|
||||||
setColors(color, holder)
|
else setColors(defaultFooterColor, holder)
|
||||||
else
|
}
|
||||||
setColors(defaultFooterColor, holder)
|
})
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getSongTitle(song: Song): String? {
|
private fun getSongTitle(song: Song): String? {
|
||||||
return song.title
|
return song.title
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSongText(song: Song): String? {
|
private fun getSongText(song: Song): String? {
|
||||||
return song.artistName
|
return song.artistName
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return dataSet.size
|
return dataSet.size
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIdentifier(position: Int): Song? {
|
override fun getIdentifier(position: Int): Song? {
|
||||||
return dataSet[position]
|
return dataSet[position]
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(song: Song): String {
|
override fun getName(song: Song): String {
|
||||||
return song.title
|
return song.title
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMultipleItemAction(menuItem: MenuItem,
|
override fun onMultipleItemAction(
|
||||||
selection: ArrayList<Song>) {
|
menuItem: MenuItem, selection: ArrayList<Song>
|
||||||
SongsMenuHelper.handleMenuClick(activity, selection, menuItem.itemId)
|
) {
|
||||||
}
|
SongsMenuHelper.handleMenuClick(activity, selection, menuItem.itemId)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getSectionName(position: Int): String {
|
override fun getSectionName(position: Int): String {
|
||||||
if (!showSectionName) {
|
if (!showSectionName) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
val sectionName: String? = when (PreferenceUtil.getInstance(activity).songSortOrder) {
|
val sectionName: String? = when (PreferenceUtil.getInstance(activity).songSortOrder) {
|
||||||
SortOrder.SongSortOrder.SONG_A_Z, SortOrder.SongSortOrder.SONG_Z_A -> dataSet[position].title
|
SortOrder.SongSortOrder.SONG_A_Z, SortOrder.SongSortOrder.SONG_Z_A -> dataSet[position].title
|
||||||
SortOrder.SongSortOrder.SONG_ALBUM -> dataSet[position].albumName
|
SortOrder.SongSortOrder.SONG_ALBUM -> dataSet[position].albumName
|
||||||
SortOrder.SongSortOrder.SONG_ARTIST -> dataSet[position].artistName
|
SortOrder.SongSortOrder.SONG_ARTIST -> dataSet[position].artistName
|
||||||
SortOrder.SongSortOrder.SONG_YEAR -> return MusicUtil.getYearString(dataSet[position].year)
|
SortOrder.SongSortOrder.SONG_YEAR -> return MusicUtil.getYearString(
|
||||||
SortOrder.SongSortOrder.COMPOSER -> dataSet[position].composer
|
dataSet[position].year
|
||||||
else -> {
|
)
|
||||||
return ""
|
SortOrder.SongSortOrder.COMPOSER -> dataSet[position].composer
|
||||||
}
|
else -> {
|
||||||
}
|
return ""
|
||||||
return MusicUtil.getSectionName(sectionName)
|
}
|
||||||
}
|
}
|
||||||
|
return MusicUtil.getSectionName(sectionName)
|
||||||
|
}
|
||||||
|
|
||||||
open inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
open inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
|
||||||
protected open var songMenuRes = SongMenuHelper.MENU_RES
|
protected open var songMenuRes = SongMenuHelper.MENU_RES
|
||||||
protected open val song: Song
|
protected open val song: Song
|
||||||
get() = dataSet[adapterPosition]
|
get() = dataSet[adapterPosition]
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setImageTransitionName(activity.getString(R.string.transition_album_art))
|
setImageTransitionName(activity.getString(R.string.transition_album_art))
|
||||||
menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
|
menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
|
||||||
override val song: Song
|
override val song: Song
|
||||||
get() = this@ViewHolder.song
|
get() = this@ViewHolder.song
|
||||||
|
|
||||||
override val menuRes: Int
|
override val menuRes: Int
|
||||||
get() = songMenuRes
|
get() = songMenuRes
|
||||||
|
|
||||||
override fun onMenuItemClick(item: MenuItem): Boolean {
|
override fun onMenuItemClick(item: MenuItem): Boolean {
|
||||||
return onSongMenuItemClick(item) || super.onMenuItemClick(item)
|
return onSongMenuItemClick(item) || super.onMenuItemClick(item)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun onSongMenuItemClick(item: MenuItem): Boolean {
|
protected open fun onSongMenuItemClick(item: MenuItem): Boolean {
|
||||||
if (image != null && image!!.visibility == View.VISIBLE) {
|
if (image != null && image!!.visibility == View.VISIBLE) {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_go_to_album -> {
|
R.id.action_go_to_album -> {
|
||||||
val options: ActivityOptions = ActivityOptions.makeSceneTransitionAnimation(activity, image, activity.getString(R.string.transition_album_art))
|
val options: ActivityOptions = ActivityOptions.makeSceneTransitionAnimation(
|
||||||
NavigationUtil.goToAlbumOptions(activity, song.albumId, options)
|
activity, image, activity.getString(R.string.transition_album_art)
|
||||||
return true
|
)
|
||||||
}
|
NavigationUtil.goToAlbumOptions(activity, song.albumId, options)
|
||||||
}
|
return true
|
||||||
}
|
}
|
||||||
return false
|
}
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
override fun onClick(v: View?) {
|
override fun onClick(v: View?) {
|
||||||
if (isInQuickSelectMode) {
|
if (isInQuickSelectMode) {
|
||||||
toggleChecked(adapterPosition)
|
toggleChecked(adapterPosition)
|
||||||
} else {
|
} else {
|
||||||
MusicPlayerRemote.openQueue(dataSet, adapterPosition, true)
|
MusicPlayerRemote.openQueue(dataSet, adapterPosition, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLongClick(v: View?): Boolean {
|
override fun onLongClick(v: View?): Boolean {
|
||||||
return toggleChecked(adapterPosition)
|
return toggleChecked(adapterPosition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
val TAG: String = SongAdapter::class.java.simpleName
|
val TAG: String = SongAdapter::class.java.simpleName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,67 +15,69 @@
|
||||||
package code.name.monkey.retromusic.appshortcuts
|
package code.name.monkey.retromusic.appshortcuts
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.*
|
||||||
import android.graphics.Canvas
|
import android.graphics.drawable.*
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import android.graphics.drawable.Icon
|
|
||||||
import android.graphics.drawable.LayerDrawable
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
|
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.*
|
||||||
import code.name.monkey.retromusic.util.RetroUtil
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.N_MR1)
|
@RequiresApi(Build.VERSION_CODES.N_MR1)
|
||||||
object AppShortcutIconGenerator {
|
object AppShortcutIconGenerator {
|
||||||
fun generateThemedIcon(context: Context, iconId: Int): Icon {
|
fun generateThemedIcon(context: Context, iconId: Int): Icon {
|
||||||
return if (PreferenceUtil.getInstance(context).coloredAppShortcuts()) {
|
return if (PreferenceUtil.getInstance(context).coloredAppShortcuts()) {
|
||||||
generateUserThemedIcon(context, iconId)
|
generateUserThemedIcon(context, iconId)
|
||||||
} else {
|
} else {
|
||||||
generateDefaultThemedIcon(context, iconId)
|
generateDefaultThemedIcon(context, iconId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateDefaultThemedIcon(context: Context, iconId: Int): Icon {
|
private fun generateDefaultThemedIcon(context: Context, iconId: Int): Icon {
|
||||||
// Return an Icon of iconId with default colors
|
// Return an Icon of iconId with default colors
|
||||||
return generateThemedIcon(context, iconId,
|
return generateThemedIcon(
|
||||||
context.getColor(R.color.app_shortcut_default_foreground),
|
context,
|
||||||
context.getColor(R.color.app_shortcut_default_background)
|
iconId,
|
||||||
)
|
context.getColor(R.color.app_shortcut_default_foreground),
|
||||||
}
|
context.getColor(R.color.app_shortcut_default_background)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun generateUserThemedIcon(context: Context, iconId: Int): Icon {
|
private fun generateUserThemedIcon(context: Context, iconId: Int): Icon {
|
||||||
// Get background color from context's theme
|
// Get background color from context's theme
|
||||||
val typedColorBackground = TypedValue()
|
val typedColorBackground = TypedValue()
|
||||||
context.theme.resolveAttribute(android.R.attr.colorBackground, typedColorBackground, true)
|
context.theme.resolveAttribute(android.R.attr.colorBackground, typedColorBackground, true)
|
||||||
|
|
||||||
// Return an Icon of iconId with those colors
|
// Return an Icon of iconId with those colors
|
||||||
return generateThemedIcon(context, iconId,
|
return generateThemedIcon(
|
||||||
ThemeStore.accentColor(context),
|
context, iconId, ThemeStore.accentColor(context), typedColorBackground.data
|
||||||
typedColorBackground.data
|
)
|
||||||
)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateThemedIcon(context: Context, iconId: Int, foregroundColor: Int, backgroundColor: Int): Icon {
|
private fun generateThemedIcon(
|
||||||
// Get and tint foreground and background drawables
|
context: Context, iconId: Int, foregroundColor: Int, backgroundColor: Int
|
||||||
val vectorDrawable = RetroUtil.getTintedVectorDrawable(context, iconId, foregroundColor)
|
): Icon {
|
||||||
val backgroundDrawable = RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_app_shortcut_background, backgroundColor)
|
// Get and tint foreground and background drawables
|
||||||
|
val vectorDrawable = RetroUtil.getTintedVectorDrawable(context, iconId, foregroundColor)
|
||||||
|
val backgroundDrawable = RetroUtil.getTintedVectorDrawable(
|
||||||
|
context, R.drawable.ic_app_shortcut_background, backgroundColor
|
||||||
|
)
|
||||||
|
|
||||||
// Squash the two drawables together
|
// Squash the two drawables together
|
||||||
val layerDrawable = LayerDrawable(arrayOf(backgroundDrawable, vectorDrawable))
|
val layerDrawable = LayerDrawable(arrayOf(backgroundDrawable, vectorDrawable))
|
||||||
|
|
||||||
// Return as an Icon
|
// Return as an Icon
|
||||||
return Icon.createWithBitmap(drawableToBitmap(layerDrawable))
|
return Icon.createWithBitmap(drawableToBitmap(layerDrawable))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawableToBitmap(drawable: Drawable): Bitmap {
|
private fun drawableToBitmap(drawable: Drawable): Bitmap {
|
||||||
val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
|
val bitmap = Bitmap.createBitmap(
|
||||||
val canvas = Canvas(bitmap)
|
drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888
|
||||||
drawable.setBounds(0, 0, canvas.width, canvas.height)
|
)
|
||||||
drawable.draw(canvas)
|
val canvas = Canvas(bitmap)
|
||||||
return bitmap
|
drawable.setBounds(0, 0, canvas.width, canvas.height)
|
||||||
}
|
drawable.draw(canvas)
|
||||||
|
return bitmap
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,74 +18,71 @@ import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import code.name.monkey.retromusic.activities.SearchActivity
|
import code.name.monkey.retromusic.activities.SearchActivity
|
||||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.LastAddedShortcutType
|
import code.name.monkey.retromusic.appshortcuts.shortcuttype.*
|
||||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.SearchShortCutType
|
|
||||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.ShuffleAllShortcutType
|
|
||||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.TopTracksShortcutType
|
|
||||||
import code.name.monkey.retromusic.model.Playlist
|
import code.name.monkey.retromusic.model.Playlist
|
||||||
import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist
|
import code.name.monkey.retromusic.model.smartplaylist.*
|
||||||
import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist
|
|
||||||
import code.name.monkey.retromusic.model.smartplaylist.ShuffleAllPlaylist
|
|
||||||
import code.name.monkey.retromusic.service.MusicService
|
import code.name.monkey.retromusic.service.MusicService
|
||||||
import code.name.monkey.retromusic.service.MusicService.*
|
import code.name.monkey.retromusic.service.MusicService.*
|
||||||
|
|
||||||
|
|
||||||
class AppShortcutLauncherActivity : Activity() {
|
class AppShortcutLauncherActivity : Activity() {
|
||||||
|
|
||||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
var shortcutType = SHORTCUT_TYPE_NONE
|
var shortcutType = SHORTCUT_TYPE_NONE
|
||||||
|
|
||||||
// Set shortcutType from the intent extras
|
// Set shortcutType from the intent extras
|
||||||
val extras = intent.extras
|
val extras = intent.extras
|
||||||
if (extras != null) {
|
if (extras != null) {
|
||||||
shortcutType = extras.getInt(KEY_SHORTCUT_TYPE, SHORTCUT_TYPE_NONE)
|
shortcutType = extras.getInt(KEY_SHORTCUT_TYPE, SHORTCUT_TYPE_NONE)
|
||||||
}
|
}
|
||||||
|
|
||||||
when (shortcutType) {
|
when (shortcutType) {
|
||||||
SHORTCUT_TYPE_SHUFFLE_ALL -> {
|
SHORTCUT_TYPE_SHUFFLE_ALL -> {
|
||||||
startServiceWithPlaylist(MusicService.SHUFFLE_MODE_SHUFFLE,
|
startServiceWithPlaylist(
|
||||||
ShuffleAllPlaylist(applicationContext))
|
MusicService.SHUFFLE_MODE_SHUFFLE, ShuffleAllPlaylist(applicationContext)
|
||||||
DynamicShortcutManager.reportShortcutUsed(this, ShuffleAllShortcutType.id)
|
)
|
||||||
}
|
DynamicShortcutManager.reportShortcutUsed(this, ShuffleAllShortcutType.id)
|
||||||
SHORTCUT_TYPE_TOP_TRACKS -> {
|
}
|
||||||
startServiceWithPlaylist(MusicService.SHUFFLE_MODE_NONE,
|
SHORTCUT_TYPE_TOP_TRACKS -> {
|
||||||
MyTopTracksPlaylist(applicationContext))
|
startServiceWithPlaylist(
|
||||||
DynamicShortcutManager.reportShortcutUsed(this, TopTracksShortcutType.id)
|
MusicService.SHUFFLE_MODE_NONE, MyTopTracksPlaylist(applicationContext)
|
||||||
}
|
)
|
||||||
SHORTCUT_TYPE_LAST_ADDED -> {
|
DynamicShortcutManager.reportShortcutUsed(this, TopTracksShortcutType.id)
|
||||||
startServiceWithPlaylist(MusicService.SHUFFLE_MODE_NONE,
|
}
|
||||||
LastAddedPlaylist(applicationContext))
|
SHORTCUT_TYPE_LAST_ADDED -> {
|
||||||
DynamicShortcutManager.reportShortcutUsed(this, LastAddedShortcutType.id)
|
startServiceWithPlaylist(
|
||||||
}
|
MusicService.SHUFFLE_MODE_NONE, LastAddedPlaylist(applicationContext)
|
||||||
SHORTCUT_TYPE_SEARCH -> {
|
)
|
||||||
startActivity(Intent(this, SearchActivity::class.java))
|
DynamicShortcutManager.reportShortcutUsed(this, LastAddedShortcutType.id)
|
||||||
DynamicShortcutManager.reportShortcutUsed(this, SearchShortCutType.id)
|
}
|
||||||
}
|
SHORTCUT_TYPE_SEARCH -> {
|
||||||
}
|
startActivity(Intent(this, SearchActivity::class.java))
|
||||||
finish()
|
DynamicShortcutManager.reportShortcutUsed(this, SearchShortCutType.id)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
private fun startServiceWithPlaylist(shuffleMode: Int, playlist: Playlist) {
|
private fun startServiceWithPlaylist(shuffleMode: Int, playlist: Playlist) {
|
||||||
val intent = Intent(this, MusicService::class.java)
|
val intent = Intent(this, MusicService::class.java)
|
||||||
intent.action = ACTION_PLAY_PLAYLIST
|
intent.action = ACTION_PLAY_PLAYLIST
|
||||||
|
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(INTENT_EXTRA_PLAYLIST, playlist)
|
bundle.putParcelable(INTENT_EXTRA_PLAYLIST, playlist)
|
||||||
bundle.putInt(INTENT_EXTRA_SHUFFLE_MODE, shuffleMode)
|
bundle.putInt(INTENT_EXTRA_SHUFFLE_MODE, shuffleMode)
|
||||||
|
|
||||||
intent.putExtras(bundle)
|
intent.putExtras(bundle)
|
||||||
|
|
||||||
startService(intent)
|
startService(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val KEY_SHORTCUT_TYPE = "code.name.monkey.retromusic.appshortcuts.ShortcutType"
|
const val KEY_SHORTCUT_TYPE = "code.name.monkey.retromusic.appshortcuts.ShortcutType"
|
||||||
const val SHORTCUT_TYPE_SHUFFLE_ALL = 0
|
const val SHORTCUT_TYPE_SHUFFLE_ALL = 0
|
||||||
const val SHORTCUT_TYPE_TOP_TRACKS = 1
|
const val SHORTCUT_TYPE_TOP_TRACKS = 1
|
||||||
const val SHORTCUT_TYPE_LAST_ADDED = 2
|
const val SHORTCUT_TYPE_LAST_ADDED = 2
|
||||||
const val SHORTCUT_TYPE_SEARCH = 3
|
const val SHORTCUT_TYPE_SEARCH = 3
|
||||||
const val SHORTCUT_TYPE_NONE = 4
|
const val SHORTCUT_TYPE_NONE = 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,56 +15,52 @@
|
||||||
package code.name.monkey.retromusic.appshortcuts
|
package code.name.monkey.retromusic.appshortcuts
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
import android.annotation.TargetApi
|
||||||
import android.content.Context
|
import android.content.*
|
||||||
import android.content.Intent
|
import android.content.pm.*
|
||||||
import android.content.pm.ShortcutInfo
|
|
||||||
import android.content.pm.ShortcutManager
|
|
||||||
import android.graphics.drawable.Icon
|
import android.graphics.drawable.Icon
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import code.name.monkey.retromusic.appshortcuts.shortcuttype.*
|
||||||
import java.util.Arrays
|
import java.util.*
|
||||||
|
|
||||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.LastAddedShortcutType
|
|
||||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.SearchShortCutType
|
|
||||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.ShuffleAllShortcutType
|
|
||||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.TopTracksShortcutType
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||||
class DynamicShortcutManager(private val context: Context) {
|
class DynamicShortcutManager(private val context: Context) {
|
||||||
private val shortcutManager: ShortcutManager = this.context.getSystemService(ShortcutManager::class.java)
|
private val shortcutManager: ShortcutManager = this.context.getSystemService(ShortcutManager::class.java)
|
||||||
|
|
||||||
private val defaultShortcuts: List<ShortcutInfo>
|
private val defaultShortcuts: List<ShortcutInfo>
|
||||||
get() = Arrays.asList(
|
get() = Arrays.asList(
|
||||||
SearchShortCutType(context).shortcutInfo,
|
SearchShortCutType(context).shortcutInfo,
|
||||||
ShuffleAllShortcutType(context).shortcutInfo,
|
ShuffleAllShortcutType(context).shortcutInfo,
|
||||||
TopTracksShortcutType(context).shortcutInfo,
|
TopTracksShortcutType(context).shortcutInfo,
|
||||||
LastAddedShortcutType(context).shortcutInfo
|
LastAddedShortcutType(context).shortcutInfo
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
fun initDynamicShortcuts() {
|
fun initDynamicShortcuts() {
|
||||||
//if (shortcutManager.dynamicShortcuts.size == 0) {
|
//if (shortcutManager.dynamicShortcuts.size == 0) {
|
||||||
shortcutManager.dynamicShortcuts = defaultShortcuts
|
shortcutManager.dynamicShortcuts = defaultShortcuts
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateDynamicShortcuts() {
|
fun updateDynamicShortcuts() {
|
||||||
shortcutManager.updateShortcuts(defaultShortcuts)
|
shortcutManager.updateShortcuts(defaultShortcuts)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun createShortcut(context: Context, id: String, shortLabel: String, longLabel: String, icon: Icon, intent: Intent): ShortcutInfo {
|
fun createShortcut(
|
||||||
return ShortcutInfo.Builder(context, id)
|
context: Context,
|
||||||
.setShortLabel(shortLabel)
|
id: String,
|
||||||
.setLongLabel(longLabel)
|
shortLabel: String,
|
||||||
.setIcon(icon)
|
longLabel: String,
|
||||||
.setIntent(intent)
|
icon: Icon,
|
||||||
.build()
|
intent: Intent
|
||||||
}
|
): ShortcutInfo {
|
||||||
|
return ShortcutInfo.Builder(context, id).setShortLabel(shortLabel)
|
||||||
|
.setLongLabel(longLabel).setIcon(icon).setIntent(intent).build()
|
||||||
|
}
|
||||||
|
|
||||||
fun reportShortcutUsed(context: Context, shortcutId: String) {
|
fun reportShortcutUsed(context: Context, shortcutId: String) {
|
||||||
context.getSystemService(ShortcutManager::class.java).reportShortcutUsed(shortcutId)
|
context.getSystemService(ShortcutManager::class.java).reportShortcutUsed(shortcutId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,37 +15,34 @@
|
||||||
package code.name.monkey.retromusic.appshortcuts.shortcuttype
|
package code.name.monkey.retromusic.appshortcuts.shortcuttype
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
import android.annotation.TargetApi
|
||||||
import android.content.Context
|
import android.content.*
|
||||||
import android.content.Intent
|
|
||||||
import android.content.pm.ShortcutInfo
|
import android.content.pm.ShortcutInfo
|
||||||
import android.os.Build
|
import android.os.*
|
||||||
import android.os.Bundle
|
|
||||||
|
|
||||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
|
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||||
abstract class BaseShortcutType(internal var context: Context) {
|
abstract class BaseShortcutType(internal var context: Context) {
|
||||||
|
|
||||||
internal abstract val shortcutInfo: ShortcutInfo
|
internal abstract val shortcutInfo: ShortcutInfo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an Intent that will launch MainActivtiy and immediately play {@param songs} in either shuffle or normal mode
|
* Creates an Intent that will launch MainActivtiy and immediately play {@param songs} in either shuffle or normal mode
|
||||||
*
|
*
|
||||||
* @param shortcutType Describes the type of shortcut to create (ShuffleAll, TopTracks, custom playlist, etc.)
|
* @param shortcutType Describes the type of shortcut to create (ShuffleAll, TopTracks, custom playlist, etc.)
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
internal fun getPlaySongsIntent(shortcutType: Int): Intent {
|
internal fun getPlaySongsIntent(shortcutType: Int): Intent {
|
||||||
val intent = Intent(context, AppShortcutLauncherActivity::class.java)
|
val intent = Intent(context, AppShortcutLauncherActivity::class.java)
|
||||||
intent.action = Intent.ACTION_VIEW
|
intent.action = Intent.ACTION_VIEW
|
||||||
val b = Bundle()
|
val b = Bundle()
|
||||||
b.putInt(AppShortcutLauncherActivity.KEY_SHORTCUT_TYPE, shortcutType)
|
b.putInt(AppShortcutLauncherActivity.KEY_SHORTCUT_TYPE, shortcutType)
|
||||||
intent.putExtras(b)
|
intent.putExtras(b)
|
||||||
return intent
|
return intent
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
internal const val ID_PREFIX = "code.name.monkey.retromusic.appshortcuts.id."
|
internal const val ID_PREFIX = "code.name.monkey.retromusic.appshortcuts.id."
|
||||||
val id: String
|
val id: String
|
||||||
get() = ID_PREFIX + "invalid"
|
get() = ID_PREFIX + "invalid"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,23 +19,27 @@ import android.content.Context
|
||||||
import android.content.pm.ShortcutInfo
|
import android.content.pm.ShortcutInfo
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator
|
import code.name.monkey.retromusic.appshortcuts.*
|
||||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||||
class LastAddedShortcutType(context: Context) : BaseShortcutType(context) {
|
class LastAddedShortcutType(context: Context) : BaseShortcutType(context) {
|
||||||
|
|
||||||
override val shortcutInfo: ShortcutInfo
|
override val shortcutInfo: ShortcutInfo
|
||||||
get() = ShortcutInfo.Builder(context, id)
|
get() = ShortcutInfo.Builder(
|
||||||
.setShortLabel(context.getString(R.string.app_shortcut_last_added_short))
|
context,
|
||||||
.setLongLabel(context.getString(R.string.app_shortcut_last_added_long))
|
id
|
||||||
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_last_added))
|
).setShortLabel(context.getString(R.string.app_shortcut_last_added_short)).setLongLabel(
|
||||||
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_LAST_ADDED))
|
context.getString(R.string.app_shortcut_last_added_long)
|
||||||
.build()
|
).setIcon(
|
||||||
|
AppShortcutIconGenerator.generateThemedIcon(
|
||||||
|
context,
|
||||||
|
R.drawable.ic_app_shortcut_last_added
|
||||||
|
)
|
||||||
|
).setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_LAST_ADDED)).build()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
val id: String
|
val id: String
|
||||||
get() = BaseShortcutType.ID_PREFIX + "last_added"
|
get() = BaseShortcutType.ID_PREFIX + "last_added"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,22 +19,24 @@ import android.content.Context
|
||||||
import android.content.pm.ShortcutInfo
|
import android.content.pm.ShortcutInfo
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator
|
import code.name.monkey.retromusic.appshortcuts.*
|
||||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||||
class SearchShortCutType(context: Context) : BaseShortcutType(context) {
|
class SearchShortCutType(context: Context) : BaseShortcutType(context) {
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
val id: String
|
val id: String
|
||||||
get() = BaseShortcutType.ID_PREFIX + "search"
|
get() = BaseShortcutType.ID_PREFIX + "search"
|
||||||
}
|
}
|
||||||
|
|
||||||
override val shortcutInfo: ShortcutInfo
|
override val shortcutInfo: ShortcutInfo
|
||||||
get() = ShortcutInfo.Builder(context, id)
|
get() = ShortcutInfo.Builder(
|
||||||
.setShortLabel(context.getString(R.string.action_search))
|
context,
|
||||||
.setLongLabel(context.getString(R.string.search_hint))
|
id
|
||||||
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_search))
|
).setShortLabel(context.getString(R.string.action_search)).setLongLabel(context.getString(R.string.search_hint)).setIcon(
|
||||||
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_SEARCH))
|
AppShortcutIconGenerator.generateThemedIcon(
|
||||||
.build()
|
context,
|
||||||
|
R.drawable.ic_app_shortcut_search
|
||||||
|
)
|
||||||
|
).setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_SEARCH)).build()
|
||||||
}
|
}
|
|
@ -18,26 +18,26 @@ import android.annotation.TargetApi
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.ShortcutInfo
|
import android.content.pm.ShortcutInfo
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator
|
import code.name.monkey.retromusic.appshortcuts.*
|
||||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
|
|
||||||
import java.security.AccessController.getContext
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||||
class ShuffleAllShortcutType(context: Context) : BaseShortcutType(context) {
|
class ShuffleAllShortcutType(context: Context) : BaseShortcutType(context) {
|
||||||
|
|
||||||
override val shortcutInfo: ShortcutInfo
|
override val shortcutInfo: ShortcutInfo
|
||||||
get() = ShortcutInfo.Builder(context, id)
|
get() = ShortcutInfo.Builder(
|
||||||
.setShortLabel(context.getString(R.string.app_shortcut_shuffle_all_short))
|
context, id
|
||||||
.setLongLabel(context.getString(R.string.app_shortcut_shuffle_all_long))
|
).setShortLabel(context.getString(R.string.app_shortcut_shuffle_all_short)).setLongLabel(
|
||||||
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_shuffle_all))
|
context.getString(R.string.app_shortcut_shuffle_all_long)
|
||||||
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_SHUFFLE_ALL))
|
).setIcon(
|
||||||
.build()
|
AppShortcutIconGenerator.generateThemedIcon(
|
||||||
|
context, R.drawable.ic_app_shortcut_shuffle_all
|
||||||
|
)
|
||||||
|
).setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_SHUFFLE_ALL)).build()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
val id: String
|
val id: String
|
||||||
get() = BaseShortcutType.ID_PREFIX + "shuffle_all"
|
get() = BaseShortcutType.ID_PREFIX + "shuffle_all"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,23 +19,25 @@ import android.content.Context
|
||||||
import android.content.pm.ShortcutInfo
|
import android.content.pm.ShortcutInfo
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator
|
import code.name.monkey.retromusic.appshortcuts.*
|
||||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||||
class TopTracksShortcutType(context: Context) : BaseShortcutType(context) {
|
class TopTracksShortcutType(context: Context) : BaseShortcutType(context) {
|
||||||
|
|
||||||
override val shortcutInfo: ShortcutInfo
|
override val shortcutInfo: ShortcutInfo
|
||||||
get() = ShortcutInfo.Builder(context, id)
|
get() = ShortcutInfo.Builder(
|
||||||
.setShortLabel(context.getString(R.string.app_shortcut_top_tracks_short))
|
context, id
|
||||||
.setLongLabel(context.getString(R.string.app_shortcut_top_tracks_long))
|
).setShortLabel(context.getString(R.string.app_shortcut_top_tracks_short)).setLongLabel(
|
||||||
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_top_tracks))
|
context.getString(R.string.app_shortcut_top_tracks_long)
|
||||||
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_TOP_TRACKS))
|
).setIcon(
|
||||||
.build()
|
AppShortcutIconGenerator.generateThemedIcon(
|
||||||
|
context, R.drawable.ic_app_shortcut_top_tracks
|
||||||
|
)
|
||||||
|
).setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_TOP_TRACKS)).build()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
val id: String
|
val id: String
|
||||||
get() = BaseShortcutType.ID_PREFIX + "top_tracks"
|
get() = BaseShortcutType.ID_PREFIX + "top_tracks"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,154 +15,170 @@
|
||||||
package code.name.monkey.retromusic.appwidgets.base
|
package code.name.monkey.retromusic.appwidgets.base
|
||||||
|
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.*
|
||||||
import android.appwidget.AppWidgetProvider
|
import android.content.*
|
||||||
import android.content.ComponentName
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.graphics.*
|
import android.graphics.*
|
||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.*
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import code.name.monkey.retromusic.App
|
import code.name.monkey.retromusic.*
|
||||||
import code.name.monkey.retromusic.R
|
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.service.MusicService
|
import code.name.monkey.retromusic.service.MusicService
|
||||||
import code.name.monkey.retromusic.service.MusicService.*
|
import code.name.monkey.retromusic.service.MusicService.*
|
||||||
|
|
||||||
abstract class BaseAppWidget : AppWidgetProvider() {
|
abstract class BaseAppWidget : AppWidgetProvider() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager,
|
override fun onUpdate(
|
||||||
appWidgetIds: IntArray) {
|
context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray
|
||||||
defaultAppWidget(context, appWidgetIds)
|
) {
|
||||||
val updateIntent = Intent(APP_WIDGET_UPDATE)
|
defaultAppWidget(context, appWidgetIds)
|
||||||
updateIntent.putExtra(EXTRA_APP_WIDGET_NAME, NAME)
|
val updateIntent = Intent(APP_WIDGET_UPDATE)
|
||||||
updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds)
|
updateIntent.putExtra(EXTRA_APP_WIDGET_NAME, NAME)
|
||||||
updateIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
|
updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds)
|
||||||
context.sendBroadcast(updateIntent)
|
updateIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
|
||||||
}
|
context.sendBroadcast(updateIntent)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a change notification coming over from [MusicService]
|
* Handle a change notification coming over from [MusicService]
|
||||||
*/
|
*/
|
||||||
fun notifyChange(service: MusicService, what: String) {
|
fun notifyChange(service: MusicService, what: String) {
|
||||||
if (hasInstances(service)) {
|
if (hasInstances(service)) {
|
||||||
if (META_CHANGED == what || PLAY_STATE_CHANGED == what) {
|
if (META_CHANGED == what || PLAY_STATE_CHANGED == what) {
|
||||||
performUpdate(service, null)
|
performUpdate(service, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun pushUpdate(context: Context, appWidgetIds: IntArray?,
|
protected fun pushUpdate(
|
||||||
views: RemoteViews) {
|
context: Context, appWidgetIds: IntArray?, views: RemoteViews
|
||||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
) {
|
||||||
if (appWidgetIds != null) {
|
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||||
appWidgetManager.updateAppWidget(appWidgetIds, views)
|
if (appWidgetIds != null) {
|
||||||
} else {
|
appWidgetManager.updateAppWidget(appWidgetIds, views)
|
||||||
appWidgetManager.updateAppWidget(ComponentName(context, javaClass), views)
|
} else {
|
||||||
}
|
appWidgetManager.updateAppWidget(ComponentName(context, javaClass), views)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check against [AppWidgetManager] if there are any instances of this widget.
|
* Check against [AppWidgetManager] if there are any instances of this widget.
|
||||||
*/
|
*/
|
||||||
private fun hasInstances(context: Context): Boolean {
|
private fun hasInstances(context: Context): Boolean {
|
||||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||||
val mAppWidgetIds = appWidgetManager.getAppWidgetIds(ComponentName(context,
|
val mAppWidgetIds = appWidgetManager.getAppWidgetIds(
|
||||||
javaClass))
|
ComponentName(
|
||||||
return mAppWidgetIds.isNotEmpty()
|
context, javaClass
|
||||||
}
|
)
|
||||||
|
)
|
||||||
|
return mAppWidgetIds.isNotEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
protected fun buildPendingIntent(context: Context, action: String,
|
protected fun buildPendingIntent(
|
||||||
serviceName: ComponentName): PendingIntent {
|
context: Context, action: String, serviceName: ComponentName
|
||||||
val intent = Intent(action)
|
): PendingIntent {
|
||||||
intent.component = serviceName
|
val intent = Intent(action)
|
||||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
intent.component = serviceName
|
||||||
PendingIntent.getForegroundService(context, 0, intent, 0)
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
} else {
|
PendingIntent.getForegroundService(context, 0, intent, 0)
|
||||||
PendingIntent.getService(context, 0, intent, 0)
|
} else {
|
||||||
}
|
PendingIntent.getService(context, 0, intent, 0)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract fun defaultAppWidget(context: Context, appWidgetIds: IntArray)
|
protected abstract fun defaultAppWidget(context: Context, appWidgetIds: IntArray)
|
||||||
|
|
||||||
abstract fun performUpdate(service: MusicService, appWidgetIds: IntArray?)
|
abstract fun performUpdate(service: MusicService, appWidgetIds: IntArray?)
|
||||||
|
|
||||||
protected fun getAlbumArtDrawable(resources: Resources, bitmap: Bitmap?): Drawable {
|
protected fun getAlbumArtDrawable(resources: Resources, bitmap: Bitmap?): Drawable {
|
||||||
return if (bitmap == null) {
|
return if (bitmap == null) {
|
||||||
ContextCompat.getDrawable(App.getContext(), R.drawable.default_album_art)!!
|
ContextCompat.getDrawable(App.getContext(), R.drawable.default_album_art)!!
|
||||||
} else {
|
} else {
|
||||||
BitmapDrawable(resources, bitmap)
|
BitmapDrawable(resources, bitmap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun getSongArtistAndAlbum(song: Song): String {
|
protected fun getSongArtistAndAlbum(song: Song): String {
|
||||||
val builder = StringBuilder()
|
val builder = StringBuilder()
|
||||||
builder.append(song.artistName)
|
builder.append(song.artistName)
|
||||||
if (!TextUtils.isEmpty(song.artistName) && !TextUtils.isEmpty(song.albumName)) {
|
if (!TextUtils.isEmpty(song.artistName) && !TextUtils.isEmpty(song.albumName)) {
|
||||||
builder.append(" • ")
|
builder.append(" • ")
|
||||||
}
|
}
|
||||||
builder.append(song.albumName)
|
builder.append(song.albumName)
|
||||||
return builder.toString()
|
return builder.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
const val NAME: String = "app_widget"
|
const val NAME: String = "app_widget"
|
||||||
|
|
||||||
|
fun createRoundedBitmap(
|
||||||
|
drawable: Drawable?,
|
||||||
|
width: Int,
|
||||||
|
height: Int,
|
||||||
|
tl: Float,
|
||||||
|
tr: Float,
|
||||||
|
bl: Float,
|
||||||
|
br: Float
|
||||||
|
): Bitmap? {
|
||||||
|
if (drawable == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
fun createRoundedBitmap(drawable: Drawable?, width: Int, height: Int, tl: Float,
|
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||||
tr: Float, bl: Float, br: Float): Bitmap? {
|
val c = Canvas(bitmap)
|
||||||
if (drawable == null) {
|
drawable.setBounds(0, 0, width, height)
|
||||||
return null
|
drawable.draw(c)
|
||||||
}
|
|
||||||
|
|
||||||
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
val rounded = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||||
val c = Canvas(bitmap)
|
|
||||||
drawable.setBounds(0, 0, width, height)
|
|
||||||
drawable.draw(c)
|
|
||||||
|
|
||||||
val rounded = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
val canvas = Canvas(rounded)
|
||||||
|
val paint = Paint()
|
||||||
|
paint.shader = BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
|
||||||
|
paint.isAntiAlias = true
|
||||||
|
canvas.drawPath(
|
||||||
|
composeRoundedRectPath(
|
||||||
|
RectF(0f, 0f, width.toFloat(), height.toFloat()), tl, tr, bl, br
|
||||||
|
), paint
|
||||||
|
)
|
||||||
|
|
||||||
val canvas = Canvas(rounded)
|
return rounded
|
||||||
val paint = Paint()
|
}
|
||||||
paint.shader = BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
|
|
||||||
paint.isAntiAlias = true
|
|
||||||
canvas.drawPath(composeRoundedRectPath(RectF(0f, 0f, width.toFloat(), height.toFloat()), tl, tr, bl, br), paint)
|
|
||||||
|
|
||||||
return rounded
|
fun createBitmap(drawable: Drawable, sizeMultiplier: Float): Bitmap {
|
||||||
}
|
val bitmap = Bitmap.createBitmap(
|
||||||
|
(drawable.intrinsicWidth * sizeMultiplier).toInt(),
|
||||||
|
(drawable.intrinsicHeight * sizeMultiplier).toInt(),
|
||||||
|
Bitmap.Config.ARGB_8888
|
||||||
|
)
|
||||||
|
val c = Canvas(bitmap)
|
||||||
|
drawable.setBounds(0, 0, c.width, c.height)
|
||||||
|
drawable.draw(c)
|
||||||
|
return bitmap
|
||||||
|
}
|
||||||
|
|
||||||
fun createBitmap(drawable: Drawable, sizeMultiplier: Float): Bitmap {
|
protected fun composeRoundedRectPath(
|
||||||
val bitmap = Bitmap.createBitmap((drawable.intrinsicWidth * sizeMultiplier).toInt(),
|
rect: RectF, tl: Float, tr: Float, bl: Float, br: Float
|
||||||
(drawable.intrinsicHeight * sizeMultiplier).toInt(), Bitmap.Config.ARGB_8888)
|
): Path {
|
||||||
val c = Canvas(bitmap)
|
val path = Path()
|
||||||
drawable.setBounds(0, 0, c.width, c.height)
|
path.moveTo(rect.left + tl, rect.top)
|
||||||
drawable.draw(c)
|
path.lineTo(rect.right - tr, rect.top)
|
||||||
return bitmap
|
path.quadTo(rect.right, rect.top, rect.right, rect.top + tr)
|
||||||
}
|
path.lineTo(rect.right, rect.bottom - br)
|
||||||
|
path.quadTo(rect.right, rect.bottom, rect.right - br, rect.bottom)
|
||||||
|
path.lineTo(rect.left + bl, rect.bottom)
|
||||||
|
path.quadTo(rect.left, rect.bottom, rect.left, rect.bottom - bl)
|
||||||
|
path.lineTo(rect.left, rect.top + tl)
|
||||||
|
path.quadTo(rect.left, rect.top, rect.left + tl, rect.top)
|
||||||
|
path.close()
|
||||||
|
|
||||||
protected fun composeRoundedRectPath(rect: RectF, tl: Float, tr: Float, bl: Float, br: Float): Path {
|
return path
|
||||||
val path = Path()
|
}
|
||||||
path.moveTo(rect.left + tl, rect.top)
|
}
|
||||||
path.lineTo(rect.right - tr, rect.top)
|
|
||||||
path.quadTo(rect.right, rect.top, rect.right, rect.top + tr)
|
|
||||||
path.lineTo(rect.right, rect.bottom - br)
|
|
||||||
path.quadTo(rect.right, rect.bottom, rect.right - br, rect.bottom)
|
|
||||||
path.lineTo(rect.left + bl, rect.bottom)
|
|
||||||
path.quadTo(rect.left, rect.bottom, rect.left, rect.bottom - bl)
|
|
||||||
path.lineTo(rect.left, rect.top + tl)
|
|
||||||
path.quadTo(rect.left, rect.top, rect.left + tl, rect.top)
|
|
||||||
path.close()
|
|
||||||
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,19 +4,13 @@ import android.animation.ValueAnimator
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.palette.graphics.Palette
|
import androidx.palette.graphics.Palette
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.*
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
|
||||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
|
||||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
import code.name.monkey.retromusic.glide.*
|
||||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
|
||||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
|
@ -27,160 +21,169 @@ import kotlinx.android.synthetic.main.fragment_color_player.*
|
||||||
|
|
||||||
class ColorFragment : AbsPlayerFragment() {
|
class ColorFragment : AbsPlayerFragment() {
|
||||||
|
|
||||||
private var lastColor: Int = 0
|
private var lastColor: Int = 0
|
||||||
private var backgroundColor: Int = 0
|
private var backgroundColor: Int = 0
|
||||||
private var playbackControlsFragment: ColorPlaybackControlsFragment? = null
|
private var playbackControlsFragment: ColorPlaybackControlsFragment? = null
|
||||||
private var valueAnimator: ValueAnimator? = null
|
private var valueAnimator: ValueAnimator? = null
|
||||||
|
|
||||||
override fun playerToolbar(): Toolbar {
|
override fun playerToolbar(): Toolbar {
|
||||||
return playerToolbar
|
return playerToolbar
|
||||||
}
|
}
|
||||||
|
|
||||||
override val paletteColor: Int
|
override val paletteColor: Int
|
||||||
get() = backgroundColor
|
get() = backgroundColor
|
||||||
|
|
||||||
override fun onColorChanged(color: Int) {
|
override fun onColorChanged(color: Int) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFavoriteToggled() {
|
override fun onFavoriteToggled() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onShow() {
|
override fun onShow() {
|
||||||
playbackControlsFragment!!.show()
|
playbackControlsFragment!!.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onHide() {
|
override fun onHide() {
|
||||||
playbackControlsFragment!!.hide()
|
playbackControlsFragment!!.hide()
|
||||||
onBackPressed()
|
onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed(): Boolean {
|
override fun onBackPressed(): Boolean {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toolbarIconColor(): Int {
|
override fun toolbarIconColor(): Int {
|
||||||
return lastColor
|
return lastColor
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toggleFavorite(song: Song) {
|
override fun toggleFavorite(song: Song) {
|
||||||
super.toggleFavorite(song)
|
super.toggleFavorite(song)
|
||||||
if (song.id == MusicPlayerRemote.currentSong.id) {
|
if (song.id == MusicPlayerRemote.currentSong.id) {
|
||||||
updateIsFavorite()
|
updateIsFavorite()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
if (valueAnimator != null) {
|
if (valueAnimator != null) {
|
||||||
valueAnimator!!.cancel()
|
valueAnimator!!.cancel()
|
||||||
valueAnimator = null
|
valueAnimator = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
override fun onCreateView(
|
||||||
savedInstanceState: Bundle?): View? {
|
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
|
||||||
return inflater.inflate(R.layout.fragment_color_player, container, false)
|
return inflater.inflate(R.layout.fragment_color_player, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
setUpSubFragments()
|
setUpSubFragments()
|
||||||
setUpPlayerToolbar()
|
setUpPlayerToolbar()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpSubFragments() {
|
private fun setUpSubFragments() {
|
||||||
playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as ColorPlaybackControlsFragment?
|
playbackControlsFragment = childFragmentManager.findFragmentById(
|
||||||
|
R.id.playbackControlsFragment
|
||||||
|
) as ColorPlaybackControlsFragment?
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpPlayerToolbar() {
|
private fun setUpPlayerToolbar() {
|
||||||
playerToolbar.apply {
|
playerToolbar.apply {
|
||||||
inflateMenu(R.menu.menu_player)
|
inflateMenu(R.menu.menu_player)
|
||||||
setNavigationOnClickListener { requireActivity().onBackPressed() }
|
setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||||
setOnMenuItemClickListener(this@ColorFragment)
|
setOnMenuItemClickListener(this@ColorFragment)
|
||||||
ToolbarContentTintHelper.colorizeToolbar(this, ATHUtil.resolveColor(context, R.attr.iconColor), activity)
|
ToolbarContentTintHelper.colorizeToolbar(
|
||||||
}
|
this, ATHUtil.resolveColor(
|
||||||
}
|
context, R.attr.iconColor
|
||||||
|
), activity
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onPlayingMetaChanged() {
|
override fun onPlayingMetaChanged() {
|
||||||
super.onPlayingMetaChanged()
|
super.onPlayingMetaChanged()
|
||||||
updateSong()
|
updateSong()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onServiceConnected() {
|
override fun onServiceConnected() {
|
||||||
super.onServiceConnected()
|
super.onServiceConnected()
|
||||||
updateSong()
|
updateSong()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSong() {
|
private fun updateSong() {
|
||||||
SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
|
SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
|
||||||
.checkIgnoreMediaStore(requireContext())
|
.checkIgnoreMediaStore(requireContext()).generatePalette(requireContext()).build()
|
||||||
.generatePalette(requireContext())
|
.into(object : RetroMusicColoredTarget(playerImage) {
|
||||||
.build()
|
override fun onColorReady(color: Int) {
|
||||||
.into(object : RetroMusicColoredTarget(playerImage) {
|
|
||||||
override fun onColorReady(color: Int) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResourceReady(resource: BitmapPaletteWrapper?, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
|
override fun onResourceReady(
|
||||||
super.onResourceReady(resource, glideAnimation)
|
resource: BitmapPaletteWrapper?,
|
||||||
resource?.let {
|
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?
|
||||||
val background = resource.palette.getColor()
|
) {
|
||||||
|
super.onResourceReady(resource, glideAnimation)
|
||||||
|
resource?.let {
|
||||||
|
val background = resource.palette.getColor()
|
||||||
|
|
||||||
val palette = resource.palette
|
val palette = resource.palette
|
||||||
val swatch = RetroColorUtil.getSwatch(palette)
|
val swatch = RetroColorUtil.getSwatch(palette)
|
||||||
|
|
||||||
val textColor = RetroColorUtil.getTextColor(palette)
|
val textColor = RetroColorUtil.getTextColor(palette)
|
||||||
val backgroundColor = swatch.rgb
|
val backgroundColor = swatch.rgb
|
||||||
|
|
||||||
setColors(backgroundColor, textColor)
|
setColors(backgroundColor, textColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
|
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
|
||||||
super.onLoadFailed(e, errorDrawable)
|
super.onLoadFailed(e, errorDrawable)
|
||||||
val backgroundColor = defaultFooterColor
|
val backgroundColor = defaultFooterColor
|
||||||
val textColor = if (ColorUtil.isColorLight(defaultFooterColor))
|
val textColor = if (ColorUtil.isColorLight(defaultFooterColor)) MaterialValueHelper.getPrimaryTextColor(
|
||||||
MaterialValueHelper.getPrimaryTextColor(context, true)
|
context,
|
||||||
else
|
true
|
||||||
MaterialValueHelper.getPrimaryTextColor(context, false)
|
)
|
||||||
|
else MaterialValueHelper.getPrimaryTextColor(context, false)
|
||||||
|
|
||||||
setColors(backgroundColor, textColor)
|
setColors(backgroundColor, textColor)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setColors(backgroundColor: Int, textColor: Int) {
|
private fun setColors(
|
||||||
playbackControlsFragment!!.setDark(textColor, backgroundColor)
|
backgroundColor: Int, textColor: Int
|
||||||
colorGradientBackground?.setBackgroundColor(backgroundColor)
|
) {
|
||||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, textColor, activity)
|
playbackControlsFragment?.setDark(textColor, backgroundColor)
|
||||||
lastColor = textColor
|
colorGradientBackground?.setBackgroundColor(backgroundColor)
|
||||||
this.backgroundColor = backgroundColor
|
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, textColor, activity)
|
||||||
playerActivity?.setLightNavigationBar(ColorUtil.isColorLight(backgroundColor))
|
lastColor = textColor
|
||||||
callbacks?.onPaletteColorChanged()
|
this.backgroundColor = backgroundColor
|
||||||
}
|
playerActivity?.setLightNavigationBar(ColorUtil.isColorLight(backgroundColor))
|
||||||
|
callbacks?.onPaletteColorChanged()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
fun newInstance(): ColorFragment {
|
||||||
fun newInstance(): ColorFragment {
|
val args = Bundle()
|
||||||
val args = Bundle()
|
val fragment = ColorFragment()
|
||||||
val fragment = ColorFragment()
|
fragment.arguments = args
|
||||||
fragment.arguments = args
|
return fragment
|
||||||
return fragment
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun Palette.getColor(): Int {
|
fun Palette.getColor(): Int {
|
||||||
return when {
|
return when {
|
||||||
darkMutedSwatch != null -> darkMutedSwatch!!.rgb
|
darkMutedSwatch != null -> darkMutedSwatch!!.rgb
|
||||||
mutedSwatch != null -> mutedSwatch!!.rgb
|
mutedSwatch != null -> mutedSwatch!!.rgb
|
||||||
lightMutedSwatch != null -> lightMutedSwatch!!.rgb
|
lightMutedSwatch != null -> lightMutedSwatch!!.rgb
|
||||||
else -> Palette.Swatch(Color.BLACK, 1).rgb
|
else -> Palette.Swatch(Color.BLACK, 1).rgb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2019 Hemanth Savarala.
|
|
||||||
*
|
|
||||||
* Licensed under the GNU General Public License v3
|
|
||||||
*
|
|
||||||
* This is free software: you can redistribute it and/or modify it under
|
|
||||||
* the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package code.name.monkey.retromusic.helper
|
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import androidx.core.app.ActivityCompat
|
|
||||||
import code.name.monkey.retromusic.App
|
|
||||||
import code.name.monkey.retromusic.activities.bugreport.ErrorHandlerActivity
|
|
||||||
|
|
||||||
class TopExceptionHandler() : Thread.UncaughtExceptionHandler {
|
|
||||||
private val defaultUEH: Thread.UncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler()
|
|
||||||
|
|
||||||
override fun uncaughtException(t: Thread, e: Throwable) {
|
|
||||||
var arr = e.stackTrace
|
|
||||||
var report = e.toString() + "\n\n"
|
|
||||||
|
|
||||||
report += "--------- Stack trace ---------\n\n"
|
|
||||||
for (i in arr.indices) {
|
|
||||||
report += " " + arr[i].toString() + "\n"
|
|
||||||
}
|
|
||||||
report += "-------------------------------\n\n"
|
|
||||||
|
|
||||||
// If the exception was thrown in a background thread inside
|
|
||||||
// AsyncTask, then the actual exception can be found with getCause
|
|
||||||
|
|
||||||
report += "--------- Cause ---------\n\n"
|
|
||||||
val cause = e.cause
|
|
||||||
if (cause != null) {
|
|
||||||
report += cause.toString() + "\n\n"
|
|
||||||
arr = cause.stackTrace
|
|
||||||
for (i in arr.indices) {
|
|
||||||
report += " " + arr[i].toString() + "\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
report += "-------------------------------\n\n"
|
|
||||||
ActivityCompat.startActivity(App.getContext(), Intent(App.getContext(), ErrorHandlerActivity::class.java)
|
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
.putExtra("error", report), null)
|
|
||||||
defaultUEH.uncaughtException(t, e)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,7 +14,9 @@
|
||||||
|
|
||||||
package code.name.monkey.retromusic.util;
|
package code.name.monkey.retromusic.util;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
@ -78,35 +80,38 @@ public class LyricUtil {
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static File getLocalLyricFile(@NonNull String title, @NonNull String artist) {
|
public static File getLocalLyricFile(@NonNull String title, @NonNull String artist) {
|
||||||
try{
|
try {
|
||||||
File file = new File(getLrcPath(title, artist));
|
File file = new File(getLrcPath(title, artist));
|
||||||
File file2 = new File(getLrcPath2(title, artist));
|
File file2 = new File(getLrcPath2(title, artist));
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
|
|
||||||
return file;
|
|
||||||
} else if (file2.exists()) {
|
|
||||||
|
|
||||||
return file2;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
return new File("lyric file not exist");
|
return file;
|
||||||
}} catch (Exception dfs){
|
} else if (file2.exists()) {
|
||||||
|
|
||||||
|
return file2;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return new File("lyric file not exist");
|
||||||
|
}
|
||||||
|
} catch (Exception dfs) {
|
||||||
dfs.printStackTrace();
|
dfs.printStackTrace();
|
||||||
return new File("lyric file not exist");
|
return new File("lyric file not exist");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getLrcPath2(String title, String artist) {
|
public static String getLrcPath2(String title, String artist) {
|
||||||
String x2;
|
Log.i("HEM", "getLrcPath2: " + title);
|
||||||
if(title.endsWith(".flac")||title.endsWith(".mogg")||title.endsWith(".alac")||title.endsWith(".aiff")||title.endsWith(".webv")){
|
if (!TextUtils.isEmpty(title)) {
|
||||||
x2= title.substring(0, title.length() -5 ) + ".lrc";
|
String x2;
|
||||||
|
if (title.endsWith(".flac") || title.endsWith(".mogg") || title.endsWith(".alac") || title.endsWith(".aiff") || title.endsWith(".webv")) {
|
||||||
|
x2 = title.substring(0, title.length() - 5) + ".lrc";
|
||||||
|
} else {
|
||||||
|
x2 = title.substring(0, title.length() - 4) + ".lrc";
|
||||||
|
}
|
||||||
|
return x2;
|
||||||
}
|
}
|
||||||
else{
|
return "";
|
||||||
x2= title.substring(0, title.length() -4 ) + ".lrc";}
|
|
||||||
|
|
||||||
|
|
||||||
return x2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getLrcPath(String title, String artist) {
|
public static String getLrcPath(String title, String artist) {
|
||||||
|
@ -135,7 +140,7 @@ public class LyricUtil {
|
||||||
File file;
|
File file;
|
||||||
File file2 = new File(getLrcPath(title, artist));
|
File file2 = new File(getLrcPath(title, artist));
|
||||||
File file3 = new File(getLrcPath2(title, artist));
|
File file3 = new File(getLrcPath2(title, artist));
|
||||||
if(file2.exists()){
|
if (file2.exists()) {
|
||||||
file = file2;
|
file = file2;
|
||||||
} else {
|
} else {
|
||||||
file = file3;
|
file = file3;
|
||||||
|
@ -143,7 +148,7 @@ public class LyricUtil {
|
||||||
FileInputStream fin = new FileInputStream(file);
|
FileInputStream fin = new FileInputStream(file);
|
||||||
String ret = convertStreamToString(fin);
|
String ret = convertStreamToString(fin);
|
||||||
fin.close();
|
fin.close();
|
||||||
// Log.d("damn2",ret);
|
// Log.d("damn2",ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,4 +6,6 @@ android.useAndroidX=true
|
||||||
android.enabelR8=true
|
android.enabelR8=true
|
||||||
android.enableR8.fullMode=false
|
android.enableR8.fullMode=false
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
android.debug.obsoleteApi=true
|
android.debug.obsoleteApi=true
|
||||||
|
android.enableBuildCache=true
|
||||||
|
android.jetifier.blacklist = butterknife.*\\.jar
|
Loading…
Add table
Add a link
Reference in a new issue