Fix stroke in now playing

This commit is contained in:
hemanthStack 2019-11-13 13:07:46 +05:30
commit 339697f6c4
304 changed files with 13090 additions and 8693 deletions

61
.github/stale.yml vendored Normal file
View file

@ -0,0 +1,61 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 60
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 7
# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
onlyLabels: []
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- pinned
- security
- "[Status] Maybe Later"
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: false
# Set to true to ignore issues with an assignee (defaults to false)
exemptAssignees: false
# Label to use when marking as stale
staleLabel: stale
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when removing the stale label.
# unmarkComment: >
# Your comment here.
# Comment to post when closing a stale Issue or Pull Request.
# closeComment: >
# Your comment here.
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30
# Limit to only `issues` or `pulls`
# only: issues
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
# pulls:
# daysUntilStale: 30
# markComment: >
# This pull request has been automatically marked as stale because it has not had
# recent activity. It will be closed if no further activity occurs. Thank you
# for your contributions.
# issues:
# exemptLabels:
# - confirmed

View file

View file

@ -13,8 +13,8 @@ android {
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
applicationId "code.name.monkey.retromusic" applicationId "code.name.monkey.retromusic"
versionCode 379 versionCode 390
versionName '3.4.400-beta05' versionName '3.4.600'
multiDexEnabled true multiDexEnabled true
@ -83,6 +83,7 @@ android {
kapt { kapt {
generateStubs = true generateStubs = true
} }
} }
def getProperties(String fileName) { def getProperties(String fileName) {
@ -107,9 +108,9 @@ 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-alpha04' implementation 'androidx.fragment:fragment:1.2.0-rc01'
implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0-beta04' implementation 'androidx.recyclerview:recyclerview:1.1.0-rc01'
implementation "androidx.gridlayout:gridlayout:1.0.0" implementation "androidx.gridlayout:gridlayout:1.0.0"
implementation "androidx.cardview:cardview:1.0.0" implementation "androidx.cardview:cardview:1.0.0"
implementation "androidx.palette:palette:1.0.0" implementation "androidx.palette:palette:1.0.0"
@ -118,12 +119,12 @@ dependencies {
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 'com.google.android.material:material:1.1.0-beta01' 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.3'
implementation 'com.squareup.retrofit2:retrofit:2.6.1' implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.6.1' implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.1' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.2'
implementation 'com.afollestad.material-dialogs:core:3.1.1' implementation 'com.afollestad.material-dialogs:core:3.1.1'
implementation 'com.afollestad.material-dialogs:input:3.1.1' implementation 'com.afollestad.material-dialogs:input:3.1.1'
@ -147,6 +148,10 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1"
implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:3.4.0.201406110918-r' implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:3.4.0.201406110918-r'
implementation 'com.github.ksoichiro:android-observablescrollview:1.6.0' implementation 'com.github.ksoichiro:android-observablescrollview:1.6.0'
@ -163,4 +168,3 @@ dependencies {
} }

File diff suppressed because one or more lines are too long

View file

@ -12,22 +12,13 @@
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
*/ */
package code.name.monkey.retromusic.util.schedulers; package code.name.monkey.retromusic
import androidx.annotation.NonNull;
import io.reactivex.Scheduler;
/** /**
* Created by hemanths on 12/08/17. * Created by hemanths on 2019-10-23.
*/ */
public interface BaseSchedulerProvider { sealed class Result<out T : Any> {
@NonNull class Success<out T : Any>(val data: T) : Result<T>()
Scheduler computation(); class Error(val exception: Throwable) : Result<Nothing>()
@NonNull
Scheduler io();
@NonNull
Scheduler ui();
} }

View file

@ -9,7 +9,6 @@ import android.view.View
import androidx.core.app.ShareCompat import androidx.core.app.ShareCompat
import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper 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
@ -69,8 +68,8 @@ class AboutActivity : AbsBaseActivity(), View.OnClickListener {
loadContributors() loadContributors()
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
ToolbarContentTintHelper.colorBackButton(toolbar, ATHUtil.resolveColor(this, R.attr.colorOnSurface)) ToolbarContentTintHelper.colorBackButton(toolbar )
appVersion.text = getAppVersion() version.setSummary ( getAppVersion())
setUpView() setUpView()
} }

View file

@ -2,7 +2,6 @@ package code.name.monkey.retromusic.activities
import android.app.ActivityOptions import android.app.ActivityOptions
import android.content.Intent import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.transition.Slide import android.transition.Slide
@ -16,7 +15,6 @@ import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialUtil import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.App import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
@ -32,7 +30,6 @@ import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest 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.misc.AppBarStateChangeListener
import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsPresenter import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsPresenter
@ -40,9 +37,7 @@ import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsView
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.google.android.material.appbar.AppBarLayout
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
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.*
@ -66,6 +61,9 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
private fun setupWindowTransition() { private fun setupWindowTransition() {
val slide = Slide(Gravity.BOTTOM) val slide = Slide(Gravity.BOTTOM)
slide.excludeTarget(android.R.id.statusBarBackground, true)
slide.excludeTarget(android.R.id.navigationBarBackground, true)
slide.excludeTarget(toolbar, true)
slide.interpolator = AnimationUtils.loadInterpolator(this, android.R.interpolator.linear_out_slow_in) slide.interpolator = AnimationUtils.loadInterpolator(this, android.R.interpolator.linear_out_slow_in)
window.enterTransition = slide window.enterTransition = slide
} }
@ -75,21 +73,21 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar() setDrawUnderStatusBar()
setupWindowTransition() //setupWindowTransition()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
App.musicComponent.inject(this)
toggleBottomNavigationView(true) toggleBottomNavigationView(true)
setLightNavigationBar(true) setStatusbarColor(Color.TRANSPARENT)
setNavigationbarColorAuto() setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
setLightNavigationBar(true)
setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
contentContainer?.setCardBackgroundColor(ColorStateList.valueOf(ATHUtil.resolveColor(this, R.attr.colorPrimary))) App.musicComponent.inject(this)
postponeEnterTransition() postponeEnterTransition()
artistImage = findViewById(R.id.artistImage) artistImage = findViewById(R.id.artistImage)
setupRecyclerView() setupRecyclerView()
setupToolbarMarginHeight()
artistImage.setOnClickListener { artistImage.setOnClickListener {
val artistPairs = ActivityOptions.makeSceneTransitionAnimation(this, UtilPair.create(artistImage, getString(R.string.transition_artist_image))) val artistPairs = ActivityOptions.makeSceneTransitionAnimation(this, UtilPair.create(artistImage, getString(R.string.transition_artist_image)))
@ -122,43 +120,6 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
} }
} }
private fun setupToolbarMarginHeight() {
setSupportActionBar(toolbar)
supportActionBar?.title = null
val primaryColor = ATHUtil.resolveColor(this, R.attr.colorPrimary)
collapsingToolbarLayout?.let {
it.setContentScrimColor(primaryColor)
it.setStatusBarScrimColor(ColorUtil.darkenColor(primaryColor))
}
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
if (toolbar != null && !PreferenceUtil.getInstance(this).fullScreenMode) {
val params = toolbar.layoutParams as ViewGroup.MarginLayoutParams
params.topMargin = RetroUtil.getStatusBarHeight()
toolbar.layoutParams = params
}
appBarLayout?.apply {
addOnOffsetChangedListener(object : AppBarStateChangeListener() {
override fun onStateChanged(appBarLayout: AppBarLayout, state: State) {
val color: Int = when (state) {
State.COLLAPSED -> {
setLightStatusbar(ColorUtil.isColorLight(primaryColor))
primaryColor
}
State.EXPANDED, State.IDLE -> {
setLightStatusbar(false)
Color.TRANSPARENT
}
}
ToolbarContentTintHelper.setToolbarContentColorBasedOnToolbarColor(this@AlbumDetailsActivity, toolbar, color)
}
})
}
}
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
disposable.dispose() disposable.dispose()
@ -178,8 +139,11 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
this.album = album this.album = album
albumTitle.text = album.title albumTitle.text = album.title
albumText.text = String.format("%s • %s • %s", album.artistName, MusicUtil.getYearString(album.year), MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs))) if (MusicUtil.getYearString(album.year) == "-") {
albumText.text = String.format("%s • %s", album.artistName, MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs)))
} else {
albumText.text = String.format("%s • %s • %s", album.artistName, MusicUtil.getYearString(album.year), MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs)))
}
loadAlbumCover() loadAlbumCover()
simpleSongAdapter.swapDataSet(album.songs) simpleSongAdapter.swapDataSet(album.songs)
albumDetailsPresenter.loadMore(album.artistId) albumDetailsPresenter.loadMore(album.artistId)
@ -190,7 +154,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
override fun moreAlbums(albums: ArrayList<Album>) { override fun moreAlbums(albums: ArrayList<Album>) {
moreTitle.show() moreTitle.show()
moreRecyclerView.show() moreRecyclerView.show()
moreTitle.text = String.format("More from %s", album.artistName) moreTitle.text = String.format(getString(R.string.label_more_from), album.artistName)
val albumAdapter = HorizontalAlbumAdapter(this, albums, false, null) val albumAdapter = HorizontalAlbumAdapter(this, albums, false, null)
moreRecyclerView.layoutManager = GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false) moreRecyclerView.layoutManager = GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false)
@ -201,6 +165,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
ArtistGlideRequest.Builder.from(Glide.with(this), artist) ArtistGlideRequest.Builder.from(Glide.with(this), artist)
.generatePalette(this).build() .generatePalette(this).build()
.dontAnimate() .dontAnimate()
.dontTransform()
.into(object : RetroMusicColoredTarget(artistImage) { .into(object : RetroMusicColoredTarget(artistImage) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
@ -213,7 +178,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
SongGlideRequest.Builder.from(Glide.with(this), album.safeGetFirstSong()) SongGlideRequest.Builder.from(Glide.with(this), album.safeGetFirstSong())
.checkIgnoreMediaStore(this) .checkIgnoreMediaStore(this)
.generatePalette(this).build() .generatePalette(this).build()
.dontAnimate() .dontAnimate().dontTransform()
.into(object : RetroMusicColoredTarget(image) { .into(object : RetroMusicColoredTarget(image) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
setColors(color) setColors(color)
@ -244,7 +209,10 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
MaterialUtil.setTint(button = shuffleAction, color = buttonColor) MaterialUtil.setTint(button = shuffleAction, color = buttonColor)
MaterialUtil.setTint(button = playAction, color = buttonColor) MaterialUtil.setTint(button = playAction, color = buttonColor)
ToolbarContentTintHelper.setToolbarContentColorBasedOnToolbarColor(this@AlbumDetailsActivity, toolbar, color) toolbar.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
setSupportActionBar(toolbar)
supportActionBar?.title = null
} }

View file

@ -2,14 +2,16 @@ package code.name.monkey.retromusic.activities
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Color import android.graphics.Color
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.text.Html import android.text.Html
import android.text.Spanned import android.text.Spanned
import android.transition.Slide import android.transition.Slide
import android.view.* import android.view.Gravity
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.animation.AnimationUtils import android.view.animation.AnimationUtils
import android.widget.Toast import android.widget.Toast
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
@ -20,7 +22,6 @@ import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialUtil import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.App import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
@ -31,7 +32,6 @@ import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.glide.ArtistGlideRequest import code.name.monkey.retromusic.glide.ArtistGlideRequest
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget 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.misc.AppBarStateChangeListener
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.ArtistDetailsPresenter
import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsView import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsView
@ -39,7 +39,6 @@ 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.*
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.google.android.material.appbar.AppBarLayout
import kotlinx.android.synthetic.main.activity_artist_content.* import kotlinx.android.synthetic.main.activity_artist_content.*
import kotlinx.android.synthetic.main.activity_artist_details.* import kotlinx.android.synthetic.main.activity_artist_details.*
import java.util.* import java.util.*
@ -70,12 +69,14 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar() setDrawUnderStatusBar()
setupWindowTransitions() // setupWindowTransitions()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
contentContainer?.setCardBackgroundColor(ColorStateList.valueOf(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
toggleBottomNavigationView(true) toggleBottomNavigationView(true)
setStatusbarColor(Color.TRANSPARENT)
setNavigationbarColorAuto() setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
setLightNavigationBar(true) setLightNavigationBar(true)
setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
ActivityCompat.postponeEnterTransition(this) ActivityCompat.postponeEnterTransition(this)
@ -115,7 +116,6 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
private fun setUpViews() { private fun setUpViews() {
setupRecyclerView() setupRecyclerView()
setupToolbarMarginHeight()
setupContainerHeight() setupContainerHeight()
} }
@ -127,42 +127,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
} }
} }
private fun setupToolbarMarginHeight() {
val primaryColor = ATHUtil.resolveColor(this, R.attr.colorPrimary)
collapsingToolbarLayout?.let {
it.setContentScrimColor(primaryColor)
it.setStatusBarScrimColor(ColorUtil.darkenColor(primaryColor))
}
toolbar?.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
setSupportActionBar(toolbar)
supportActionBar?.title = null
if (toolbar != null && !PreferenceUtil.getInstance(this).fullScreenMode) {
val params = toolbar!!.layoutParams as ViewGroup.MarginLayoutParams
params.topMargin = RetroUtil.getStatusBarHeight()
toolbar!!.layoutParams = params
}
appBarLayout?.addOnOffsetChangedListener(object : AppBarStateChangeListener() {
override fun onStateChanged(appBarLayout: AppBarLayout, state: State) {
val color: Int = when (state) {
State.COLLAPSED -> {
setLightStatusbar(ColorUtil.isColorLight(primaryColor))
primaryColor
}
State.EXPANDED, State.IDLE -> {
setLightStatusbar(false)
Color.TRANSPARENT
}
}
ToolbarContentTintHelper.setToolbarContentColorBasedOnToolbarColor(appBarLayout.context, toolbar, color)
}
})
setColors(ThemeStore.accentColor(this))
}
private fun setupRecyclerView() { private fun setupRecyclerView() {
albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), false, null) albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), false, null)
@ -261,7 +226,8 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
private fun setColors(color: Int) { private fun setColors(color: Int) {
val textColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color else ThemeStore.accentColor(this) val textColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color
else ThemeStore.accentColor(this)
albumTitle.setTextColor(textColor) albumTitle.setTextColor(textColor)
songTitle.setTextColor(textColor) songTitle.setTextColor(textColor)
@ -272,6 +238,10 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
MaterialUtil.setTint(button = shuffleAction, color = buttonColor) MaterialUtil.setTint(button = shuffleAction, color = buttonColor)
MaterialUtil.setTint(button = playAction, color = buttonColor) MaterialUtil.setTint(button = playAction, color = buttonColor)
toolbar.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
setSupportActionBar(toolbar)
supportActionBar?.title = null
} }

View file

@ -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;
@ -66,7 +65,7 @@ public class LicenseActivity extends AbsBaseActivity {
setLightNavigationBar(true); setLightNavigationBar(true);
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
ToolbarContentTintHelper.colorBackButton(toolbar, ATHUtil.INSTANCE.resolveColor(this, R.attr.colorOnSurface)); ToolbarContentTintHelper.colorBackButton(toolbar );
WebView webView = findViewById(R.id.license); WebView webView = findViewById(R.id.license);
try { try {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();

View file

@ -150,8 +150,13 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
private fun showSyncedLyrics() { private fun showSyncedLyrics() {
var content = "" var content = ""
try { try {
content = LyricUtil.getStringFromFile(song.title, song.artistName) content = LyricUtil.getStringFromFile(song.data, song.artistName)
} catch (e: Exception) { } catch (e: Exception) {
try {
content = LyricUtil.getStringFromFile(song.title, song.artistName)
} catch (e2: Exception) {
}
e.printStackTrace() e.printStackTrace()
} }
@ -161,7 +166,7 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
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.title, song.artistName, input.toString()) LyricUtil.writeLrcToLoc(song.data, song.artistName, input.toString())
} }
positiveButton(android.R.string.ok) { positiveButton(android.R.string.ok) {
updateSong() updateSong()
@ -215,7 +220,7 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
return baseUrl return baseUrl
} }
class PagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { class PagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
class Tabs(@StringRes val title: Int, class Tabs(@StringRes val title: Int,
val fragment: Fragment) val fragment: Fragment)
@ -364,8 +369,12 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
private fun loadLRCLyrics() { private fun loadLRCLyrics() {
val song = MusicPlayerRemote.currentSong val song = MusicPlayerRemote.currentSong
if (LyricUtil.isLrcFileExist(song.title, song.artistName)) { if (LyricUtil.isLrcFile2Exist(song.data, song.artistName)) {
showLyricsLocal(LyricUtil.getLocalLyricFile(song.title, song.artistName)) showLyricsLocal(LyricUtil.getLocalLyricFile(song.data, song.artistName))
} else {
if (LyricUtil.isLrcFileExist(song.title, song.artistName)) {
showLyricsLocal(LyricUtil.getLocalLyricFile(song.title, song.artistName))
}
} }
} }

View file

@ -19,7 +19,7 @@ import code.name.monkey.retromusic.loaders.AlbumLoader
import code.name.monkey.retromusic.loaders.ArtistLoader import code.name.monkey.retromusic.loaders.ArtistLoader
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader 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.transform.AppRater import code.name.monkey.retromusic.util.AppRater
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import java.util.* import java.util.*
@ -64,7 +64,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
} }
if (savedInstanceState == null) { if (savedInstanceState == null) {
selectedFragment(PreferenceUtil.getInstance(this).lastPage) setMusicChooser(PreferenceUtil.getInstance(this).lastMusicChooser)
} else { } else {
restoreCurrentFragment() restoreCurrentFragment()
} }
@ -129,7 +129,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
val uri = intent.data val uri = intent.data
val mimeType = intent.type val mimeType = intent.type
var handled = false var handled = false
println("uri -> $uri")
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) {
@ -222,7 +221,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
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.BLACK_THEME ||
key == PreferenceUtil.ADAPTIVE_COLOR_APP || key == PreferenceUtil.ADAPTIVE_COLOR_APP ||
key == PreferenceUtil.DOMINANT_COLOR || key == PreferenceUtil.DOMINANT_COLOR ||
key == PreferenceUtil.USER_NAME || key == PreferenceUtil.USER_NAME ||
@ -244,6 +243,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
key == PreferenceUtil.ALBUM_COVER_STYLE || key == PreferenceUtil.ALBUM_COVER_STYLE ||
key == PreferenceUtil.HOME_ARTIST_GRID_STYLE || key == PreferenceUtil.HOME_ARTIST_GRID_STYLE ||
key == PreferenceUtil.ALBUM_COVER_TRANSFORM || key == PreferenceUtil.ALBUM_COVER_TRANSFORM ||
key == PreferenceUtil.DESATURATED_COLOR ||
key == PreferenceUtil.TAB_TEXT_MODE || key == PreferenceUtil.TAB_TEXT_MODE ||
key == PreferenceUtil.LIBRARY_CATEGORIES) key == PreferenceUtil.LIBRARY_CATEGORIES)
postRecreate() postRecreate()
@ -264,7 +264,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
}*/ }*/
} }
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_artist,
@ -272,16 +272,25 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
R.id.action_genre, R.id.action_genre,
R.id.action_song -> setCurrentFragment(LibraryFragment.newInstance(itemId), itemId.toString()) R.id.action_song -> setCurrentFragment(LibraryFragment.newInstance(itemId), itemId.toString())
R.id.action_home -> setCurrentFragment(BannerHomeFragment.newInstance(), BannerHomeFragment.TAG) R.id.action_home -> setCurrentFragment(BannerHomeFragment.newInstance(), BannerHomeFragment.TAG)
R.id.action_folder -> setCurrentFragment(FoldersFragment.newInstance(this), FoldersFragment.TAG)
else -> { else -> {
setCurrentFragment(BannerHomeFragment.newInstance(), BannerHomeFragment.TAG) setCurrentFragment(BannerHomeFragment.newInstance(), BannerHomeFragment.TAG)
} }
} }
} }
fun setMusicChooser(key: Int) {
PreferenceUtil.getInstance(this).lastMusicChooser = key
when (key) {
FOLDER -> setCurrentFragment(FoldersFragment.newInstance(this), FoldersFragment.TAG)
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 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

View file

@ -14,6 +14,7 @@ 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.DensityUtil
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
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
@ -21,7 +22,7 @@ import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
import kotlinx.android.synthetic.main.activity_playing_queue.* import kotlinx.android.synthetic.main.activity_playing_queue.*
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
@ -29,7 +30,7 @@ class PlayingQueueActivity : AbsMusicServiceActivity() {
private lateinit var linearLayoutManager: LinearLayoutManager private lateinit var linearLayoutManager: LinearLayoutManager
protected fun getUpNextAndQueueTime(): String { private fun getUpNextAndQueueTime(): String {
val duration = MusicPlayerRemote.getQueueDurationMillis(MusicPlayerRemote.position) val duration = MusicPlayerRemote.getQueueDurationMillis(MusicPlayerRemote.position)
return MusicUtil.buildInfoString( return MusicUtil.buildInfoString(
@ -55,6 +56,7 @@ class PlayingQueueActivity : AbsMusicServiceActivity() {
clearQueue.setOnClickListener { clearQueue.setOnClickListener {
MusicPlayerRemote.clearQueue() MusicPlayerRemote.clearQueue()
} }
checkForPadding()
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
@ -76,7 +78,7 @@ class PlayingQueueActivity : AbsMusicServiceActivity() {
MusicPlayerRemote.playingQueue, MusicPlayerRemote.playingQueue,
MusicPlayerRemote.position, MusicPlayerRemote.position,
R.layout.item_queue) R.layout.item_queue)
wrappedAdapter = recyclerViewDragDropManager!!.createWrappedAdapter(playingQueueAdapter!!) wrappedAdapter = recyclerViewDragDropManager?.createWrappedAdapter(playingQueueAdapter!!)
linearLayoutManager = LinearLayoutManager(this) linearLayoutManager = LinearLayoutManager(this)
@ -84,7 +86,7 @@ class PlayingQueueActivity : AbsMusicServiceActivity() {
layoutManager = linearLayoutManager layoutManager = linearLayoutManager
adapter = wrappedAdapter adapter = wrappedAdapter
itemAnimator = animator itemAnimator = animator
recyclerViewDragDropManager!!.attachRecyclerView(this) recyclerViewDragDropManager?.attachRecyclerView(this)
} }
linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0) linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
@ -101,11 +103,17 @@ class PlayingQueueActivity : AbsMusicServiceActivity() {
}) })
} }
private fun checkForPadding() {
val height = DensityUtil.dip2px(this, 102f)
recyclerView.setPadding(0, 0, 0, (height))
}
override fun onQueueChanged() { override fun onQueueChanged() {
if (MusicPlayerRemote.playingQueue.isEmpty()) { if (MusicPlayerRemote.playingQueue.isEmpty()) {
finish() finish()
return return
} }
checkForPadding()
updateQueue() updateQueue()
updateCurrentSong() updateCurrentSong()
} }
@ -124,13 +132,13 @@ class PlayingQueueActivity : AbsMusicServiceActivity() {
} }
private fun updateQueuePosition() { private fun updateQueuePosition() {
playingQueueAdapter!!.setCurrent(MusicPlayerRemote.position) playingQueueAdapter?.setCurrent(MusicPlayerRemote.position)
resetToCurrentPosition() resetToCurrentPosition()
playerQueueSubHeader.text = getUpNextAndQueueTime() playerQueueSubHeader.text = getUpNextAndQueueTime()
} }
private fun updateQueue() { private fun updateQueue() {
playingQueueAdapter!!.swapDataSet(MusicPlayerRemote.playingQueue, MusicPlayerRemote.position) playingQueueAdapter?.swapDataSet(MusicPlayerRemote.playingQueue, MusicPlayerRemote.position)
resetToCurrentPosition() resetToCurrentPosition()
} }

View file

@ -25,6 +25,7 @@ import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsPresenter import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsPresenter
import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsView 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.PlaylistsUtil
import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroColorUtil
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ViewUtil
@ -50,6 +51,9 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar() setDrawUnderStatusBar()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
App.musicComponent.inject(this)
playlistSongsPresenter.attachView(this)
setStatusbarColor(Color.TRANSPARENT) setStatusbarColor(Color.TRANSPARENT)
setNavigationbarColorAuto() setNavigationbarColorAuto()
@ -65,10 +69,6 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
finish() finish()
} }
App.musicComponent.inject(this)
playlistSongsPresenter.attachView(this)
setUpToolBar() setUpToolBar()
setUpRecyclerView() setUpRecyclerView()
} }
@ -160,14 +160,12 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
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) {
@ -182,8 +180,13 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
supportActionBar!!.title = title supportActionBar!!.title = title
} }
private fun checkIsEmpty() { private fun checkForPadding() {
val height = DensityUtil.dip2px(this, 52f)
recyclerView.setPadding(0, 0, 0, (height ))
}
private fun checkIsEmpty() {
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
} }

View file

@ -1,10 +1,8 @@
package code.name.monkey.retromusic.activities package code.name.monkey.retromusic.activities
import android.app.Activity import android.app.Activity
import android.app.SearchManager
import android.app.Service import android.app.Service
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.os.Bundle import android.os.Bundle
@ -77,6 +75,10 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch
keyboardPopup.setTextColor(this) keyboardPopup.setTextColor(this)
keyboardPopup.iconTint = this keyboardPopup.iconTint = this
} }
if (savedInstanceState != null) {
query = savedInstanceState.getString(QUERY);
}
} }
private fun setupRecyclerView() { private fun setupRecyclerView() {
@ -104,15 +106,9 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch
} }
private fun setupSearchView() { private fun setupSearchView() {
getSystemService(Context.SEARCH_SERVICE) as SearchManager
searchView.addTextChangedListener(this) searchView.addTextChangedListener(this)
} }
override fun onResume() {
super.onResume()
searchPresenter.search(query)
}
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
searchPresenter.detachView() searchPresenter.detachView()
@ -123,11 +119,6 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch
outState.putString(QUERY, query) outState.putString(QUERY, query)
} }
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
searchPresenter.search(savedInstanceState.getString(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))
@ -135,14 +126,14 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch
private fun search(query: String) { private fun search(query: String) {
this.query = query.trim { it <= ' ' } this.query = query
voiceSearch.visibility = if (query.isNotEmpty()) View.GONE else View.VISIBLE voiceSearch.visibility = if (query.isNotEmpty()) View.GONE else View.VISIBLE
searchPresenter.search(query) searchPresenter.search(query)
} }
override fun onMediaStoreChanged() { override fun onMediaStoreChanged() {
super.onMediaStoreChanged() super.onMediaStoreChanged()
searchPresenter.search(query!!) query?.let { search(it) }
} }
override fun onQueryTextSubmit(query: String): Boolean { override fun onQueryTextSubmit(query: String): Boolean {

View file

@ -39,7 +39,7 @@ class SettingsActivity : AbsBaseActivity() {
setTitleTextColor(ATHUtil.resolveColor(this@SettingsActivity, R.attr.colorOnPrimary)) setTitleTextColor(ATHUtil.resolveColor(this@SettingsActivity, R.attr.colorOnPrimary))
setBackgroundColor(ATHUtil.resolveColor(this@SettingsActivity, R.attr.colorPrimary)) setBackgroundColor(ATHUtil.resolveColor(this@SettingsActivity, R.attr.colorPrimary))
setNavigationOnClickListener { onBackPressed() } setNavigationOnClickListener { onBackPressed() }
ToolbarContentTintHelper.colorBackButton(toolbar, ATHUtil.resolveColor(this@SettingsActivity, R.attr.colorOnSecondary)) ToolbarContentTintHelper.colorBackButton(toolbar)
} }
appBarLayout.setBackgroundColor(ATHUtil.resolveColor(this@SettingsActivity, R.attr.colorPrimary)) appBarLayout.setBackgroundColor(ATHUtil.resolveColor(this@SettingsActivity, R.attr.colorPrimary))

View file

@ -12,6 +12,7 @@ import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.annotation.LayoutRes import androidx.annotation.LayoutRes
import androidx.appcompat.widget.AppCompatImageView
import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -22,7 +23,6 @@ import code.name.monkey.retromusic.BuildConfig
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.views.IconImageView
import com.anjlab.android.iab.v3.BillingProcessor import com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.SkuDetails import com.anjlab.android.iab.v3.SkuDetails
import com.anjlab.android.iab.v3.TransactionDetails import com.anjlab.android.iab.v3.TransactionDetails
@ -161,7 +161,10 @@ private class SkuDetailsLoadAsyncTask internal constructor(supportDevelopmentAct
} }
} }
class SkuDetailsAdapter(private var donationsDialog: SupportDevelopmentActivity, objects: List<SkuDetails>) : RecyclerView.Adapter<SkuDetailsAdapter.ViewHolder>() { class SkuDetailsAdapter(
private var donationsDialog: SupportDevelopmentActivity,
objects: List<SkuDetails>
) : RecyclerView.Adapter<SkuDetailsAdapter.ViewHolder>() {
private var skuDetailsList: List<SkuDetails> = ArrayList() private var skuDetailsList: List<SkuDetails> = ArrayList()
init { init {
@ -218,7 +221,7 @@ class SkuDetailsAdapter(private var donationsDialog: SupportDevelopmentActivity,
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: IconImageView = view.findViewById(R.id.itemImage) var image: AppCompatImageView = view.findViewById(R.id.itemImage)
} }
companion object { companion object {

View file

@ -237,7 +237,7 @@ class UserInfoActivity : AbsBaseActivity() {
.compressToBitmapAsFlowable(File(profileImagePath, USER_BANNER)) .compressToBitmapAsFlowable(File(profileImagePath, USER_BANNER))
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe { bitmap -> bannerImage.setImageBitmap(bitmap) }) .subscribe({ bitmap -> bannerImage.setImageBitmap(bitmap) }, { t -> println() }))
} }
private fun loadImageFromStorage(path: String) { private fun loadImageFromStorage(path: String) {
@ -249,7 +249,7 @@ class UserInfoActivity : AbsBaseActivity() {
.compressToBitmapAsFlowable(File(path, USER_PROFILE)) .compressToBitmapAsFlowable(File(path, USER_PROFILE))
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe { bitmap -> userImage!!.setImageBitmap(bitmap) }) .subscribe({ bitmap -> userImage!!.setImageBitmap(bitmap) }, { t -> println() }))
} }
private fun saveToInternalStorage(bitmapImage: Bitmap, userBanner: String): String { private fun saveToInternalStorage(bitmapImage: Bitmap, userBanner: String): String {

View file

@ -19,7 +19,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;
@ -67,7 +66,7 @@ public class WhatsNewActivity extends AbsBaseActivity {
//setSupportActionBar(toolbar); //setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(v -> onBackPressed()); toolbar.setNavigationOnClickListener(v -> onBackPressed());
ToolbarContentTintHelper.colorBackButton(toolbar, ATHUtil.INSTANCE.resolveColor(this, R.attr.colorOnSecondary)); ToolbarContentTintHelper.colorBackButton(toolbar);
try { try {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();

View file

@ -2,7 +2,10 @@ 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.Rect
import android.os.Bundle import android.os.Bundle
import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
@ -11,6 +14,8 @@ import androidx.fragment.app.Fragment
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.fragments.MiniPlayerFragment 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.NowPlayingScreen.*
@ -60,6 +65,8 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
override fun onSlide(bottomSheet: View, slideOffset: Float) { override fun onSlide(bottomSheet: View, slideOffset: Float) {
setMiniPlayerAlphaProgress(slideOffset) setMiniPlayerAlphaProgress(slideOffset)
dimBackground.show()
dimBackground.alpha = slideOffset
} }
override fun onStateChanged(bottomSheet: View, newState: Int) { override fun onStateChanged(bottomSheet: View, newState: Int) {
@ -69,6 +76,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
} }
BottomSheetBehavior.STATE_COLLAPSED -> { BottomSheetBehavior.STATE_COLLAPSED -> {
onPanelCollapsed() onPanelCollapsed()
dimBackground.hide()
} }
else -> { else -> {
@ -88,6 +96,9 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
updateTabs() updateTabs()
bottomSheetBehavior = BottomSheetBehavior.from(slidingPanel) bottomSheetBehavior = BottomSheetBehavior.from(slidingPanel)
val themeColor = ATHUtil.resolveColor(this, R.attr.colorPrimary, Color.GRAY)
dimBackground.setBackgroundColor(ColorUtil.withAlpha(themeColor, 0.5f))
} }
override fun onResume() { override fun onResume() {
@ -117,16 +128,13 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
return slidingMusicPanelLayout return slidingMusicPanelLayout
} }
fun setAntiDragView(antiDragView: View) {
//slidingLayout.setAntiDragView(antiDragView)
}
private fun collapsePanel() { private fun collapsePanel() {
bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
} }
fun expandPanel() { fun expandPanel() {
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
setMiniPlayerAlphaProgress(1f)
} }
private fun setMiniPlayerAlphaProgress(progress: Float) { private fun setMiniPlayerAlphaProgress(progress: Float) {
@ -175,7 +183,6 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
} }
when (panelState) { when (panelState) {
BottomSheetBehavior.STATE_EXPANDED -> { BottomSheetBehavior.STATE_EXPANDED -> {
onPanelExpanded() onPanelExpanded()
} }
BottomSheetBehavior.STATE_COLLAPSED -> onPanelCollapsed() BottomSheetBehavior.STATE_COLLAPSED -> onPanelCollapsed()
@ -344,4 +351,17 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
} }
} }
} }
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)
}
} }

View file

@ -10,8 +10,8 @@ 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.ATH
import code.name.monkey.appthemehelper.ATHActivity
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.appthemehelper.util.TintHelper
@ -21,7 +21,7 @@ import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import code.name.monkey.retromusic.util.ThemeManager import code.name.monkey.retromusic.util.ThemeManager
abstract class AbsThemeActivity : ATHActivity(), Runnable { abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
private val handler = Handler() private val handler = Handler()

View file

@ -19,6 +19,7 @@ import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.MaterialUtil import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.appthemehelper.util.TintHelper 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.DeviceInfo
@ -58,7 +59,6 @@ open class BugReportActivity : AbsThemeActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_bug_report) setContentView(R.layout.activity_bug_report)
setStatusbarColorAuto() setStatusbarColorAuto()
setNavigationbarColorAuto() setNavigationbarColorAuto()
setTaskDescriptionColorAuto() setTaskDescriptionColorAuto()
@ -68,53 +68,51 @@ open class BugReportActivity : AbsThemeActivity() {
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)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
TintHelper.setTintAuto(optionUseAccount, accentColor, false)
optionUseAccount?.setOnClickListener {
inputTitle.isEnabled = true
inputDescription.isEnabled = true
inputUsername.isEnabled = true
inputPassword.isEnabled = true
supportActionBar!!.setDisplayHomeAsUpEnabled(true) optionAnonymous.isChecked = false
sendFab.hide(object : FloatingActionButton.OnVisibilityChangedListener() {
TintHelper.setTintAuto(optionUseAccount!!, accentColor, false)
optionUseAccount!!.setOnClickListener {
inputTitle!!.isEnabled = true
inputDescription!!.isEnabled = true
inputUsername!!.isEnabled = true
inputPassword!!.isEnabled = true
optionAnonymous!!.isChecked = false
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
@ -122,10 +120,10 @@ open class BugReportActivity : AbsThemeActivity() {
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)
@ -134,10 +132,10 @@ open class BugReportActivity : AbsThemeActivity() {
} }
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()
@ -151,43 +149,42 @@ open class BugReportActivity : AbsThemeActivity() {
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.setPrimaryClip(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
@ -204,8 +201,8 @@ open class BugReportActivity : AbsThemeActivity() {
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()

View file

@ -51,7 +51,7 @@ class ContributorAdapter(
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.image) 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

View file

@ -12,6 +12,7 @@ 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.loaders.PlaylistSongsLoader import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist import code.name.monkey.retromusic.model.Artist
@ -23,12 +24,13 @@ import com.google.android.material.textview.MaterialTextView
class HomeAdapter( class HomeAdapter(
private val activity: AppCompatActivity, private val activity: AppCompatActivity,
private var homes: List<Home>,
private val displayMetrics: DisplayMetrics private val displayMetrics: DisplayMetrics
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var list = ArrayList<Home>()
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int): Int {
return homes[position].homeSection return list[position].homeSection
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
@ -43,89 +45,137 @@ class HomeAdapter(
} }
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val home = homes[position] println("ViewType ${getItemViewType(position)}")
when (getItemViewType(position)) { when (getItemViewType(position)) {
RECENT_ALBUMS -> {
RECENT_ALBUMS, TOP_ALBUMS -> {
val viewHolder = holder as AlbumViewHolder val viewHolder = holder as AlbumViewHolder
viewHolder.bindView(home) viewHolder.bindView(list[position].arrayList.toAlbums(), R.string.recent_albums, R.string.recent_added_albums)
} }
RECENT_ARTISTS, TOP_ARTISTS -> { TOP_ALBUMS -> {
val viewHolder = holder as AlbumViewHolder
viewHolder.bindView(list[position].arrayList.toAlbums(), R.string.top_albums, R.string.most_played_albums)
}
RECENT_ARTISTS -> {
val viewHolder = holder as ArtistViewHolder val viewHolder = holder as ArtistViewHolder
viewHolder.bindView(home) 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)
} }
PLAYLISTS -> { PLAYLISTS -> {
val viewHolder = holder as PlaylistViewHolder val viewHolder = holder as PlaylistViewHolder
viewHolder.bindView(home) viewHolder.bindView(list[position].arrayList.toPlaylist(), R.string.favorites, R.string.favorites_songs)
} }
} }
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {
return homes.size return list.size
} }
fun swapData(finalList: List<Home>) { fun swapData(sections: ArrayList<Home>) {
homes = finalList list = sections
notifyDataSetChanged() notifyDataSetChanged()
} }
companion object { companion object {
@IntDef(RECENT_ALBUMS, TOP_ALBUMS, RECENT_ARTISTS, TOP_ARTISTS, GENRES, 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 = 0 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 = 3 const val TOP_ARTISTS = 0
const val GENRES = 4 const val PLAYLISTS = 4
const val PLAYLISTS = 5
} }
private inner class AlbumViewHolder(view: View) : AbsHomeViewItem(view) { private inner class AlbumViewHolder(view: View) : AbsHomeViewItem(view) {
fun bindView(home: Home) { fun bindView(list: ArrayList<Album>, titleRes: Int, subtitleRes: Int) {
recyclerView.apply { if (list.isNotEmpty()) {
adapter = AlbumFullWidthAdapter(activity, home.arrayList as ArrayList<Album>, displayMetrics) recyclerView.apply {
show()
adapter = AlbumFullWidthAdapter(activity, list, displayMetrics)
}
titleContainer.show()
title.text = activity.getString(titleRes)
text.text = activity.getString(subtitleRes)
} }
title.text = activity.getString(home.title)
text.text = activity.getString(home.subTitle)
} }
} }
private inner class ArtistViewHolder(view: View) : AbsHomeViewItem(view) { inner class ArtistViewHolder(view: View) : AbsHomeViewItem(view) {
fun bindView(home: Home) { fun bindView(list: ArrayList<Artist>, titleRes: Int, subtitleRes: Int) {
recyclerView.apply { if (list.isNotEmpty()) {
layoutManager = GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false) recyclerView.apply {
val artistAdapter = ArtistAdapter(activity, home.arrayList as ArrayList<Artist>, show()
PreferenceUtil.getInstance(activity).getHomeGridStyle(activity), false, null) layoutManager = GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
adapter = artistAdapter val artistAdapter = ArtistAdapter(activity, list,
PreferenceUtil.getInstance(activity).getHomeGridStyle(activity), false, null)
adapter = artistAdapter
}
titleContainer.show()
title.text = activity.getString(titleRes)
text.text = activity.getString(subtitleRes)
} }
title.text = activity.getString(home.title)
text.text = activity.getString(home.subTitle)
} }
} }
private inner class PlaylistViewHolder(view: View) : AbsHomeViewItem(view) { private inner class PlaylistViewHolder(view: View) : AbsHomeViewItem(view) {
fun bindView(home: Home) { fun bindView(arrayList: ArrayList<Playlist>, titleRes: Int, subtitleRes: Int) {
val songs = PlaylistSongsLoader.getPlaylistSongList(activity, home.arrayList[0] as Playlist) if (arrayList.isNotEmpty()) {
recyclerView.apply { val songs = PlaylistSongsLoader.getPlaylistSongList(activity, arrayList[0])
val songAdapter = SongAdapter(activity, songs, R.layout.item_album_card, false, null) if (songs.isNotEmpty()) {
layoutManager = GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false) recyclerView.apply {
adapter = songAdapter show()
val songAdapter = SongAdapter(activity, songs, R.layout.item_album_card, false, null)
layoutManager = GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
adapter = songAdapter
}
titleContainer.show()
title.text = activity.getString(titleRes)
text.text = activity.getString(subtitleRes)
}
} }
title.text = activity.getString(home.title)
text.text = activity.getString(home.subTitle)
} }
} }
private 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 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> {
val arrayList = ArrayList<Album>()
for (x in this) {
arrayList.add(x as Album)
}
return arrayList;
}
private fun <E> ArrayList<E>.toArtists(): ArrayList<Artist> {
val arrayList = ArrayList<Artist>()
for (x in this) {
arrayList.add(x as Artist)
}
return arrayList;
}
private fun <E> ArrayList<E>.toPlaylist(): ArrayList<Playlist> {
val arrayList = ArrayList<Playlist>()
for (x in this) {
arrayList.add(x as Playlist)
}
return arrayList;
}

View file

@ -19,7 +19,6 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import java.util.*
import android.util.Pair as UtilPair import android.util.Pair as UtilPair
class SearchAdapter( class SearchAdapter(
@ -57,7 +56,7 @@ class SearchAdapter(
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) ArtistGlideRequest.Builder.from(Glide.with(activity), artist)
.build().into(holder.image); .build().into(holder.image)
} }
SONG -> { SONG -> {
val song = dataSet?.get(position) as Song val song = dataSet?.get(position) as Song
@ -79,26 +78,22 @@ class SearchAdapter(
init { init {
itemView.setOnLongClickListener(null) itemView.setOnLongClickListener(null)
if (menu != 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.image_container) val container = itemView.findViewById<View>(R.id.imageContainer)
if (container != null) { container?.visibility = View.GONE
container.visibility = View.GONE
}
} }
} }
} }
@ -126,7 +121,6 @@ class SearchAdapter(
} }
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

View file

@ -55,12 +55,8 @@ class SongFileAdapter(
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)
if (holder.title != null) {
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)

View file

@ -80,19 +80,11 @@ open class AlbumAdapter(protected val activity: AppCompatActivity,
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val album = dataSet[position] val album = dataSet[position]
val isChecked = isChecked(album) val isChecked = isChecked(album)
holder.itemView.isActivated = isChecked holder.itemView.isActivated = isChecked
holder.title?.text = getAlbumTitle(album)
if (holder.title != null) { holder.text?.text = getAlbumText(album)
holder.title!!.text = getAlbumTitle(album) holder.playSongs?.setOnClickListener { album.songs?.let { songs -> MusicPlayerRemote.openQueue(songs, 0, true) } }
}
if (holder.text != null) {
holder.text!!.text = getAlbumText(album)
}
if (holder.playSongs != null) {
holder.playSongs!!.setOnClickListener { MusicPlayerRemote.openQueue(album.songs!!, 0, true) }
}
loadAlbumCover(album, holder) loadAlbumCover(album, holder)
} }

View file

@ -1,6 +1,5 @@
package code.name.monkey.retromusic.adapter.album package code.name.monkey.retromusic.adapter.album
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -8,12 +7,13 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import code.name.monkey.retromusic.activities.LyricsActivity 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.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest 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.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import java.util.* import java.util.*
@ -69,14 +69,14 @@ class AlbumCoverPagerAdapter(fm: FragmentManager, private val dataSet: ArrayList
private val layout: Int private val layout: Int
get() { get() {
return when (PreferenceUtil.getInstance(activity).albumCoverStyle) { return when (PreferenceUtil.getInstance(activity).albumCoverStyle) {
AlbumCoverStyle.NORMAL -> code.name.monkey.retromusic.R.layout.fragment_album_cover AlbumCoverStyle.NORMAL -> R.layout.fragment_album_cover
AlbumCoverStyle.FLAT -> code.name.monkey.retromusic.R.layout.fragment_album_flat_cover AlbumCoverStyle.FLAT -> R.layout.fragment_album_flat_cover
AlbumCoverStyle.CIRCLE -> code.name.monkey.retromusic.R.layout.fragment_album_circle_cover AlbumCoverStyle.CIRCLE -> R.layout.fragment_album_circle_cover
AlbumCoverStyle.CARD -> code.name.monkey.retromusic.R.layout.fragment_album_card_cover AlbumCoverStyle.CARD -> R.layout.fragment_album_card_cover
AlbumCoverStyle.MATERIAL -> code.name.monkey.retromusic.R.layout.fragment_album_material_cover AlbumCoverStyle.MATERIAL -> R.layout.fragment_album_material_cover
AlbumCoverStyle.FULL -> code.name.monkey.retromusic.R.layout.fragment_album_full_cover AlbumCoverStyle.FULL -> R.layout.fragment_album_full_cover
AlbumCoverStyle.FULL_CARD -> code.name.monkey.retromusic.R.layout.fragment_album_full_card_cover AlbumCoverStyle.FULL_CARD -> R.layout.fragment_album_full_card_cover
else -> code.name.monkey.retromusic.R.layout.fragment_album_cover else -> R.layout.fragment_album_cover
} }
} }
@ -89,12 +89,15 @@ class AlbumCoverPagerAdapter(fm: FragmentManager, private val dataSet: ArrayList
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val finalLayout = when { val finalLayout = when {
PreferenceUtil.getInstance(activity).carouselEffect() -> code.name.monkey.retromusic.R.layout.fragment_album_carousel_cover PreferenceUtil.getInstance(activity).carouselEffect() -> R.layout.fragment_album_carousel_cover
else -> layout else -> layout
} }
val view = inflater.inflate(finalLayout, container, false) val view = inflater.inflate(finalLayout, container, false)
albumCover = view.findViewById(code.name.monkey.retromusic.R.id.player_image) albumCover = view.findViewById(R.id.player_image)
albumCover.setOnClickListener { startActivity(Intent(context, LyricsActivity::class.java)) } albumCover.setOnClickListener {
NavigationUtil.goToLyrics(requireActivity())
}
return view return view
} }

View file

@ -40,18 +40,10 @@ class AlbumFullWidthAdapter(private val activity: Activity, private val dataSet:
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)
if (holder.title != null) { holder.text?.text = getAlbumText(album)
holder.title!!.text = getAlbumTitle(album) holder.playSongs?.setOnClickListener { album.songs?.let { songs -> MusicPlayerRemote.openQueue(songs, 0, true) } }
}
if (holder.text != null) {
holder.text!!.text = getAlbumText(album)
}
if (holder.playSongs != null) {
holder.playSongs!!.setOnClickListener { MusicPlayerRemote.openQueue(album.songs!!, 0, true) }
}
loadAlbumCover(album, holder) loadAlbumCover(album, holder)
} }

View file

@ -126,9 +126,7 @@ class ArtistAdapter(val activity: AppCompatActivity,
init { init {
setImageTransitionName(activity.getString(code.name.monkey.retromusic.R.string.transition_artist_image)) setImageTransitionName(activity.getString(code.name.monkey.retromusic.R.string.transition_artist_image))
if (menu != null) { menu?.visibility = View.GONE
menu!!.visibility = View.GONE
}
} }
override fun onClick(v: View?) { override fun onClick(v: View?) {

View file

@ -14,7 +14,6 @@
package code.name.monkey.retromusic.adapter.base; package code.name.monkey.retromusic.adapter.base;
import android.os.Build;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageButton; import android.widget.ImageButton;
@ -81,14 +80,14 @@ public class MediaEntryViewHolder extends RecyclerView.ViewHolder implements Vie
image = itemView.findViewById(R.id.image); image = itemView.findViewById(R.id.image);
time = itemView.findViewById(R.id.time); time = itemView.findViewById(R.id.time);
imageText = itemView.findViewById(R.id.image_text); imageText = itemView.findViewById(R.id.imageText);
imageContainer = itemView.findViewById(R.id.image_container); imageContainer = itemView.findViewById(R.id.imageContainer);
imageTextContainer = itemView.findViewById(R.id.image_text_container); imageTextContainer = itemView.findViewById(R.id.imageTextContainer);
imageContainerCard = itemView.findViewById(R.id.image_container_card); imageContainerCard = itemView.findViewById(R.id.imageContainerCard);
menu = itemView.findViewById(R.id.menu); menu = itemView.findViewById(R.id.menu);
dragView = itemView.findViewById(R.id.drag_view); dragView = itemView.findViewById(R.id.drag_view);
paletteColorContainer = itemView.findViewById(R.id.palette_color_container); paletteColorContainer = itemView.findViewById(R.id.paletteColorContainer);
recyclerView = itemView.findViewById(R.id.recycler_view); recyclerView = itemView.findViewById(R.id.recycler_view);
mask = itemView.findViewById(R.id.mask); mask = itemView.findViewById(R.id.mask);
playSongs = itemView.findViewById(R.id.playSongs); playSongs = itemView.findViewById(R.id.playSongs);
@ -111,7 +110,7 @@ public class MediaEntryViewHolder extends RecyclerView.ViewHolder implements Vie
} }
public void setImageTransitionName(@NonNull String transitionName) { public void setImageTransitionName(@NonNull String transitionName) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && image != null) { if (image != null) {
image.setTransitionName(transitionName); image.setTransitionName(transitionName);
} }
} }

View file

@ -1,44 +0,0 @@
package code.name.monkey.retromusic.adapter.playlist
import android.app.Activity
import android.app.Dialog
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import java.util.ArrayList
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.adapter.playlist.AddToPlaylist.ViewHolder
import code.name.monkey.retromusic.util.PlaylistsUtil
class AddToPlaylist(private val activity: Activity,
private val playlists: ArrayList<Playlist>, private val itemLayoutRes: Int,
private val songs: ArrayList<Song>, private val dialog: Dialog) : RecyclerView.Adapter<ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false))
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val playlist = playlists[position]
if (holder.title != null) {
holder.title!!.text = playlist.name
}
}
override fun getItemCount(): Int {
return playlists.size
}
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
override fun onClick(v: View?) {
super.onClick(v)
PlaylistsUtil.addToPlaylist(activity, songs, playlists[adapterPosition].id, true)
dialog.dismiss()
}
}
}

View file

@ -5,7 +5,6 @@ import android.view.LayoutInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.annotation.LayoutRes
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
@ -30,15 +29,15 @@ import code.name.monkey.retromusic.util.NavigationUtil
import java.util.* import java.util.*
class PlaylistAdapter(protected val activity: AppCompatActivity, dataSet: ArrayList<Playlist>, class PlaylistAdapter(private val activity: AppCompatActivity,
@param:LayoutRes protected var itemLayoutRes: Int, cabHolder: CabHolder?) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist>(activity, cabHolder, R.menu.menu_playlists_selection) { var dataSet: ArrayList<Playlist>,
var dataSet: ArrayList<Playlist> private var itemLayoutRes: Int,
protected set cabHolder: CabHolder?) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist>(activity, cabHolder, R.menu.menu_playlists_selection) {
var songs = ArrayList<Song>() var songs = ArrayList<Song>()
init { init {
this.dataSet = dataSet
setHasStableIds(true) setHasStableIds(true)
} }
@ -70,20 +69,11 @@ class PlaylistAdapter(protected val activity: AppCompatActivity, dataSet: ArrayL
} }
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val playlist = dataSet[position] val playlist = dataSet[position]
val songs = getSongs(playlist)
holder.itemView.isActivated = isChecked(playlist) holder.itemView.isActivated = isChecked(playlist)
holder.title?.text = getPlaylistTitle(playlist)
if (holder.title != null) { holder.text?.text = getPlaylistText(playlist)
holder.title!!.text = getPlaylistTitle(playlist) holder.image?.setImageDrawable(getIconRes(playlist))
}
if (holder.text != null) {
holder.text!!.text = getPlaylistText(playlist)
}
if (holder.image != null) {
holder.image!!.setImageDrawable(getIconRes(playlist))
}
} }
private fun getIconRes(playlist: Playlist): Drawable { private fun getIconRes(playlist: Playlist): Drawable {
@ -215,9 +205,7 @@ class PlaylistAdapter(protected val activity: AppCompatActivity, dataSet: ArrayL
} }
companion object { companion object {
val TAG: String = PlaylistAdapter::class.java.simpleName val TAG: String = PlaylistAdapter::class.java.simpleName
private const val SMART_PLAYLIST = 0 private const val SMART_PLAYLIST = 0
private const val DEFAULT_PLAYLIST = 1 private const val DEFAULT_PLAYLIST = 1
} }

View file

@ -100,9 +100,9 @@ class OrderablePlaylistSongAdapter(activity: AppCompatActivity,
init { init {
if (dragView != null) { if (dragView != null) {
if (onMoveItemListener != null) { if (onMoveItemListener != null) {
dragView!!.visibility = View.VISIBLE dragView?.visibility = View.VISIBLE
} else { } else {
dragView!!.visibility = View.GONE dragView?.visibility = View.GONE
} }
} }
} }

View file

@ -5,8 +5,6 @@ import android.graphics.PorterDuff
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import androidx.annotation.ColorInt
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
@ -20,36 +18,27 @@ import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableI
import java.util.* import java.util.*
class PlayingQueueAdapter : SongAdapter, DraggableItemAdapter<PlayingQueueAdapter.ViewHolder> { class PlayingQueueAdapter(activity: AppCompatActivity,
dataSet: ArrayList<Song>,
private var current: Int,
itemLayoutRes: Int) : SongAdapter(
activity,
dataSet,
itemLayoutRes,
false,
null
), DraggableItemAdapter<PlayingQueueAdapter.ViewHolder> {
private var current: Int = 0
private var color = -1 private var color = -1
constructor(activity: AppCompatActivity, dataSet: ArrayList<Song>, current: Int,
@LayoutRes itemLayoutRes: Int) : super(activity, dataSet, itemLayoutRes, false, null) {
this.current = current
}
constructor(activity: AppCompatActivity,
dataSet: ArrayList<Song>, current: Int,
@LayoutRes itemLayoutRes: Int,
@ColorInt color: Int) : super(activity, dataSet, itemLayoutRes, false, null) {
this.current = current
this.color = color
}
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)
if (holder.imageText != null) { holder.imageText?.text = (position - current).toString()
holder.imageText!!.text = (position - current).toString() holder.time?.text = MusicUtil.getReadableDurationString(dataSet[position].duration)
}
if (holder.time != null) {
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)
} }
@ -66,15 +55,10 @@ class PlayingQueueAdapter : SongAdapter, DraggableItemAdapter<PlayingQueueAdapte
holder.title!!.setTextColor(color) holder.title!!.setTextColor(color)
} }
} }
if (holder.text != null) {
holder.text!!.setTextColor(white) holder.text?.setTextColor(white)
} holder.time?.setTextColor(white)
if (holder.time != null) { holder.imageText?.setTextColor(white)
holder.time!!.setTextColor(white)
}
if (holder.imageText != null) {
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)
} }
@ -111,21 +95,11 @@ class PlayingQueueAdapter : SongAdapter, DraggableItemAdapter<PlayingQueueAdapte
} }
private fun setAlpha(holder: SongAdapter.ViewHolder, alpha: Float) { private fun setAlpha(holder: SongAdapter.ViewHolder, alpha: Float) {
if (holder.image != null) { holder.image?.alpha = alpha
holder.image!!.alpha = alpha holder.title?.alpha = alpha
} holder.text?.alpha = alpha
if (holder.title != null) { holder.imageText?.alpha = alpha
holder.title!!.alpha = alpha holder.paletteColorContainer?.alpha = alpha
}
if (holder.text != null) {
holder.text!!.alpha = alpha
}
if (holder.imageText != null) {
holder.imageText!!.alpha = alpha
}
if (holder.paletteColorContainer != null) {
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 {
@ -164,12 +138,8 @@ class PlayingQueueAdapter : SongAdapter, DraggableItemAdapter<PlayingQueueAdapte
} }
init { init {
if (imageText != null) { imageText?.visibility = View.VISIBLE
imageText!!.visibility = View.VISIBLE dragView?.visibility = View.VISIBLE
}
if (dragView != null) {
dragView!!.visibility = View.VISIBLE
}
} }
override fun onSongMenuItemClick(item: MenuItem): Boolean { override fun onSongMenuItemClick(item: MenuItem): Boolean {

View file

@ -47,8 +47,7 @@ class AppWidgetCard : BaseAppWidget() {
* actions if service not running. * actions if service not running.
*/ */
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) { override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName, val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_card)
R.layout.app_widget_card)
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE) appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art) appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
@ -64,8 +63,7 @@ class AppWidgetCard : BaseAppWidget() {
* Update all active widget instances by pushing changes * Update all active widget instances by pushing changes
*/ */
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) { override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName, val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_card)
R.layout.app_widget_card)
val isPlaying = service.isPlaying val isPlaying = service.isPlaying
val song = service.currentSong val song = service.currentSong

View file

@ -49,6 +49,7 @@ class AppWidgetClassic : BaseAppWidget() {
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) { override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_classic) val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_classic)
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE) appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art) appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f)) appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
@ -63,8 +64,7 @@ class AppWidgetClassic : BaseAppWidget() {
* Update all active widget instances by pushing changes * Update all active widget instances by pushing changes
*/ */
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) { override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName, val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_classic)
R.layout.app_widget_classic)
val isPlaying = service.isPlaying val isPlaying = service.isPlaying
val song = service.currentSong val song = service.currentSong

View file

@ -73,11 +73,11 @@ abstract class BaseAppWidget : AppWidgetProvider() {
/** /**
* Check against [AppWidgetManager] if there are any instances of this widget. * Check against [AppWidgetManager] if there are any instances of this widget.
*/ */
protected 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(ComponentName(context,
javaClass)) javaClass))
return mAppWidgetIds.size > 0 return mAppWidgetIds.isNotEmpty()
} }
protected fun buildPendingIntent(context: Context, action: String, protected fun buildPendingIntent(context: Context, action: String,

View file

@ -33,10 +33,9 @@ class AddToPlaylistDialog : DialogFragment() {
override fun onCreateDialog( override fun onCreateDialog(
savedInstanceState: Bundle? savedInstanceState: Bundle?
): Dialog { ): Dialog {
val cntx = requireContext() val playlists = PlaylistLoader.getAllPlaylists(requireContext())
val playlists = PlaylistLoader.getAllPlaylists(cntx)
val playlistNames: MutableList<String> = mutableListOf() val playlistNames: MutableList<String> = mutableListOf()
playlistNames.add(cntx.resources.getString(R.string.action_new_playlist)) playlistNames.add(requireContext().resources.getString(R.string.action_new_playlist))
for (p in playlists) { for (p in playlists) {
playlistNames.add(p.name) playlistNames.add(p.name)
} }
@ -51,7 +50,7 @@ class AddToPlaylistDialog : DialogFragment() {
activity?.supportFragmentManager?.let { CreatePlaylistDialog.create(songs).show(it, "ADD_TO_PLAYLIST") } activity?.supportFragmentManager?.let { CreatePlaylistDialog.create(songs).show(it, "ADD_TO_PLAYLIST") }
} else { } else {
dialog.dismiss() dialog.dismiss()
PlaylistsUtil.addToPlaylist(cntx, songs, playlists[index - 1].id, true) PlaylistsUtil.addToPlaylist(requireContext(), songs, playlists[index - 1].id, true)
} }
} }
} }

View file

@ -19,7 +19,6 @@ import android.os.Bundle
import android.provider.MediaStore import android.provider.MediaStore
import android.widget.TextView import android.widget.TextView
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.MaterialUtil import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.R.layout import code.name.monkey.retromusic.R.layout
@ -30,8 +29,6 @@ import code.name.monkey.retromusic.util.PlaylistsUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.LayoutMode import com.afollestad.materialdialogs.LayoutMode
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.WhichButton
import com.afollestad.materialdialogs.actions.getActionButton
import com.afollestad.materialdialogs.bottomsheets.BottomSheet import com.afollestad.materialdialogs.bottomsheets.BottomSheet
import com.afollestad.materialdialogs.customview.customView import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.customview.getCustomView import com.afollestad.materialdialogs.customview.getCustomView
@ -67,7 +64,6 @@ class CreatePlaylistDialog : DialogFragment() {
} }
} }
} }
getActionButton(WhichButton.POSITIVE).updateTextColor(ThemeStore.accentColor(context))
} }
val dialogView = materialDialog.getCustomView() val dialogView = materialDialog.getCustomView()
@ -77,12 +73,11 @@ class CreatePlaylistDialog : DialogFragment() {
MaterialUtil.setTint(actionNewPlaylistContainer, false) MaterialUtil.setTint(actionNewPlaylistContainer, false)
val playlistId = arguments!!.getLong(MediaStore.Audio.Playlists.Members.PLAYLIST_ID) val playlistId = arguments!!.getLong(MediaStore.Audio.Playlists.Members.PLAYLIST_ID)
playlistView.appHandleColor().setText(PlaylistsUtil.getNameForPlaylist(context!!, playlistId), TextView.BufferType.EDITABLE) playlistView.appHandleColor().setText(PlaylistsUtil.getNameForPlaylist(requireContext(), playlistId), TextView.BufferType.EDITABLE)
return materialDialog return materialDialog
} }
companion object { companion object {
private const val SONGS = "songs"
@JvmOverloads @JvmOverloads
fun create(song: Song? = null): CreatePlaylistDialog { fun create(song: Song? = null): CreatePlaylistDialog {
val list = ArrayList<Song>() val list = ArrayList<Song>()

View file

@ -35,8 +35,8 @@ class OptionsSheetDialogFragment : DialogFragment(), View.OnClickListener {
override fun onClick(view: View) { override fun onClick(view: View) {
val mainActivity = activity as MainActivity? ?: return val mainActivity = activity as MainActivity? ?: return
when (view.id) { when (view.id) {
R.id.actionFolders -> mainActivity.selectedFragment(R.id.action_folder) R.id.actionFolders -> mainActivity.setMusicChooser(MainActivity.FOLDER)
R.id.actionLibrary -> mainActivity.selectedFragment(PreferenceUtil.getInstance(requireContext()).lastPage) R.id.actionLibrary -> mainActivity.setMusicChooser(MainActivity.LIBRARY)
R.id.actionSettings -> NavigationUtil.goToSettings(mainActivity) R.id.actionSettings -> NavigationUtil.goToSettings(mainActivity)
R.id.actionRate -> NavigationUtil.goToPlayStore(mainActivity) R.id.actionRate -> NavigationUtil.goToPlayStore(mainActivity)
} }

View file

@ -19,7 +19,6 @@ import android.os.Bundle
import android.provider.MediaStore.Audio.Playlists.Members.PLAYLIST_ID import android.provider.MediaStore.Audio.Playlists.Members.PLAYLIST_ID
import android.widget.TextView import android.widget.TextView
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.MaterialUtil import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.R.layout import code.name.monkey.retromusic.R.layout
@ -29,8 +28,6 @@ import code.name.monkey.retromusic.util.PlaylistsUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.LayoutMode import com.afollestad.materialdialogs.LayoutMode
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.WhichButton
import com.afollestad.materialdialogs.actions.getActionButton
import com.afollestad.materialdialogs.bottomsheets.BottomSheet import com.afollestad.materialdialogs.bottomsheets.BottomSheet
import com.afollestad.materialdialogs.customview.customView import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.customview.getCustomView import com.afollestad.materialdialogs.customview.getCustomView
@ -55,7 +52,6 @@ class RenamePlaylistDialog : DialogFragment() {
PlaylistsUtil.renamePlaylist(context, playlistId, playlistView.text!!.toString()) PlaylistsUtil.renamePlaylist(context, playlistId, playlistView.text!!.toString())
} }
} }
getActionButton(WhichButton.POSITIVE).updateTextColor(ThemeStore.accentColor(context))
} }
val dialogView = materialDialog.getCustomView() val dialogView = materialDialog.getCustomView()

View file

@ -181,78 +181,7 @@ class SleepTimerDialog : DialogFragment() {
updateCancelButton() updateCancelButton()
} }
} }
/* override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_sleep_timer, container, false)
}*/
private fun setProgressBarColor(dark: Int) { private fun setProgressBarColor(dark: Int) {
ViewUtil.setProgressDrawable(progressSlider = seekBar, newColor = dark) ViewUtil.setProgressDrawable(progressSlider = seekBar, newColor = dark)
} }
/*override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
MaterialUtil.setTint(actionCancel, false)
title.setTextColor(ThemeStore.textColorPrimary(context!!))
timerDisplay!!.setTextColor(ThemeStore.textColorSecondary(context!!))
timerUpdater = TimerUpdater()
seekArcProgress = PreferenceUtil.getInstance().lastSleepTimerValue
updateTimeDisplayTime()
seekBar.progress = seekArcProgress
setProgressBarColor(ThemeStore.accentColor(context!!))
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) {
if (i < 1) {
seekBar.progress = 1
return
}
seekArcProgress = i
updateTimeDisplayTime()
}
override fun onStartTrackingTouch(seekBar: SeekBar) {
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
PreferenceUtil.getInstance().lastSleepTimerValue = seekArcProgress
}
})
actionCancel.apply {
icon = ContextCompat.getDrawable(context, R.drawable.ic_close_white_24dp)
setOnClickListener {
val previous = makeTimerPendingIntent(PendingIntent.FLAG_NO_CREATE)
if (previous != null) {
val am = activity!!.getSystemService(Context.ALARM_SERVICE) as AlarmManager
am.cancel(previous)
previous.cancel()
Toast.makeText(activity, activity!!.resources.getString(R.string.sleep_timer_canceled), Toast.LENGTH_SHORT).show()
}
dismiss()
}
}
actionSet.apply {
icon = ContextCompat.getDrawable(context, R.drawable.ic_time_lapse_white_24dp)
MaterialUtil.setTint(actionSet)
setOnClickListener {
val minutes = seekArcProgress
val pi = makeTimerPendingIntent(PendingIntent.FLAG_CANCEL_CURRENT)
val nextSleepTimerElapsedTime = SystemClock.elapsedRealtime() + minutes * 60 * 1000
PreferenceUtil.getInstance().setNextSleepTimerElapsedRealtime(nextSleepTimerElapsedTime)
val am = activity!!.getSystemService(Context.ALARM_SERVICE) as AlarmManager
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextSleepTimerElapsedTime, pi)
Toast.makeText(activity, activity!!.resources.getString(R.string.sleep_timer_set, minutes), Toast.LENGTH_SHORT).show()
dismiss()
}
}
}*/
} }

View file

@ -16,7 +16,6 @@ package code.name.monkey.retromusic.extensions
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
@ -25,8 +24,9 @@ fun AppCompatActivity.applyToolbar(toolbar: Toolbar) {
toolbar.apply { toolbar.apply {
setNavigationOnClickListener { onBackPressed() } setNavigationOnClickListener { onBackPressed() }
setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp) setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.textColorSecondary(this@applyToolbar)) ToolbarContentTintHelper.colorBackButton(toolbar)
setBackgroundColor(ATHUtil.resolveColor(this@applyToolbar, R.attr.colorPrimary)) setBackgroundColor(ATHUtil.resolveColor(this@applyToolbar, R.attr.colorPrimary))
} }
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
} }

View file

@ -12,19 +12,21 @@
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
*/ */
package code.name.monkey.retromusic.util package code.name.monkey.retromusic.extensions
import android.content.Context import code.name.monkey.retromusic.helper.MusicPlayerRemote
import androidx.annotation.AttrRes import code.name.monkey.retromusic.model.Song
object AttrsUtil { /**
@JvmOverloads * Created by hemanths on 2019-11-01.
fun resolveColor(context: Context, @AttrRes attr: Int, fallback: Int = 0): Int { */
val a = context.theme.obtainStyledAttributes(intArrayOf(attr))
try {
return a.getColor(0, fallback) fun ArrayList<Song>.lastElement(): Boolean {
} finally { println("${this.size} ${this.indexOf(MusicPlayerRemote.currentSong)}")
a.recycle() return this.size - 1 == this.indexOf(MusicPlayerRemote.currentSong)
} }
}
fun ArrayList<Song>.fistElement(): Boolean {
return 0 == this.indexOf(MusicPlayerRemote.currentSong)
} }

View file

@ -36,6 +36,10 @@ fun View.hide() {
visibility = View.GONE visibility = View.GONE
} }
fun View.hidden() {
visibility = View.INVISIBLE
}
fun View.showOrHide(show: Boolean) = if (show) show() else hide() fun View.showOrHide(show: Boolean) = if (show) show() else hide()
fun EditText.appHandleColor(): EditText { fun EditText.appHandleColor(): EditText {

View file

@ -3,7 +3,6 @@ package code.name.monkey.retromusic.fragments
import android.animation.ObjectAnimator import android.animation.ObjectAnimator
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.AsyncTask
import android.os.Bundle import android.os.Bundle
import android.text.SpannableString import android.text.SpannableString
import android.text.SpannableStringBuilder import android.text.SpannableStringBuilder
@ -16,8 +15,10 @@ import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
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 code.name.monkey.retromusic.util.RetroUtil
import code.name.monkey.retromusic.util.ViewUtil
import kotlinx.android.synthetic.main.fragment_mini_player.* import kotlinx.android.synthetic.main.fragment_mini_player.*
import kotlin.math.abs import kotlin.math.abs
@ -52,9 +53,9 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
actionPrevious.visibility = View.VISIBLE actionPrevious.visibility = View.VISIBLE
actionPlayingQueue.visibility = View.VISIBLE actionPlayingQueue.visibility = View.VISIBLE
} else { } else {
actionNext.visibility = if (PreferenceUtil.getInstance(requireContext()).isExtraMiniExtraControls) View.VISIBLE else View.GONE actionNext.visibility = if (PreferenceUtil.getInstance(requireContext()).isExtraControls) View.VISIBLE else View.GONE
actionPlayingQueue.visibility = if (PreferenceUtil.getInstance(requireContext()).isExtraMiniExtraControls) View.GONE else View.VISIBLE actionPlayingQueue.visibility = if (PreferenceUtil.getInstance(requireContext()).isExtraControls) View.GONE else View.VISIBLE
actionPrevious.visibility = if (PreferenceUtil.getInstance(requireContext()).isExtraMiniExtraControls) View.VISIBLE else View.GONE actionPrevious.visibility = if (PreferenceUtil.getInstance(requireContext()).isExtraControls) View.VISIBLE else View.GONE
} }
actionPlayingQueue.setOnClickListener(this) actionPlayingQueue.setOnClickListener(this)
@ -91,18 +92,17 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
override fun onServiceConnected() { override fun onServiceConnected() {
updateSongTitle() updateSongTitle()
updatePlayPauseDrawableState() updatePlayPauseDrawableState()
//updateIsFavorite()
} }
override fun onPlayingMetaChanged() { override fun onPlayingMetaChanged() {
updateSongTitle() updateSongTitle()
//updateIsFavorite()
} }
override fun onPlayStateChanged() { override fun onPlayStateChanged() {
updatePlayPauseDrawableState() updatePlayPauseDrawableState()
} }
override fun onUpdateProgressViews(progress: Int, total: Int) { override fun onUpdateProgressViews(progress: Int, total: Int) {
progressBar.max = total progressBar.max = total
val animator = ObjectAnimator.ofInt(progressBar, "progress", progress) val animator = ObjectAnimator.ofInt(progressBar, "progress", progress)
@ -125,7 +125,7 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
if (MusicPlayerRemote.isPlaying) { if (MusicPlayerRemote.isPlaying) {
miniPlayerPlayPauseButton!!.setImageResource(R.drawable.ic_pause_white_24dp) miniPlayerPlayPauseButton!!.setImageResource(R.drawable.ic_pause_white_24dp)
} else { } else {
miniPlayerPlayPauseButton!!.setImageResource(R.drawable.ic_play_arrow_white_32dp) miniPlayerPlayPauseButton!!.setImageResource(R.drawable.ic_play_arrow_white_24dp)
} }
} }
@ -157,34 +157,4 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
return flingPlayBackController.onTouchEvent(event) return flingPlayBackController.onTouchEvent(event)
} }
} }
fun toggleFavorite(song: Song) {
MusicUtil.toggleFavorite(requireActivity(), song)
if (song.id == MusicPlayerRemote.currentSong.id) {
updateIsFavorite()
}
}
private var updateIsFavoriteTask: AsyncTask<*, *, *>? = null
@SuppressLint("StaticFieldLeak")
fun updateIsFavorite() {
if (updateIsFavoriteTask != null) {
updateIsFavoriteTask!!.cancel(false)
}
updateIsFavoriteTask = object : AsyncTask<Song, Void, Boolean>() {
override fun doInBackground(vararg params: Song): Boolean {
return MusicUtil.isFavorite(requireActivity(), params[0])
}
override fun onPostExecute(isFavorite: Boolean) {
val res = if (isFavorite)
R.drawable.ic_favorite_white_24dp
else
R.drawable.ic_favorite_border_white_24dp
val drawable = RetroUtil.getTintedVectorDrawable(requireActivity(), res, ThemeStore.accentColor(requireActivity()))
miniPlayerImage.setImageDrawable(drawable)
}
}.execute(MusicPlayerRemote.currentSong)
}
} }

View file

@ -9,6 +9,7 @@ import androidx.annotation.StringRes
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.helper.MusicPlayerRemote
import code.name.monkey.retromusic.util.DensityUtil import code.name.monkey.retromusic.util.DensityUtil
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ViewUtil
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
@ -44,7 +45,7 @@ abstract class AbsLibraryPagerRecyclerViewFragment<A : RecyclerView.Adapter<*>,
private fun initAdapter() { private fun initAdapter() {
adapter = createAdapter() adapter = createAdapter()
adapter!!.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { adapter?.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onChanged() { override fun onChanged() {
super.onChanged() super.onChanged()
checkIsEmpty() checkIsEmpty()
@ -63,8 +64,15 @@ abstract class AbsLibraryPagerRecyclerViewFragment<A : RecyclerView.Adapter<*>,
} }
private fun checkForPadding() { private fun checkForPadding() {
val height = DensityUtil.dip2px(requireContext(), 52f) val itemCount: Int = adapter?.itemCount ?: 0
recyclerView.setPadding(0, 0, 0, (height * 2.3).toInt()) val params = container.layoutParams as ViewGroup.MarginLayoutParams
if (itemCount > 0 && MusicPlayerRemote.playingQueue.isNotEmpty()) {
val height = DensityUtil.dip2px(requireContext(), 104f)
params.bottomMargin = height
} else {
val height = DensityUtil.dip2px(requireContext(), 52f)
params.bottomMargin = height
}
} }
private fun initLayoutManager() { private fun initLayoutManager() {

View file

@ -71,4 +71,6 @@ abstract class AbsPlayerControlsFragment : AbsMusicServiceFragment(), MusicProgr
companion object { companion object {
const val SLIDER_ANIMATION_TIME: Long = 400 const val SLIDER_ANIMATION_TIME: Long = 400
} }
} }

View file

@ -213,7 +213,7 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
override fun doInBackground(vararg params: Song): Lyrics? { override fun doInBackground(vararg params: Song): Lyrics? {
try { try {
var data: String? = LyricUtil.getStringFromFile(params[0].title, params[0].artistName) var data: String? = LyricUtil.getStringFromFile(params[0].data, params[0].artistName)
return if (TextUtils.isEmpty(data)) { return if (TextUtils.isEmpty(data)) {
data = MusicUtil.getLyrics(params[0]) data = MusicUtil.getLyrics(params[0])
return if (TextUtils.isEmpty(data)) { return if (TextUtils.isEmpty(data)) {

View file

@ -151,7 +151,7 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
}); });
getMainActivity().setSupportActionBar(toolbar); getMainActivity().setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(v -> showMainMenu(OptionsSheetDialogFragment.LIBRARY)); toolbar.setNavigationOnClickListener(v -> showMainMenu(OptionsSheetDialogFragment.LIBRARY));
ToolbarContentTintHelper.colorBackButton(toolbar, ATHUtil.INSTANCE.resolveColor(requireContext(), R.attr.colorOnSurface)); ToolbarContentTintHelper.colorBackButton(toolbar );
toolbar.setTitleTextColor(ATHUtil.INSTANCE.resolveColor(requireContext(), R.attr.colorOnSecondary)); toolbar.setTitleTextColor(ATHUtil.INSTANCE.resolveColor(requireContext(), R.attr.colorOnSecondary));
} }

View file

@ -50,8 +50,8 @@ class PlaylistsFragment : AbsLibraryPagerRecyclerViewFragment<PlaylistAdapter, L
} }
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView()
playlistsPresenter.detachView() playlistsPresenter.detachView()
super.onDestroyView()
} }
override fun onMediaStoreChanged() { override fun onMediaStoreChanged() {

View file

@ -47,7 +47,6 @@ 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.ATHUtil;
import code.name.monkey.appthemehelper.util.ColorUtil; import code.name.monkey.appthemehelper.util.ColorUtil;
import code.name.monkey.appthemehelper.util.TintHelper;
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;
import code.name.monkey.retromusic.adapter.SongFileAdapter; import code.name.monkey.retromusic.adapter.SongFileAdapter;
@ -63,6 +62,7 @@ import code.name.monkey.retromusic.misc.DialogAsyncTask;
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener; import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener;
import code.name.monkey.retromusic.misc.WrappedAsyncTaskLoader; import code.name.monkey.retromusic.misc.WrappedAsyncTaskLoader;
import code.name.monkey.retromusic.model.Song; import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.util.DensityUtil;
import code.name.monkey.retromusic.util.FileUtil; import code.name.monkey.retromusic.util.FileUtil;
import code.name.monkey.retromusic.util.NavigationUtil; import code.name.monkey.retromusic.util.NavigationUtil;
import code.name.monkey.retromusic.util.PreferenceUtil; import code.name.monkey.retromusic.util.PreferenceUtil;
@ -85,7 +85,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
private static final String CRUMBS = "crumbs"; private static final String CRUMBS = "crumbs";
private static final int LOADER_ID = LoaderIds.Companion.getFOLDERS_FRAGMENT(); private static final int LOADER_ID = LoaderIds.Companion.getFOLDERS_FRAGMENT();
private View coordinatorLayout, container, empty; private View coordinatorLayout, empty;
private MaterialCardView toolbarContainer; private MaterialCardView toolbarContainer;
@ -158,7 +158,6 @@ public class FoldersFragment extends AbsMainActivityFragment implements
breadCrumbs = view.findViewById(R.id.breadCrumbs); breadCrumbs = view.findViewById(R.id.breadCrumbs);
toolbar = view.findViewById(R.id.toolbar); toolbar = view.findViewById(R.id.toolbar);
empty = view.findViewById(android.R.id.empty); empty = view.findViewById(android.R.id.empty);
container = view.findViewById(R.id.container);
} }
private void setCrumb(BreadCrumbLayout.Crumb crumb, boolean addToHistory) { private void setCrumb(BreadCrumbLayout.Crumb crumb, boolean addToHistory) {
@ -232,7 +231,6 @@ public class FoldersFragment extends AbsMainActivityFragment implements
private void setUpAppbarColor() { private void setUpAppbarColor() {
int primaryColor = ATHUtil.INSTANCE.resolveColor(requireContext(), R.attr.colorPrimary); int primaryColor = ATHUtil.INSTANCE.resolveColor(requireContext(), R.attr.colorPrimary);
getMainActivity().setSupportActionBar(toolbar); getMainActivity().setSupportActionBar(toolbar);
TintHelper.setTintAuto(container, primaryColor, true);
appBarLayout.setBackgroundColor(primaryColor); appBarLayout.setBackgroundColor(primaryColor);
toolbar.setBackgroundColor(RetroColorUtil.toolbarColor(getMainActivity())); toolbar.setBackgroundColor(RetroColorUtil.toolbarColor(getMainActivity()));
toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp); toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp);
@ -467,8 +465,9 @@ public class FoldersFragment extends AbsMainActivityFragment implements
@Override @Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
container.setPadding(container.getPaddingLeft(), container.getPaddingTop(), recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(),
container.getPaddingRight(), this.appBarLayout.getTotalScrollRange() + verticalOffset); recyclerView.getPaddingRight(), DensityUtil.dip2px(requireContext(), 52f) +
this.appBarLayout.getTotalScrollRange() + verticalOffset);
} }
private void checkIsEmpty() { private void checkIsEmpty() {

View file

@ -1,13 +1,10 @@
package code.name.monkey.retromusic.fragments.mainactivity.home package code.name.monkey.retromusic.fragments.mainactivity.home
import android.app.ActivityOptions import android.app.ActivityOptions
import android.graphics.Bitmap
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.util.DisplayMetrics import android.util.DisplayMetrics
import android.view.* import android.view.*
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.appthemehelper.common.ATHToolbarActivity import code.name.monkey.appthemehelper.common.ATHToolbarActivity
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
@ -18,7 +15,6 @@ import code.name.monkey.retromusic.Constants.USER_BANNER
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.HomeAdapter import code.name.monkey.retromusic.adapter.HomeAdapter
import code.name.monkey.retromusic.dialogs.OptionsSheetDialogFragment import code.name.monkey.retromusic.dialogs.OptionsSheetDialogFragment
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
@ -30,15 +26,10 @@ import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist
import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist
import code.name.monkey.retromusic.mvp.presenter.HomePresenter import code.name.monkey.retromusic.mvp.presenter.HomePresenter
import code.name.monkey.retromusic.mvp.presenter.HomeView import code.name.monkey.retromusic.mvp.presenter.HomeView
import code.name.monkey.retromusic.util.Compressor
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroColorUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.abs_playlists.* import kotlinx.android.synthetic.main.abs_playlists.*
import kotlinx.android.synthetic.main.fragment_banner_home.* import kotlinx.android.synthetic.main.fragment_banner_home.*
import kotlinx.android.synthetic.main.home_content.* import kotlinx.android.synthetic.main.home_content.*
@ -47,49 +38,28 @@ import java.util.*
import javax.inject.Inject import javax.inject.Inject
class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallbacks, HomeView { class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallbacks, HomeView {
private lateinit var homeAdapter: HomeAdapter
@Inject @Inject
lateinit var homePresenter: HomePresenter lateinit var homePresenter: HomePresenter
private var disposable: CompositeDisposable = CompositeDisposable() private lateinit var homeAdapter: HomeAdapter
private lateinit var toolbar: Toolbar private lateinit var toolbar: Toolbar
override fun sections(sections: ArrayList<Home>) { override fun sections(sections: ArrayList<Home>) {
val finalList = sections.sortedWith(compareBy { it.priority }) println(sections.size)
homeAdapter.swapData(finalList) homeAdapter.swapData(sections)
if (sections.isEmpty()) {
showEmptyView()
} else {
emptyContainer.hide()
}
} }
override fun onCreateView(inflater: LayoutInflater, viewGroup: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, viewGroup: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(if (PreferenceUtil.getInstance(requireContext()).isHomeBanner) R.layout.fragment_banner_home else R.layout.fragment_home, viewGroup, false) return inflater.inflate(if (PreferenceUtil.getInstance(requireContext()).isHomeBanner) R.layout.fragment_banner_home else R.layout.fragment_home, viewGroup, false)
} }
private fun loadImageFromStorage() { private fun loadImageFromStorage() {
disposable.add(Compressor(context!!) Glide.with(requireContext())
.setMaxHeight(300) .load(File(PreferenceUtil.getInstance(requireContext()).profileImage, Constants.USER_PROFILE))
.setMaxWidth(300) .asBitmap()
.setQuality(75) .placeholder(R.drawable.ic_person_flat)
.setCompressFormat(Bitmap.CompressFormat.WEBP) .error(R.drawable.ic_person_flat)
.compressToBitmapAsFlowable(File(PreferenceUtil.getInstance(requireContext()).profileImage, Constants.USER_PROFILE)) .into(userImage)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
if (it != null) {
userImage.setImageBitmap(it)
} else {
userImage.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_person_flat))
}
}) {
userImage.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_person_flat))
})
} }
private val displayMetrics: DisplayMetrics private val displayMetrics: DisplayMetrics
@ -137,20 +107,18 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
titleWelcome.text = String.format("%s", PreferenceUtil.getInstance(requireContext()).userName) titleWelcome.text = String.format("%s", PreferenceUtil.getInstance(requireContext()).userName)
App.musicComponent.inject(this) App.musicComponent.inject(this)
homePresenter.attachView(this) homeAdapter = HomeAdapter(mainActivity, displayMetrics)
homePresenter.loadSections()
homeAdapter = HomeAdapter(mainActivity, ArrayList(), displayMetrics)
recyclerView.apply { recyclerView.apply {
layoutManager = LinearLayoutManager(mainActivity) layoutManager = LinearLayoutManager(mainActivity)
adapter = homeAdapter adapter = homeAdapter
} }
homePresenter.attachView(this)
homePresenter.loadSections()
} }
private fun toolbarColor(): Int { private fun toolbarColor(): Int {
return if (PreferenceUtil.getInstance(requireContext()).isHomeBanner) { return if (PreferenceUtil.getInstance(requireContext()).isHomeBanner) {
toolbarContainer.setBackgroundColor(Color.TRANSPARENT)
ColorUtil.withAlpha(RetroColorUtil.toolbarColor(mainActivity), 0.85f) ColorUtil.withAlpha(RetroColorUtil.toolbarColor(mainActivity), 0.85f)
} else { } else {
RetroColorUtil.toolbarColor(mainActivity) RetroColorUtil.toolbarColor(mainActivity)
@ -182,7 +150,6 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
disposable.dispose()
homePresenter.detachView() homePresenter.detachView()
} }
@ -213,7 +180,6 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
private fun getTimeOfTheDay() { private fun getTimeOfTheDay() {
val c = Calendar.getInstance() val c = Calendar.getInstance()
val timeOfDay = c.get(Calendar.HOUR_OF_DAY) val timeOfDay = c.get(Calendar.HOUR_OF_DAY)
var images = arrayOf<String>() var images = arrayOf<String>()
when (timeOfDay) { when (timeOfDay) {
in 0..5 -> images = resources.getStringArray(R.array.night) in 0..5 -> images = resources.getStringArray(R.array.night)
@ -222,28 +188,25 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
in 16..19 -> images = resources.getStringArray(R.array.evening) in 16..19 -> images = resources.getStringArray(R.array.evening)
in 20..23 -> images = resources.getStringArray(R.array.night) in 20..23 -> images = resources.getStringArray(R.array.night)
} }
val day = images[Random().nextInt(images.size)] val day = images[Random().nextInt(images.size)]
loadTimeImage(day) loadTimeImage(day)
} }
private fun loadTimeImage(day: String) { private fun loadTimeImage(day: String) {
if (bannerImage != null) { bannerImage?.let {
val request = Glide.with(requireContext())
if (PreferenceUtil.getInstance(requireContext()).bannerImage.isEmpty()) { if (PreferenceUtil.getInstance(requireContext()).bannerImage.isEmpty()) {
Glide.with(requireActivity()) request.load(day)
.load(day)
.placeholder(R.drawable.material_design_default) .placeholder(R.drawable.material_design_default)
.diskCacheStrategy(DiskCacheStrategy.ALL) .error(R.drawable.material_design_default)
.into(bannerImage!!) .into(it)
} else { } else {
disposable.add(Compressor(requireActivity()) request.load(File(PreferenceUtil.getInstance(requireContext()).bannerImage, USER_BANNER))
.setQuality(100) .asBitmap()
.setCompressFormat(Bitmap.CompressFormat.WEBP) .placeholder(R.drawable.material_design_default)
.compressToBitmapAsFlowable(File(PreferenceUtil.getInstance(requireContext()).bannerImage, USER_BANNER)) .error(R.drawable.material_design_default)
.subscribeOn(Schedulers.io()) .into(it)
.observeOn(AndroidSchedulers.mainThread())
.subscribe { bitmap -> bannerImage.setImageBitmap(bitmap) })
} }
} }
loadImageFromStorage() loadImageFromStorage()

View file

@ -12,12 +12,10 @@ import android.view.animation.DecelerateInterpolator
import android.view.animation.LinearInterpolator import android.view.animation.LinearInterpolator
import android.widget.SeekBar import android.widget.SeekBar
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.TintHelper 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.ripAlpha
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
@ -38,9 +36,10 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this) progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateView(inflater: LayoutInflater,
savedInstanceState: Bundle?): View? { container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_blur_player_playback_controls, container, false) return inflater.inflate(R.layout.fragment_blur_player_playback_controls, container, false)
} }
@ -56,6 +55,7 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
} }
showBonceAnimation() showBonceAnimation()
} }
title.isSelected = true
text.isSelected = true text.isSelected = true
} }
@ -114,7 +114,7 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
text.setTextColor(lastDisabledPlaybackControlsColor) text.setTextColor(lastDisabledPlaybackControlsColor)
TintHelper.setTintAuto(progressSlider, lastPlaybackControlsColor , false) TintHelper.setTintAuto(progressSlider, lastPlaybackControlsColor, false)
volumeFragment?.setTintableColor(lastPlaybackControlsColor) volumeFragment?.setTintableColor(lastPlaybackControlsColor)
setFabColor(lastPlaybackControlsColor) setFabColor(lastPlaybackControlsColor)
} }

View file

@ -15,12 +15,12 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.TintHelper 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.ripAlpha import code.name.monkey.retromusic.extensions.ripAlpha
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.android.synthetic.main.fragment_card_player_playback_controls.* import kotlinx.android.synthetic.main.fragment_card_player_playback_controls.*
@ -47,8 +47,6 @@ class CardPlaybackControlsFragment : AbsPlayerControlsFragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setUpMusicControllers() setUpMusicControllers()
setupControls()
playPauseButton.setOnClickListener { playPauseButton.setOnClickListener {
if (MusicPlayerRemote.isPlaying) { if (MusicPlayerRemote.isPlaying) {
MusicPlayerRemote.pauseSong() MusicPlayerRemote.pauseSong()
@ -57,20 +55,14 @@ class CardPlaybackControlsFragment : AbsPlayerControlsFragment() {
} }
showBonceAnimation(playPauseButton) showBonceAnimation(playPauseButton)
} }
} title.isSelected = true
text.isSelected = true
private fun setupControls() {
image.apply {
setImageResource(R.drawable.ic_play_circle_filled_white_24dp)
val iconPadding = activity!!.resources.getDimensionPixelSize(R.dimen.list_item_image_icon_padding)
setPadding(iconPadding, iconPadding, iconPadding, iconPadding)
}
} }
private fun updateSong() { private fun updateSong() {
val song = MusicPlayerRemote.currentSong val song = MusicPlayerRemote.currentSong
songTitle.text = song.title title.text = song.title
songText.text = song.artistName text.text = song.artistName
} }

View file

@ -57,6 +57,8 @@ class ColorPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setUpMusicControllers() setUpMusicControllers()
title.isSelected = true
text.isSelected = true
} }
private fun updateSong() { private fun updateSong() {

View file

@ -17,12 +17,12 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.TintHelper 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.ripAlpha import code.name.monkey.retromusic.extensions.ripAlpha
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.android.synthetic.main.fragment_player_playback_controls.* import kotlinx.android.synthetic.main.fragment_player_playback_controls.*
@ -50,6 +50,9 @@ class FitPlaybackControlsFragment : AbsPlayerControlsFragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setUpMusicControllers() setUpMusicControllers()
title.isSelected = true
text.isSelected = true
playPauseButton.setOnClickListener { playPauseButton.setOnClickListener {
if (MusicPlayerRemote.isPlaying) { if (MusicPlayerRemote.isPlaying) {
MusicPlayerRemote.pauseSong() MusicPlayerRemote.pauseSong()

View file

@ -16,13 +16,13 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.TintHelper 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.ripAlpha import code.name.monkey.retromusic.extensions.ripAlpha
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper.Callback import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper.Callback
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ViewUtil
@ -48,6 +48,8 @@ class FlatPlaybackControlsFragment : AbsPlayerControlsFragment(), Callback {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setUpMusicControllers() setUpMusicControllers()
title.isSelected = true
text.isSelected = true
} }
override fun onResume() { override fun onResume() {

View file

@ -22,13 +22,13 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.TintHelper 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.ripAlpha import code.name.monkey.retromusic.extensions.ripAlpha
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
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.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ViewUtil
@ -281,7 +281,7 @@ class FullPlaybackControlsFragment : AbsPlayerControlsFragment(), PopupMenu.OnMe
override fun doInBackground(vararg params: Song): Boolean? { override fun doInBackground(vararg params: Song): Boolean? {
val activity = activity val activity = activity
return if (activity != null) { return if (activity != null) {
MusicUtil.isFavorite(getActivity()!!, params[0]) MusicUtil.isFavorite(requireActivity(), params[0])
} else { } else {
cancel(false) cancel(false)
null null

View file

@ -48,6 +48,8 @@ class MaterialControlsFragment : AbsPlayerControlsFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setUpMusicControllers() setUpMusicControllers()
title.isSelected = true
text.isSelected = true
} }
private fun updateSong() { private fun updateSong() {

View file

@ -12,10 +12,10 @@ import androidx.appcompat.widget.Toolbar
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
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
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ViewUtil
import code.name.monkey.retromusic.views.DrawableGradient import code.name.monkey.retromusic.views.DrawableGradient
@ -100,16 +100,6 @@ class PlayerFragment : AbsPlayerFragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setUpSubFragments() setUpSubFragments()
setUpPlayerToolbar() setUpPlayerToolbar()
//val display = activity?.windowManager?.defaultDisplay
//val outMetrics = DisplayMetrics()
//display?.getMetrics(outMetrics)
//val density = resources.displayMetrics.density
//val dpWidth = outMetrics.widthPixels / density
//playerAlbumCoverContainer?.layoutParams?.height = RetroUtil.convertDpToPixel((dpWidth - getCutOff()), context!!).toInt()
} }

View file

@ -48,7 +48,6 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setUpMusicControllers() setUpMusicControllers()
playPauseButton.setOnClickListener { playPauseButton.setOnClickListener {
if (MusicPlayerRemote.isPlaying) { if (MusicPlayerRemote.isPlaying) {
MusicPlayerRemote.pauseSong() MusicPlayerRemote.pauseSong()
@ -57,6 +56,7 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
} }
showBonceAnimation(playPauseButton) showBonceAnimation(playPauseButton)
} }
title.isSelected = true
} }
override fun setDark(color: Int) { override fun setDark(color: Int) {

View file

@ -66,14 +66,20 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment() {
progressViewUpdateHelper.stop() progressViewUpdateHelper.stop()
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_peak_control_player, container, false) return inflater.inflate(R.layout.fragment_peak_control_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)
setUpMusicControllers() setUpMusicControllers()
} }
override fun show() { override fun show() {
@ -122,13 +128,13 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment() {
} }
private fun updatePlayPauseDrawableState() { private fun updatePlayPauseDrawableState() {
when { if (MusicPlayerRemote.isPlaying) {
MusicPlayerRemote.isPlaying -> playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp) playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp)
else -> playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp) } else {
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
} }
} }
private fun setUpMusicControllers() { private fun setUpMusicControllers() {
setUpPlayPauseFab() setUpPlayPauseFab()
setUpPrevNext() setUpPrevNext()
@ -137,6 +143,20 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment() {
setUpProgressSlider() setUpProgressSlider()
} }
private fun setUpShuffleButton() {
shuffleButton.setOnClickListener {
println("shuffleButton Click")
MusicPlayerRemote.toggleShuffleMode()
}
}
private fun setUpRepeatButton() {
repeatButton.setOnClickListener {
println("repeatButton Click")
MusicPlayerRemote.cycleRepeatMode()
}
}
override fun setUpProgressSlider() { override fun setUpProgressSlider() {
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() { progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
@ -165,9 +185,6 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment() {
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
private fun setUpShuffleButton() {
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
}
override fun updateShuffleState() { override fun updateShuffleState() {
when (MusicPlayerRemote.shuffleMode) { when (MusicPlayerRemote.shuffleMode) {
@ -176,9 +193,6 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment() {
} }
} }
private fun setUpRepeatButton() {
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
}
override fun updateRepeatState() { override fun updateRepeatState() {
when (MusicPlayerRemote.repeatMode) { when (MusicPlayerRemote.repeatMode) {
@ -206,4 +220,12 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment() {
super.onServiceConnected() super.onServiceConnected()
updatePlayPauseDrawableState() updatePlayPauseDrawableState()
} }
override fun onRepeatModeChanged() {
updateRepeatState()
}
override fun onShuffleModeChanged() {
updateShuffleState()
}
} }

View file

@ -26,6 +26,7 @@ import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest 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.util.NavigationUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_peak_player.* import kotlinx.android.synthetic.main.fragment_peak_player.*
@ -46,6 +47,10 @@ class PeakPlayerFragment : AbsPlayerFragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setUpPlayerToolbar() setUpPlayerToolbar()
setUpSubFragments() setUpSubFragments()
title.isSelected = true
playerImage.setOnClickListener {
NavigationUtil.goToLyrics(requireActivity())
}
} }
private fun setUpSubFragments() { private fun setUpSubFragments() {
@ -111,10 +116,6 @@ class PeakPlayerFragment : AbsPlayerFragment() {
} }
override fun onPlayStateChanged() {
super.onPlayStateChanged()
}
override fun onServiceConnected() { override fun onServiceConnected() {
super.onServiceConnected() super.onServiceConnected()
updateSong() updateSong()
@ -124,7 +125,4 @@ class PeakPlayerFragment : AbsPlayerFragment() {
super.onPlayingMetaChanged() super.onPlayingMetaChanged()
updateSong() updateSong()
} }
} }

View file

@ -15,8 +15,7 @@ import code.name.monkey.retromusic.model.Song
import kotlinx.android.synthetic.main.fragment_plain_player.* import kotlinx.android.synthetic.main.fragment_plain_player.*
class PlainPlayerFragment : AbsPlayerFragment() { class PlainPlayerFragment : AbsPlayerFragment() {
override fun playerToolbar(): Toolbar override fun playerToolbar(): Toolbar {
{
return playerToolbar return playerToolbar
} }
@ -33,8 +32,8 @@ class PlainPlayerFragment : AbsPlayerFragment() {
private fun updateSong() { private fun updateSong() {
val song = MusicPlayerRemote.currentSong val song = MusicPlayerRemote.currentSong
playerTitle.text = song.title title.text = song.title
playerText.text = song.artistName text.text = song.artistName
} }
override fun onServiceConnected() { override fun onServiceConnected() {
@ -50,7 +49,7 @@ class PlainPlayerFragment : AbsPlayerFragment() {
private fun setUpPlayerToolbar() { private fun setUpPlayerToolbar() {
playerToolbar.apply { playerToolbar.apply {
inflateMenu(R.menu.menu_player) inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { activity!!.onBackPressed() } setNavigationOnClickListener { requireActivity().onBackPressed() }
setOnMenuItemClickListener(this@PlainPlayerFragment) setOnMenuItemClickListener(this@PlainPlayerFragment)
ToolbarContentTintHelper.colorizeToolbar(this, ATHUtil.resolveColor(context, R.attr.iconColor), activity) ToolbarContentTintHelper.colorizeToolbar(this, ATHUtil.resolveColor(context, R.attr.iconColor), activity)
} }
@ -60,6 +59,8 @@ class PlainPlayerFragment : AbsPlayerFragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setUpSubFragments() setUpSubFragments()
setUpPlayerToolbar() setUpPlayerToolbar()
title.isSelected = true
text.isSelected = true
} }
private fun setUpSubFragments() { private fun setUpSubFragments() {
@ -82,14 +83,14 @@ class PlainPlayerFragment : AbsPlayerFragment() {
} }
override fun toolbarIconColor(): Int { override fun toolbarIconColor(): Int {
return ATHUtil.resolveColor(context!!, R.attr.iconColor) return ATHUtil.resolveColor(requireContext(), R.attr.iconColor)
} }
override fun onColorChanged(color: Int) { override fun onColorChanged(color: Int) {
plainPlaybackControlsFragment.setDark(color) plainPlaybackControlsFragment.setDark(color)
lastColor = color lastColor = color
callbacks!!.onPaletteColorChanged() callbacks!!.onPaletteColorChanged()
ToolbarContentTintHelper.colorizeToolbar(playerToolbar!!, ATHUtil.resolveColor(context!!, R.attr.iconColor), activity) ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(requireContext(), R.attr.iconColor), activity)
} }
override fun onFavoriteToggled() { override fun onFavoriteToggled() {

View file

@ -12,11 +12,11 @@ import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.android.synthetic.main.fragment_simple_controls_fragment.* import kotlinx.android.synthetic.main.fragment_simple_controls_fragment.*
@ -74,7 +74,7 @@ class SimplePlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setUpMusicControllers() setUpMusicControllers()
title.isSelected = true
playPauseButton.setOnClickListener { playPauseButton.setOnClickListener {
if (MusicPlayerRemote.isPlaying) { if (MusicPlayerRemote.isPlaying) {
MusicPlayerRemote.pauseSong() MusicPlayerRemote.pauseSong()

View file

@ -8,17 +8,17 @@ import androidx.appcompat.widget.Toolbar
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
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
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import kotlinx.android.synthetic.main.fragment_simple_player.* import kotlinx.android.synthetic.main.fragment_simple_player.*
/** /**
* @author Hemanth S (h4h13). * @author Hemanth S (h4h13).
*/ */
class SimplePlayerFragment : AbsPlayerFragment() { class SimplePlayerFragment : AbsPlayerFragment() {
override fun playerToolbar(): Toolbar { override fun playerToolbar(): Toolbar {
return playerToolbar return playerToolbar
} }
@ -45,7 +45,6 @@ class SimplePlayerFragment : AbsPlayerFragment() {
val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
playerAlbumCoverFragment.setCallbacks(this) playerAlbumCoverFragment.setCallbacks(this)
simplePlaybackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as SimplePlaybackControlsFragment simplePlaybackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as SimplePlaybackControlsFragment
} }
override fun onShow() { override fun onShow() {
@ -61,14 +60,14 @@ class SimplePlayerFragment : AbsPlayerFragment() {
} }
override fun toolbarIconColor(): Int { override fun toolbarIconColor(): Int {
return ATHUtil.resolveColor(context!!, R.attr.iconColor) return ATHUtil.resolveColor(requireContext(), R.attr.iconColor)
} }
override fun onColorChanged(color: Int) { override fun onColorChanged(color: Int) {
lastColor = color lastColor = color
callbacks!!.onPaletteColorChanged() callbacks?.onPaletteColorChanged()
simplePlaybackControlsFragment.setDark(color) simplePlaybackControlsFragment.setDark(color)
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context!!, R.attr.iconColor), activity) ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(requireContext(), R.attr.iconColor), requireActivity())
} }
@ -86,9 +85,9 @@ class SimplePlayerFragment : AbsPlayerFragment() {
private fun setUpPlayerToolbar() { private fun setUpPlayerToolbar() {
playerToolbar.apply { playerToolbar.apply {
inflateMenu(R.menu.menu_player) inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { activity!!.onBackPressed() } setNavigationOnClickListener { requireActivity().onBackPressed() }
setOnMenuItemClickListener(this@SimplePlayerFragment) setOnMenuItemClickListener(this@SimplePlayerFragment)
ToolbarContentTintHelper.colorizeToolbar(this, ATHUtil.resolveColor(context, R.attr.iconColor), activity) ToolbarContentTintHelper.colorizeToolbar(this, ATHUtil.resolveColor(context, R.attr.iconColor), requireActivity())
} }
} }
} }

View file

@ -93,8 +93,8 @@ class TinyPlayerFragment : AbsPlayerFragment(), MusicProgressViewUpdateHelper.Ca
ViewUtil.setProgressDrawable(progressBar, colorFinal) ViewUtil.setProgressDrawable(progressBar, colorFinal)
songTitle.setTextColor(textColorPrimary) title.setTextColor(textColorPrimary)
songText.setTextColor(textColorPrimaryDisabled) text.setTextColor(textColorPrimaryDisabled)
playerSongTotalTime.setTextColor(textColorPrimary) playerSongTotalTime.setTextColor(textColorPrimary)
@ -125,8 +125,8 @@ class TinyPlayerFragment : AbsPlayerFragment(), MusicProgressViewUpdateHelper.Ca
private fun updateSong() { private fun updateSong() {
val song = MusicPlayerRemote.currentSong val song = MusicPlayerRemote.currentSong
songTitle.text = song.title title.text = song.title
songText.text = String.format("%s \nby - %s", song.albumName, song.artistName) text.text = String.format("%s \nby - %s", song.albumName, song.artistName)
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -135,7 +135,7 @@ class TinyPlayerFragment : AbsPlayerFragment(), MusicProgressViewUpdateHelper.Ca
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
title.isSelected = true
progressBar.setOnClickListener(PlayPauseButtonOnClickHandler()) progressBar.setOnClickListener(PlayPauseButtonOnClickHandler())
progressBar.setOnTouchListener(MiniPlayerFragment.FlingPlayBackController(activity!!)) progressBar.setOnTouchListener(MiniPlayerFragment.FlingPlayBackController(activity!!))

View file

@ -21,10 +21,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil
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.App
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.SettingsActivity import code.name.monkey.retromusic.activities.SettingsActivity
@ -74,11 +71,11 @@ class MainSettingsFragment : Fragment(), View.OnClickListener {
buyPremium.setOnClickListener { buyPremium.setOnClickListener {
NavigationUtil.goToProVersion(requireContext()) NavigationUtil.goToProVersion(requireContext())
} }
MaterialUtil.setTint(buyPremium) ThemeStore.accentColor(requireContext()).let {
val primaryColor = MaterialValueHelper.getPrimaryTextColor(requireContext(), ColorUtil.isColorLight(ATHUtil.resolveColor(requireContext(), R.attr.colorPrimary))) buyPremium.setTextColor(it)
text.setTextColor(ColorUtil.withAlpha(primaryColor, 0.75f)) diamondIcon.imageTintList = ColorStateList.valueOf(it)
text2.setTextColor(primaryColor) }
text3.imageTintList = ColorStateList.valueOf(primaryColor)
} }
private fun inflateFragment(fragment: Fragment, @StringRes title: Int) { private fun inflateFragment(fragment: Fragment, @StringRes title: Int) {

View file

@ -33,12 +33,12 @@ class PersonaizeSettingsFragment : AbsSettingsFragment(), SharedPreferences.OnSh
showProToastAndNavigate(activity!!.getString(R.string.pref_title_round_corners)) showProToastAndNavigate(activity!!.getString(R.string.pref_title_round_corners))
return@setOnPreferenceChangeListener false return@setOnPreferenceChangeListener false
} }
activity!!.recreate() requireActivity().recreate()
return@setOnPreferenceChangeListener true return@setOnPreferenceChangeListener true
} }
val toggleFullScreen: TwoStatePreference = findPreference("toggle_full_screen")!! val toggleFullScreen: TwoStatePreference = findPreference("toggle_full_screen")!!
toggleFullScreen.setOnPreferenceChangeListener { _, _ -> toggleFullScreen.setOnPreferenceChangeListener { _, _ ->
activity!!.recreate() requireActivity().recreate()
true true
} }
} }

View file

@ -86,6 +86,16 @@ class ThemeSettingsFragment : AbsSettingsFragment() {
true true
} }
val desaturatedColor: ATESwitchPreference? = findPreference(PreferenceUtil.DESATURATED_COLOR)
desaturatedColor?.setOnPreferenceChangeListener { _, value ->
val desaturated = value as Boolean
ThemeStore.prefs(requireContext()).edit().putBoolean("desaturated_color", desaturated).apply()
PreferenceUtil.getInstance(requireContext()).setDesaturatedColor(desaturated)
requireActivity().recreate()
true
}
val colorAppShortcuts: TwoStatePreference = findPreference("should_color_app_shortcuts")!! val colorAppShortcuts: TwoStatePreference = findPreference("should_color_app_shortcuts")!!
if (!VersionUtils.hasNougatMR()) { if (!VersionUtils.hasNougatMR()) {
colorAppShortcuts.isVisible = false colorAppShortcuts.isVisible = false

View file

@ -29,24 +29,127 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.drawable.GlideDrawable; import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.target.Target;
import java.util.ArrayList;
import java.util.List;
import code.name.monkey.retromusic.App; import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.artistimage.AlbumCover;
import code.name.monkey.retromusic.glide.artistimage.ArtistImage; import code.name.monkey.retromusic.glide.artistimage.ArtistImage;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder; import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper; import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
import code.name.monkey.retromusic.model.Album;
import code.name.monkey.retromusic.model.Artist; import code.name.monkey.retromusic.model.Artist;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.util.ArtistSignatureUtil; import code.name.monkey.retromusic.util.ArtistSignatureUtil;
import code.name.monkey.retromusic.util.CustomArtistImageUtil; import code.name.monkey.retromusic.util.CustomArtistImageUtil;
public class ArtistGlideRequest {
public static final int DEFAULT_ANIMATION = android.R.anim.fade_in;
private static final DiskCacheStrategy DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.SOURCE;
private static final int DEFAULT_ERROR_IMAGE = R.drawable.default_artist_art;
public static DrawableTypeRequest createBaseRequest(RequestManager requestManager, Artist artist, boolean noCustomImage, boolean forceDownload) {
boolean hasCustomImage = CustomArtistImageUtil.Companion.getInstance(App.Companion.getContext()).hasCustomArtistImage(artist);
if (noCustomImage || !hasCustomImage) {
return requestManager.load(new ArtistImage(artist.getName(), forceDownload));
} else {
return requestManager.load(CustomArtistImageUtil.getFile(artist));
}
}
public static Key createSignature(Artist artist) {
return ArtistSignatureUtil.getInstance(App.Companion.getContext()).getArtistSignature(artist.getName());
}
public static class Builder {
final RequestManager requestManager;
final Artist artist;
boolean noCustomImage;
boolean forceDownload;
private Builder(@NonNull RequestManager requestManager, Artist artist) {
this.requestManager = requestManager;
this.artist = artist;
}
public static Builder from(@NonNull RequestManager requestManager, Artist artist) {
return new Builder(requestManager, artist);
}
public PaletteBuilder generatePalette(Context context) {
return new PaletteBuilder(this, context);
}
public BitmapBuilder asBitmap() {
return new BitmapBuilder(this);
}
public Builder noCustomImage(boolean noCustomImage) {
this.noCustomImage = noCustomImage;
return this;
}
public Builder forceDownload(boolean forceDownload) {
this.forceDownload = forceDownload;
return this;
}
public DrawableRequestBuilder<GlideDrawable> build() {
//noinspection unchecked
return createBaseRequest(requestManager, artist, noCustomImage, forceDownload)
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.priority(Priority.LOW)
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.signature(createSignature(artist));
}
}
public static class BitmapBuilder {
private final Builder builder;
public BitmapBuilder(Builder builder) {
this.builder = builder;
}
public BitmapRequestBuilder<?, Bitmap> build() {
//noinspection unchecked
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage, builder.forceDownload)
.asBitmap()
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.priority(Priority.LOW)
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.signature(createSignature(builder.artist));
}
}
public static class PaletteBuilder {
final Context context;
private final Builder builder;
public PaletteBuilder(Builder builder, Context context) {
this.builder = builder;
this.context = context;
}
public BitmapRequestBuilder<?, BitmapPaletteWrapper> build() {
//noinspection unchecked
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage, builder.forceDownload)
.asBitmap()
.transcode(new BitmapPaletteTranscoder(context), BitmapPaletteWrapper.class)
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.priority(Priority.LOW)
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.signature(createSignature(builder.artist));
}
}
}
/** /**
* @author Karim Abou Zeid (kabouzeid) * @author Karim Abou Zeid (kabouzeid)
*/ *//*
public class ArtistGlideRequest { public class ArtistGlideRequest {
public static final int DEFAULT_ANIMATION = android.R.anim.fade_in; public static final int DEFAULT_ANIMATION = android.R.anim.fade_in;
@ -152,4 +255,4 @@ public class ArtistGlideRequest {
.signature(createSignature(builder.artist)); .signature(createSignature(builder.artist));
} }
} }
} }*/

View file

@ -51,29 +51,4 @@ abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(vi
RetroColorUtil.getColor(it.palette, defaultColor)) RetroColorUtil.getColor(it.palette, defaultColor))
} }
} }
/* protected val defaultFooterColor: Int
get() = ATHUtil.resolveColor(getView().context, R.attr.defaultFooterColor)
protected val albumArtistFooterColor: Int
get() = ATHUtil.resolveColor(getView().context, R.attr.cardBackgroundColor)
override fun onLoadFailed(e: Exception, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
onColorReady(defaultFooterColor)
}
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
super.onResourceReady(resource, glideAnimation)
val defaultColor = defaultFooterColor
onColorReady(if (PreferenceUtil.getInstance(getView().context).isDominantColor)
getDominantColor(resource.bitmap, defaultColor)
else
getColor(resource.palette, defaultColor))
}
abstract fun onColorReady(color: Int)*/
} }

View file

@ -17,6 +17,7 @@ package code.name.monkey.retromusic.glide
import android.content.Context import android.content.Context
import code.name.monkey.retromusic.glide.artistimage.ArtistImage import code.name.monkey.retromusic.glide.artistimage.ArtistImage
import code.name.monkey.retromusic.glide.artistimage.ArtistImageLoader import code.name.monkey.retromusic.glide.artistimage.ArtistImageLoader
import code.name.monkey.retromusic.glide.artistimage.Factory
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverLoader import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverLoader
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
@ -30,6 +31,6 @@ class RetroMusicGlideModule : GlideModule {
override fun registerComponents(context: Context, glide: Glide) { override fun registerComponents(context: Context, glide: Glide) {
glide.register(AudioFileCover::class.java, InputStream::class.java, AudioFileCoverLoader.Factory()) glide.register(AudioFileCover::class.java, InputStream::class.java, AudioFileCoverLoader.Factory())
glide.register(ArtistImage::class.java, InputStream::class.java, ArtistImageLoader.Factory()) glide.register(ArtistImage::class.java, InputStream::class.java, Factory(context))
} }
} }

View file

@ -15,255 +15,75 @@
package code.name.monkey.retromusic.glide.artistimage package code.name.monkey.retromusic.glide.artistimage
import android.content.Context import android.content.Context
import android.graphics.Bitmap import code.name.monkey.retromusic.deezer.Data
import android.graphics.Canvas import code.name.monkey.retromusic.deezer.DeezerApiService
import android.media.MediaMetadataRetriever import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverUtils
import code.name.monkey.retromusic.util.ImageUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Priority import com.bumptech.glide.Priority
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader
import com.bumptech.glide.load.data.DataFetcher import com.bumptech.glide.load.data.DataFetcher
import com.bumptech.glide.load.model.GenericLoaderFactory import com.bumptech.glide.load.model.GenericLoaderFactory
import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.load.model.ModelLoader import com.bumptech.glide.load.model.ModelLoader
import com.bumptech.glide.load.model.ModelLoaderFactory import com.bumptech.glide.load.model.ModelLoaderFactory
import com.bumptech.glide.load.model.stream.StreamModelLoader import com.bumptech.glide.load.model.stream.StreamModelLoader
import java.io.ByteArrayInputStream import okhttp3.OkHttpClient
import java.io.ByteArrayOutputStream
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
import java.util.concurrent.TimeUnit
class AlbumCover(
var year: Int,
var filePath: String?)
class ArtistImage(val artistName: String, // filePath to get the image of the artist
val albumCovers: List<AlbumCover>
) {
fun toIdString(): String {
val id = StringBuilder(artistName)
for (albumCover in albumCovers) {
id.append(albumCover.year).append(albumCover.filePath)
}
return id.toString()
}
}
class ArtistImageFetcher(
val artistImage: ArtistImage,
val ignoreMediaStore: Boolean
) : DataFetcher<InputStream> {
private var stream: InputStream? = null
override fun cleanup() {
if (stream != null) {
try {
stream?.close()
} catch (ignore: IOException) {
// can't do much about it
}
}
}
override fun cancel() {
}
override fun loadData(priority: Priority?): InputStream {
println("MOSAIC load data for" + artistImage.artistName)
stream = getMosaic(artistImage.albumCovers)?.let {
it
}
return stream as InputStream
}
private fun getMosaic(albumCovers: List<AlbumCover>): InputStream? {
val retriever = MediaMetadataRetriever()
val artistBitMapSize = 512
val images = HashMap<InputStream, Int>()
var result: InputStream? = null
var streams = ArrayList<InputStream>()
try {
for (albumCover in albumCovers) {
var picture: ByteArray? = null
if (!ignoreMediaStore) {
retriever.setDataSource(albumCover.filePath)
picture = retriever.embeddedPicture
}
val stream: InputStream? = if (picture != null) {
ByteArrayInputStream(picture)
} else {
AudioFileCoverUtils.fallback(albumCover.filePath)
}
if (stream != null) {
images[stream] = albumCover.year
}
val nbImages = images.size
if (nbImages > 3) {
streams = ArrayList(images.keys)
var divisor = 1
var i = 1
while (i < nbImages && Math.pow(i.toDouble(), 2.0) <= nbImages) {
divisor = i
++i
}
divisor += 1
var nbTiles = Math.pow(divisor.toDouble(), 2.0)
if (nbImages < nbTiles) {
divisor -= 1;
nbTiles = Math.pow(divisor.toDouble(), 2.0)
}
val resize = (artistBitMapSize / divisor) + 1
val bitmap = Bitmap.createBitmap(artistBitMapSize, artistBitMapSize, Bitmap.Config.RGB_565)
val canvas = Canvas(bitmap)
var x = 0F
var y = 0F
var j = 0
while (j < streams.size && j < nbTiles) {
val tempBitmap = ImageUtil.resize(streams[j], resize, resize)
canvas.drawBitmap(tempBitmap, x, y, null)
x += resize
if (x >= artistBitMapSize) {
x = 0F
y += resize
}
++j
}
val bos = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 0, bos)
result = ByteArrayInputStream(bos.toByteArray())
} else if (nbImages > 0) {
var maxEntryYear: Map.Entry<InputStream, Int>? = null
for (entry in images.entries) {
if (maxEntryYear == null || entry.value
.compareTo(maxEntryYear.value) > 0) {
maxEntryYear = entry
}
}
result = if (maxEntryYear != null) {
maxEntryYear.key
} else {
images.entries
.iterator()
.next()
.key
}
}
}
} finally {
retriever.release()
try {
for (stream in streams) {
stream.close()
}
} catch (e: IOException) {
e.printStackTrace()
}
}
return result
}
override fun getId(): String {
println("MOSAIC get id for" + artistImage.artistName)
// never return NULL here!
// this id is used to determine whether the image is already cached
// we use the artist name as well as the album years + file paths
return artistImage.toIdString() + "ignoremediastore:" + ignoreMediaStore
}
}
class ArtistImageLoader(
private val context: Context
) : StreamModelLoader<ArtistImage> {
override fun getResourceFetcher(model: ArtistImage, width: Int, height: Int): DataFetcher<InputStream> {
return ArtistImageFetcher(model, PreferenceUtil.getInstance(context).ignoreMediaStoreArtwork())
}
class Factory : ModelLoaderFactory<ArtistImage, InputStream> {
override fun build(context: Context, factories: GenericLoaderFactory): ModelLoader<ArtistImage, InputStream> {
return ArtistImageLoader(context)
}
override fun teardown() {
}
}
}
/*
class ArtistImage(val artistName: String, val skipOkHttpCache: Boolean) class ArtistImage(val artistName: String, val skipOkHttpCache: Boolean)
class ArtistImageFetcher(private val context: Context, class ArtistImageFetcher(
private val deezerApiService: DeezerApiService, private val context: Context,
private val okHttp: OkHttpClient, private val deezerApiService: DeezerApiService,
private val model: ArtistImage) : DataFetcher<InputStream> { val model: ArtistImage,
@Volatile val urlLoader: ModelLoader<GlideUrl, InputStream>,
val width: Int,
val height: Int
) : DataFetcher<InputStream> {
private var urlFetcher: DataFetcher<InputStream>? = null
private var isCancelled: Boolean = false private var isCancelled: Boolean = false
private var call: Call<DeezerResponse>? = null
private var streamFetcher: OkHttpStreamFetcher? = null
override fun cleanup() {
override fun getDataClass(): Class<InputStream> { urlFetcher?.cleanup()
return InputStream::class.java
} }
override fun getDataSource(): DataSource { override fun getId(): String {
return DataSource.LOCAL return model.artistName
} }
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) { override fun cancel() {
try { isCancelled = true
if (!MusicUtil.isArtistNameUnknown(model.artistName) && RetroUtil.isAllowedToDownloadMetadata(context)) { urlFetcher?.cancel()
val artists = model.artistName.split(",") }
call = deezerApiService.getArtistImage(artists[0])
call?.enqueue(object : Callback<DeezerResponse> {
override fun onFailure(call: Call<DeezerResponse>, t: Throwable) {
callback.onLoadFailed(Exception(t))
}
override fun onResponse(call: Call<DeezerResponse>, response: Response<DeezerResponse>) { override fun loadData(priority: Priority?): InputStream? {
if (isCancelled) { if (!MusicUtil.isArtistNameUnknown(model.artistName) && PreferenceUtil.isAllowedToDownloadMetadata(context)) {
callback.onDataReady(null) val artists = model.artistName.split(",")
return val response = deezerApiService.getArtistImage(artists[0]).execute()
}
try {
val deezerResponse: DeezerResponse? = response.body()
val url = deezerResponse?.data?.get(0)?.let { getHighestQuality(it) }
streamFetcher = OkHttpStreamFetcher(okHttp, GlideUrl(url))
streamFetcher?.loadData(priority, callback)
} catch (e: Exception) {
callback.onLoadFailed(Exception("No artist image url found"))
}
}
}) if (!response.isSuccessful) {
throw IOException("Request failed with code: " + response.code());
} }
} catch (e: Exception) {
callback.onLoadFailed(e)
}
if (isCancelled) return null
return try {
val deezerResponse = response.body();
val imageUrl = deezerResponse?.data?.get(0)?.let { getHighestQuality(it) }
val glideUrl = GlideUrl(imageUrl)
urlFetcher = urlLoader.getResourceFetcher(glideUrl, width, height)
urlFetcher?.loadData(priority)
} catch (e: Exception) {
null
}
} else return null
} }
fun getHighestQuality(imageUrl: Data): String { private fun getHighestQuality(imageUrl: Data): String {
return when { return when {
imageUrl.pictureXl.isNotEmpty() -> imageUrl.pictureXl imageUrl.pictureXl.isNotEmpty() -> imageUrl.pictureXl
imageUrl.pictureBig.isNotEmpty() -> imageUrl.pictureBig imageUrl.pictureBig.isNotEmpty() -> imageUrl.pictureBig
@ -273,61 +93,49 @@ class ArtistImageFetcher(private val context: Context,
else -> "" else -> ""
} }
} }
}
override fun cleanup() { class ArtistImageLoader(
if (streamFetcher != null) { val context: Context,
streamFetcher!!.cleanup() private val deezerApiService: DeezerApiService,
} private val urlLoader: ModelLoader<GlideUrl, InputStream>
} ) : StreamModelLoader<ArtistImage> {
override fun cancel() { override fun getResourceFetcher(model: ArtistImage, width: Int, height: Int): DataFetcher<InputStream> {
isCancelled = true return ArtistImageFetcher(context, deezerApiService, model, urlLoader, width, height)
call?.cancel()
if (streamFetcher != null) {
streamFetcher!!.cancel()
}
}
companion object {
val TAG: String = ArtistImageFetcher::class.java.simpleName
} }
} }
class ArtistImageLoader(private val context: Context, class Factory(
private val deezerApiService: DeezerApiService, val context: Context
private val okhttp: OkHttpClient) : ModelLoader<ArtistImage, InputStream> { ) : ModelLoaderFactory<ArtistImage, InputStream> {
private var deezerApiService: DeezerApiService
private var okHttpFactory: OkHttpUrlLoader.Factory
override fun buildLoadData(model: ArtistImage, width: Int, height: Int, options: Options): ModelLoader.LoadData<InputStream>? { init {
return ModelLoader.LoadData(ObjectKey(model.artistName), ArtistImageFetcher(context, deezerApiService, okhttp, model)) okHttpFactory = OkHttpUrlLoader.Factory(OkHttpClient.Builder()
.connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.build())
deezerApiService = DeezerApiService.invoke(DeezerApiService.createDefaultOkHttpClient(context)
.connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.build())
} }
override fun handles(model: ArtistImage): Boolean { override fun build(context: Context?, factories: GenericLoaderFactory?): ModelLoader<ArtistImage, InputStream> {
return true return ArtistImageLoader(context!!, deezerApiService, okHttpFactory.build(context, factories))
} }
class Factory(private val context: Context) : ModelLoaderFactory<ArtistImage, InputStream> { override fun teardown() {
private val deezerApiService: DeezerApiService = okHttpFactory.teardown()
DeezerApiService.invoke(DeezerApiService.createDefaultOkHttpClient(context)
.connectTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.writeTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.build())
private val okHttp: OkHttpClient = OkHttpClient.Builder()
.connectTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.writeTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
.build()
override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader<ArtistImage, InputStream> {
return ArtistImageLoader(context, deezerApiService, okHttp)
}
override fun teardown() {}
} }
companion object { companion object {
// we need these very low values to make sure our artist image loading calls doesn't block the image loading queue // we need these very low values to make sure our artist image loading calls doesn't block the image loading queue
private const val TIMEOUT = 700 private const val TIMEOUT: Long = 700
} }
}*/
}

View file

@ -16,7 +16,6 @@ package code.name.monkey.retromusic.loaders
import android.content.Context import android.content.Context
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import io.reactivex.Observable
object SearchLoader { object SearchLoader {

View file

@ -42,8 +42,8 @@ public class LrcHelper {
private static final String CHARSET = "utf-8"; private static final String CHARSET = "utf-8";
//[03:56.00][03:18.00][02:06.00][01:07.00]原谅我这一生不羁放纵爱自由 //[03:56.00][03:18.00][02:06.00][01:07.00]原谅我这一生不羁放纵爱自由
private static final String LINE_REGEX = "((\\[\\d{2}:\\d{2}\\.\\d{2}])+)(.*)"; private static final String LINE_REGEX = "((\\[\\d{2}:\\d{2}\\.\\d{2,3}])+)(.*)";
private static final String TIME_REGEX = "\\[(\\d{2}):(\\d{2})\\.(\\d{2})]"; private static final String TIME_REGEX = "\\[(\\d{2}):(\\d{2})\\.(\\d{2,3})]";
public static List<Lrc> parseLrcFromAssets(Context context, String fileName) { public static List<Lrc> parseLrcFromAssets(Context context, String fileName) {
try { try {
@ -127,8 +127,14 @@ public class LrcHelper {
String mil = timeMatcher.group(3); String mil = timeMatcher.group(3);
Lrc lrc = new Lrc(); Lrc lrc = new Lrc();
if (content != null && content.length() != 0) { if (content != null && content.length() != 0) {
lrc.setTime(Long.parseLong(min) * 60 * 1000 + Long.parseLong(sec) * 1000 if(Integer.parseInt(mil)< 100){
+ Long.parseLong(mil) * 10); lrc.setTime(Long.parseLong(min) * 60 * 1000 + Long.parseLong(sec) * 1000
+ Long.parseLong(mil) * 10);}
else{
lrc.setTime(Long.parseLong(min) * 60 * 1000 + Long.parseLong(sec) * 1000
+ Long.parseLong(mil)
);
}
lrc.setText(content); lrc.setText(content);
lrcs.add(lrc); lrcs.add(lrc);
} }

View file

@ -0,0 +1,50 @@
/*
* 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.misc
import android.content.Context
import android.text.TextUtils
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.loaders.AlbumLoader
import code.name.monkey.retromusic.loaders.ArtistLoader
import code.name.monkey.retromusic.loaders.SongLoader
import java.util.*
internal class AsyncSearchResultLoader(context: Context, private val query: String) : WrappedAsyncTaskLoader<List<Any>>(context) {
override fun loadInBackground(): List<Any>? {
val results = ArrayList<Any>()
if (!TextUtils.isEmpty(query)) {
val songs = SongLoader.getSongs(context, query.trim { it <= ' ' })
if (!songs.isEmpty()) {
results.add(context.resources.getString(R.string.songs))
results.addAll(songs)
}
val artists = ArtistLoader.getArtists(context, query.trim { it <= ' ' })
if (!artists.isEmpty()) {
results.add(context.resources.getString(R.string.artists))
results.addAll(artists)
}
val albums = AlbumLoader.getAlbums(context, query.trim { it <= ' ' })
if (!albums.isEmpty()) {
results.add(context.resources.getString(R.string.albums))
results.addAll(albums)
}
}
return results
}
}

View file

@ -14,13 +14,17 @@
package code.name.monkey.retromusic.mvp package code.name.monkey.retromusic.mvp
import androidx.annotation.CallSuper
/** /**
* Created by hemanths on 16/08/17. * Created by hemanths on 16/08/17.
*/ */
interface Presenter<T> { interface Presenter<T> {
@CallSuper
fun attachView(view: T) fun attachView(view: T)
@CallSuper
fun detachView() fun detachView()
} }

View file

@ -50,30 +50,30 @@ interface AlbumDetailsPresenter : Presenter<AlbumDetailsView> {
override fun loadMore(artistId: Int) { override fun loadMore(artistId: Int) {
disposable += repository.getArtistByIdFlowable(artistId) disposable += repository.getArtistByIdFlowable(artistId)
.map { .map {
view.loadArtistImage(it) view?.loadArtistImage(it)
return@map it.albums return@map it.albums
} }
.map { .map {
it.filter { filterAlbum -> album.id != filterAlbum.id } it.filter { filterAlbum -> album.id != filterAlbum.id }
} }
.subscribe { .subscribe({
if (it.isEmpty()) { if (it.isEmpty()) {
return@subscribe return@subscribe
} }
view.moreAlbums(ArrayList(it)) view?.moreAlbums(ArrayList(it))
} }, { t -> println(t) })
} }
override fun loadAlbum(albumId: Int) { override fun loadAlbum(albumId: Int) {
disposable += repository.getAlbumFlowable(albumId) disposable += repository.getAlbumFlowable(albumId)
.doOnComplete { .doOnComplete {
view.complete() view?.complete()
} }
.subscribe { .subscribe({
album = it album = it
view.album(it) view?.album(it)
} }, { t -> println(t) })
} }
override fun detachView() { override fun detachView() {

View file

@ -14,14 +14,16 @@
package code.name.monkey.retromusic.mvp.presenter package code.name.monkey.retromusic.mvp.presenter
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.mvp.BaseView import code.name.monkey.retromusic.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.Disposable import kotlinx.coroutines.*
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
/** /**
@ -37,21 +39,30 @@ interface AlbumsPresenter : Presenter<AlbumsView> {
class AlbumsPresenterImpl @Inject constructor( class AlbumsPresenterImpl @Inject constructor(
private val repository: Repository private val repository: Repository
) : PresenterImpl<AlbumsView>(), AlbumsPresenter { ) : PresenterImpl<AlbumsView>(), AlbumsPresenter, CoroutineScope {
private val job = Job()
private var disposable: Disposable? = null override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
private fun showList(albums: ArrayList<Album>) {
if (albums.isNotEmpty()) view.albums(albums) else view.showEmptyView()
}
override fun detachView() { override fun detachView() {
super.detachView() super.detachView()
disposable?.dispose() job.cancel()
} }
override fun loadAlbums() { override fun loadAlbums() {
disposable = repository.allAlbumsFlowable launch {
.subscribe { this.showList(it) } when (val result = repository.allAlbums()) {
is Result.Success -> {
withContext(Dispatchers.Main) {
view?.albums(result.data)
}
}
is Result.Error -> {
view?.showEmptyView()
}
}
}
} }
} }
} }

View file

@ -51,7 +51,7 @@ interface ArtistDetailsPresenter : Presenter<ArtistDetailsView> {
cache: String?) { cache: String?) {
disposable += repository.artistInfoFloable(name, lang, cache) disposable += repository.artistInfoFloable(name, lang, cache)
.subscribe { .subscribe {
view.artistInfo(it) view?.artistInfo(it)
} }
} }
@ -60,20 +60,16 @@ interface ArtistDetailsPresenter : Presenter<ArtistDetailsView> {
override fun loadArtist(artistId: Int) { override fun loadArtist(artistId: Int) {
disposable += repository.getArtistByIdFlowable(artistId) disposable += repository.getArtistByIdFlowable(artistId)
.doOnComplete { .doOnComplete {
view.complete() view?.complete()
}
.subscribe {
this.showArtist(it)
} }
.subscribe({
view?.artist(it)
}, { t -> println(t) })
} }
override fun detachView() { override fun detachView() {
super.detachView() super.detachView()
disposable.dispose() disposable.dispose()
} }
private fun showArtist(artist: Artist) {
view.artist(artist)
}
} }
} }

View file

@ -14,15 +14,15 @@
package code.name.monkey.retromusic.mvp.presenter package code.name.monkey.retromusic.mvp.presenter
import code.name.monkey.retromusic.helper.SearchQueryHelper.songs import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.Artist import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.mvp.BaseView import code.name.monkey.retromusic.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.Disposable import kotlinx.coroutines.*
import io.reactivex.functions.Consumer
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
interface ArtistsView : BaseView { interface ArtistsView : BaseView {
fun artists(artists: ArrayList<Artist>) fun artists(artists: ArrayList<Artist>)
@ -34,29 +34,26 @@ interface ArtistsPresenter : Presenter<ArtistsView> {
class ArtistsPresenterImpl @Inject constructor( class ArtistsPresenterImpl @Inject constructor(
private val repository: Repository private val repository: Repository
) : PresenterImpl<ArtistsView>(), ArtistsPresenter { ) : PresenterImpl<ArtistsView>(), ArtistsPresenter, CoroutineScope {
private val job = Job()
private var disposable: Disposable? = null override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
private fun showList(artists: ArrayList<Artist>) {
if (songs.isNotEmpty())
view.artists(artists)
else
view.showEmptyView()
}
override fun detachView() { override fun detachView() {
super.detachView() super.detachView()
disposable?.dispose() job.cancel()
} }
override fun loadArtists() { override fun loadArtists() {
disposable = repository.allArtistsFlowable launch {
.subscribe({ when (val result = repository.allArtists()) {
view.artists(it) is Result.Success -> withContext(Dispatchers.Main) {
}, { view?.artists(result.data)
println(it) }
}) is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
}
}
} }
} }
} }

View file

@ -14,14 +14,16 @@
package code.name.monkey.retromusic.mvp.presenter package code.name.monkey.retromusic.mvp.presenter
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.mvp.BaseView import code.name.monkey.retromusic.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.Disposable import kotlinx.coroutines.*
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
/** /**
@ -37,28 +39,28 @@ interface GenreDetailsPresenter : Presenter<GenreDetailsView> {
class GenreDetailsPresenterImpl @Inject constructor( class GenreDetailsPresenterImpl @Inject constructor(
private val repository: Repository private val repository: Repository
) : PresenterImpl<GenreDetailsView>(), GenreDetailsPresenter { ) : PresenterImpl<GenreDetailsView>(), GenreDetailsPresenter, CoroutineScope {
private val job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
override fun detachView() { override fun detachView() {
super.detachView() super.detachView()
disposable?.dispose() job.cancel()
} }
private var disposable: Disposable? = null
override fun loadGenreSongs(genreId: Int) { override fun loadGenreSongs(genreId: Int) {
disposable = repository.getGenreFlowable(genreId) launch {
.subscribe { when (val result = repository.getGenre(genreId)) {
showGenre(it) is Result.Success -> withContext(Dispatchers.Main) {
view?.songs(result.data)
} }
is Result.Error -> withContext(Dispatchers.Main) {
} view?.showEmptyView()
}
private fun showGenre(songs: ArrayList<Song>) { }
if (songs.isNotEmpty()) {
view.songs(songs)
} else {
view.showEmptyView()
} }
} }
} }

View file

@ -14,14 +14,16 @@
package code.name.monkey.retromusic.mvp.presenter package code.name.monkey.retromusic.mvp.presenter
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.Genre import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.mvp.BaseView import code.name.monkey.retromusic.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.Disposable import kotlinx.coroutines.*
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
/** /**
* @author Hemanth S (h4h13). * @author Hemanth S (h4h13).
@ -35,20 +37,25 @@ interface GenresPresenter : Presenter<GenresView> {
class GenresPresenterImpl @Inject constructor( class GenresPresenterImpl @Inject constructor(
private val repository: Repository private val repository: Repository
) : PresenterImpl<GenresView>(), GenresPresenter { ) : PresenterImpl<GenresView>(), GenresPresenter, CoroutineScope {
private val job = Job()
private var disposable: Disposable? = null override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
override fun loadGenres() { override fun detachView() {
disposable = repository.allGenresFlowable super.detachView()
.subscribe { this.showList(it) } job.cancel()
} }
private fun showList(genres: ArrayList<Genre>) { override fun loadGenres() {
if (genres.isNotEmpty()) { launch {
view.genres(genres) when (val result = repository.allGenres()) {
} else { is Result.Success -> withContext(Dispatchers.Main) {
view.showEmptyView() view?.genres(result.data)
}
is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
}
} }
} }
} }

View file

@ -14,12 +14,7 @@
package code.name.monkey.retromusic.mvp.presenter package code.name.monkey.retromusic.mvp.presenter
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.PLAYLISTS
import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.RECENT_ALBUMS
import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.RECENT_ARTISTS
import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.TOP_ALBUMS
import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.TOP_ARTISTS
import code.name.monkey.retromusic.model.Home import code.name.monkey.retromusic.model.Home
import code.name.monkey.retromusic.mvp.BaseView import code.name.monkey.retromusic.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.Presenter
@ -27,7 +22,9 @@ import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import kotlinx.coroutines.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
operator fun CompositeDisposable.plusAssign(disposable: Disposable) { operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
add(disposable) add(disposable)
@ -40,238 +37,38 @@ interface HomeView : BaseView {
interface HomePresenter : Presenter<HomeView> { interface HomePresenter : Presenter<HomeView> {
fun loadSections() fun loadSections()
class HomePresenterImpl @Inject constructor( class HomePresenterImpl @Inject constructor(
private val repository: Repository private val repository: Repository
) : PresenterImpl<HomeView>(), HomePresenter { ) : PresenterImpl<HomeView>(), HomePresenter, CoroutineScope {
private val job = Job()
private val hashSet: HashSet<Home> = HashSet() override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
override fun detachView() {
super.detachView()
job.cancel()
}
override fun loadSections() { override fun loadSections() {
loadRecentArtists() launch {
loadRecentAlbums() val list = ArrayList<Home>()
loadTopArtists() val recentArtistResult = listOf(
loadATopAlbums() repository.topArtists(),
loadFavorite() repository.topAlbums(),
//loadHomeSection() repository.recentArtists(),
} repository.recentAlbums(),
repository.favoritePlaylist()
private var disposable: CompositeDisposable = CompositeDisposable() )
for (r in recentArtistResult) {
private fun showData(sections: ArrayList<Home>) { when (r) {
if (sections.isEmpty()) { is Result.Success -> list.add(r.data)
view.showEmptyView() }
} else { }
view.sections(sections) withContext(Dispatchers.Main) {
if (list.isNotEmpty()) view?.sections(list) else view?.showEmptyView()
}
} }
} }
private fun loadRecentArtists() {
disposable += repository.recentArtistsFlowable
.subscribe {
if (it.isNotEmpty()) hashSet.add(
Home(0,
R.string.recent_artists,
R.string.recent_added_artists,
it,
RECENT_ARTISTS,
R.drawable.ic_artist_white_24dp
))
showData(ArrayList(hashSet))
}
}
private fun loadRecentAlbums() {
disposable += repository.recentAlbumsFlowable
.subscribe {
if (it.isNotEmpty()) hashSet.add(
Home(1,
R.string.recent_albums,
R.string.recent_added_albums,
it,
RECENT_ALBUMS,
R.drawable.ic_album_white_24dp
))
showData(ArrayList(hashSet))
}
}
private fun loadTopArtists() {
disposable += repository.topArtistsFlowable
.subscribe {
if (it.isNotEmpty()) hashSet.add(
Home(2,
R.string.top_artists,
R.string.most_played_artists,
it,
TOP_ARTISTS,
R.drawable.ic_artist_white_24dp
))
showData(ArrayList(hashSet))
}
}
private fun loadATopAlbums() {
disposable += repository.topAlbumsFlowable
.subscribe {
if (it.isNotEmpty()) hashSet.add(
Home(3,
R.string.top_albums,
R.string.most_played_albums,
it,
TOP_ALBUMS,
R.drawable.ic_album_white_24dp
))
showData(ArrayList(hashSet))
}
}
private fun loadFavorite() {
disposable += repository.favoritePlaylistFlowable
.subscribe {
if (it.isNotEmpty()) hashSet.add(
Home(4,
R.string.favorites,
R.string.favorites_songs,
it,
PLAYLISTS,
R.drawable.ic_favorite_white_24dp
))
showData(ArrayList(hashSet))
}
}
/*private fun loadHomeSection() {
val ob = listOf(repository.recentArtistsFlowable,
repository.recentAlbumsFlowable,
repository.topArtistsFlowable,
repository.topAlbumsFlowable,
repository.favoritePlaylistFlowable)
disposable += Observable.combineLatest(ob) {
val hashSet: HashSet<Home> = HashSet()
val recentArtist = it[0] as ArrayList<Artist>
if (recentArtist.isNotEmpty()) hashSet.add(
Home(0,
R.string.recent_artists,
0,
recentArtist,
RECENT_ARTISTS,
R.drawable.ic_artist_white_24dp
))
val recentAlbums = it[1] as ArrayList<Album>
if (recentAlbums.isNotEmpty()) hashSet.add(
Home(1,
R.string.recent_albums,
0,
recentAlbums,
RECENT_ALBUMS,
R.drawable.ic_album_white_24dp
))
val topArtists = it[2] as ArrayList<Artist>
if (topArtists.isNotEmpty()) hashSet.add(
Home(2,
R.string.top_artists,
0,
topArtists,
TOP_ARTISTS,
R.drawable.ic_artist_white_24dp
))
val topAlbums = it[3] as ArrayList<Album>
if (topAlbums.isNotEmpty()) hashSet.add(
Home(3,
R.string.top_albums,
0,
topAlbums,
TOP_ALBUMS,
R.drawable.ic_album_white_24dp
))
val playlists = it[4] as ArrayList<Playlist>
if (playlists.isNotEmpty()) hashSet.add(
Home(4,
R.string.favorites,
0,
playlists,
PLAYLISTS,
R.drawable.ic_favorite_white_24dp
))
return@combineLatest hashSet
}.subscribe {
view.sections(ArrayList(it))
}
}*/
} }
} }
/*class HomePresenter(
private val view: HomeContract.HomeView,
private val repositoryImpl: RepositoryImpl
) : Presenter(), HomeContract.HomePresenter {
private val hashSet: HashSet<Home> = HashSet()
override fun homeSections() {
loadRecentArtists()
loadRecentAlbums()
loadTopArtists()
loadATopAlbums()
loadFavorite()
}
override fun subscribe() {
homeSections()
}
override fun unsubscribe() {
disposable.dispose()
}
private fun loadRecentArtists() {
disposable += repositoryImpl.recentArtistsFlowable
.subscribe({
if (it.isNotEmpty()) hashSet.add(Home(0, R.string.recent_artists, 0, it, RECENT_ARTISTS, R.drawable.ic_artist_white_24dp))
view.showData(ArrayList(hashSet))
}, {
view.showEmptyView()
})
}
private fun loadRecentAlbums() {
disposable += repositoryImpl.recentAlbumsFlowable
.subscribe({
if (it.isNotEmpty()) hashSet.add(Home(1, R.string.recent_albums, 0, it, RECENT_ALBUMS, R.drawable.ic_album_white_24dp))
view.showData(ArrayList(hashSet))
}, {
view.showEmptyView()
})
}
private fun loadATopAlbums() {
disposable += repositoryImpl.topAlbumsFlowable
.subscribe({
if (it.isNotEmpty()) hashSet.add(Home(3, R.string.top_albums, 0, it, TOP_ALBUMS, R.drawable.ic_album_white_24dp))
view.showData(ArrayList(hashSet))
}, {
view.showEmptyView()
})
}
private fun loadTopArtists() {
disposable += repositoryImpl.topArtistsFlowable
.subscribe({
if (it.isNotEmpty()) hashSet.add(Home(2, R.string.top_artists, 0, it, TOP_ARTISTS, R.drawable.ic_artist_white_24dp))
view.showData(ArrayList(hashSet))
}, {
view.showEmptyView()
})
}
private fun loadFavorite() {
disposable += repositoryImpl.favoritePlaylistFlowable
.subscribe({
if (it.isNotEmpty()) hashSet.add(Home(4, R.string.favorites, 0, it, PLAYLISTS, R.drawable.ic_favorite_white_24dp))
view.showData(ArrayList(hashSet))
}, {
view.showEmptyView()
})
}
}*/

View file

@ -14,13 +14,15 @@
package code.name.monkey.retromusic.mvp.presenter package code.name.monkey.retromusic.mvp.presenter
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.Playlist import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.mvp.BaseView import code.name.monkey.retromusic.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.Disposable import kotlinx.coroutines.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
/** /**
@ -37,20 +39,28 @@ interface PlaylistsPresenter : Presenter<PlaylistView> {
class PlaylistsPresenterImpl @Inject constructor( class PlaylistsPresenterImpl @Inject constructor(
private val repository: Repository private val repository: Repository
) : PresenterImpl<PlaylistView>(), PlaylistsPresenter { ) : PresenterImpl<PlaylistView>(), PlaylistsPresenter, CoroutineScope {
private var disposable: Disposable? = null private val job = Job()
override fun playlists() { override val coroutineContext: CoroutineContext
disposable = repository.allPlaylistsFlowable get() = Dispatchers.IO + job
.subscribe { this.showList(it) }
override fun detachView() {
super.detachView()
job.cancel()
} }
private fun showList(arrayList: ArrayList<Playlist>) { override fun playlists() {
if (arrayList.isEmpty()) { launch {
view.showEmptyView() when (val result = repository.allPlaylists()) {
} else { is Result.Success -> withContext(Dispatchers.Main) {
view.playlists(arrayList) view?.playlists(result.data)
}
is Result.Error -> withContext(Dispatchers.Main) {
view?.showEmptyView()
}
}
} }
} }
} }

View file

@ -14,14 +14,16 @@
package code.name.monkey.retromusic.mvp.presenter package code.name.monkey.retromusic.mvp.presenter
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.Playlist import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.mvp.BaseView import code.name.monkey.retromusic.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.Disposable import kotlinx.coroutines.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
/** /**
* Created by hemanths on 20/08/17. * Created by hemanths on 20/08/17.
@ -35,25 +37,29 @@ interface PlaylistSongsPresenter : Presenter<PlaylistSongsView> {
class PlaylistSongsPresenterImpl @Inject constructor( class PlaylistSongsPresenterImpl @Inject constructor(
private val repository: Repository private val repository: Repository
) : PresenterImpl<PlaylistSongsView>(), PlaylistSongsPresenter { ) : PresenterImpl<PlaylistSongsView>(), PlaylistSongsPresenter, CoroutineScope {
private var disposable: Disposable? = null private var job: Job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
override fun loadPlaylistSongs(playlist: Playlist) { override fun loadPlaylistSongs(playlist: Playlist) {
disposable = repository.getPlaylistSongsFlowable(playlist) launch {
.subscribe { when (val songs = repository.getPlaylistSongs(playlist)) {
view.songs(it) is Result.Success -> withContext(Dispatchers.Main) {
view?.songs(songs.data)
} }
is Result.Error -> withContext(Dispatchers.Main) {
view?.showEmptyView()
}
}
}
} }
override fun detachView() { override fun detachView() {
super.detachView() super.detachView()
disposable?.dispose() job.cancel()
} }
override fun attachView(view: PlaylistSongsView) {
super.attachView(view)
}
} }
} }

View file

@ -14,19 +14,22 @@
package code.name.monkey.retromusic.mvp.presenter package code.name.monkey.retromusic.mvp.presenter
import code.name.monkey.retromusic.Result.Error
import code.name.monkey.retromusic.Result.Success
import code.name.monkey.retromusic.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
import kotlinx.coroutines.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
/** /**
* Created by hemanths on 20/08/17. * Created by hemanths on 20/08/17.
*/ */
interface SearchView { interface SearchView : BaseView {
fun showData(data: MutableList<Any>) fun showData(data: MutableList<Any>)
fun showEmptyView()
} }
interface SearchPresenter : Presenter<SearchView> { interface SearchPresenter : Presenter<SearchView> {
@ -35,18 +38,27 @@ interface SearchPresenter : Presenter<SearchView> {
class SearchPresenterImpl @Inject constructor( class SearchPresenterImpl @Inject constructor(
private val repository: Repository private val repository: Repository
) : PresenterImpl<SearchView>(), SearchPresenter { ) : PresenterImpl<SearchView>(), SearchPresenter, CoroutineScope {
override fun attachView(view: SearchView) { override val coroutineContext: CoroutineContext
super.attachView(view) get() = Dispatchers.IO + job
}
private var job: Job = Job()
override fun detachView() { override fun detachView() {
super.detachView() super.detachView()
job.cancel()
} }
override fun search(query: String?) { override fun search(query: String?) {
view.showData(repository.search(query)) launch {
when (val result = repository.search(query)) {
is Success -> withContext(Dispatchers.Main) {
view?.showData(result.data)
}
is Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
}
}
} }
} }
} }

View file

@ -14,13 +14,15 @@
package code.name.monkey.retromusic.mvp.presenter package code.name.monkey.retromusic.mvp.presenter
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.Disposable import kotlinx.coroutines.*
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
/** /**
* Created by hemanths on 10/08/17. * Created by hemanths on 10/08/17.
@ -33,23 +35,27 @@ interface SongView {
interface SongPresenter : Presenter<SongView> { interface SongPresenter : Presenter<SongView> {
fun loadSongs() fun loadSongs()
class SongPresenterImpl @Inject constructor( class SongPresenterImpl @Inject constructor(
private val repository: Repository private val repository: Repository
) : PresenterImpl<SongView>(), SongPresenter { ) : PresenterImpl<SongView>(), SongPresenter, CoroutineScope {
private var disposable: Disposable? = null private var job: Job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
override fun loadSongs() { override fun loadSongs() {
disposable = repository.allSongsFlowable launch {
.subscribe({ when (val songs = repository.allSongs()) {
view?.songs(it) is Result.Success -> withContext(Dispatchers.Main) { view?.songs(songs.data) }
}, { t -> print(t) }) is Result.Error -> view?.showEmptyView()
}
}
} }
override fun detachView() { override fun detachView() {
super.detachView() super.detachView()
disposable?.dispose() job.cancel();
} }
} }
} }

View file

@ -25,6 +25,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.CategoryInfoAdapter import code.name.monkey.retromusic.adapter.CategoryInfoAdapter
import code.name.monkey.retromusic.model.CategoryInfo import code.name.monkey.retromusic.model.CategoryInfo
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
@ -58,7 +59,7 @@ class LibraryPreferenceDialog : PreferenceDialogFragmentCompat() {
lateinit var adapter: CategoryInfoAdapter lateinit var adapter: CategoryInfoAdapter
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val view = activity!!.layoutInflater.inflate(code.name.monkey.retromusic.R.layout.preference_dialog_library_categories, null) val view = requireActivity().layoutInflater.inflate(R.layout.preference_dialog_library_categories, null)
val categoryInfos: List<CategoryInfo> val categoryInfos: List<CategoryInfo>
if (savedInstanceState != null) { if (savedInstanceState != null) {
@ -68,14 +69,14 @@ class LibraryPreferenceDialog : PreferenceDialogFragmentCompat() {
} }
adapter = CategoryInfoAdapter(categoryInfos) adapter = CategoryInfoAdapter(categoryInfos)
val recyclerView = view.findViewById<RecyclerView>(code.name.monkey.retromusic.R.id.recycler_view) val recyclerView = view.findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.layoutManager = LinearLayoutManager(activity) recyclerView.layoutManager = LinearLayoutManager(activity)
recyclerView.adapter = adapter recyclerView.adapter = adapter
adapter.attachToRecyclerView(recyclerView) adapter.attachToRecyclerView(recyclerView)
return MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)) return MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT))
.title(code.name.monkey.retromusic.R.string.library_categories) .title(R.string.library_categories)
.cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner) .cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
.customView(view = view) .customView(view = view)
.positiveButton(android.R.string.ok) { .positiveButton(android.R.string.ok) {
@ -85,7 +86,7 @@ class LibraryPreferenceDialog : PreferenceDialogFragmentCompat() {
.negativeButton(android.R.string.cancel) { .negativeButton(android.R.string.cancel) {
dismiss() dismiss()
} }
.neutralButton(code.name.monkey.retromusic.R.string.reset_action) { .neutralButton(R.string.reset_action) {
adapter.categoryInfos = PreferenceUtil.getInstance(requireContext()).defaultLibraryCategoryInfos adapter.categoryInfos = PreferenceUtil.getInstance(requireContext()).defaultLibraryCategoryInfos
} }
.noAutoDismiss() .noAutoDismiss()

View file

@ -92,7 +92,7 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP
return MaterialDialog(requireContext()).show { return MaterialDialog(requireContext()).show {
title(R.string.pref_title_album_cover_style) title(R.string.pref_title_now_playing_screen_appearance)
positiveButton(R.string.set) { positiveButton(R.string.set) {
val nowPlayingScreen = NowPlayingScreen.values()[viewPagerPosition] val nowPlayingScreen = NowPlayingScreen.values()[viewPagerPosition]
if (isNowPlayingThemes(nowPlayingScreen)) { if (isNowPlayingThemes(nowPlayingScreen)) {

View file

@ -15,7 +15,11 @@
package code.name.monkey.retromusic.providers package code.name.monkey.retromusic.providers
import android.content.Context import android.content.Context
import code.name.monkey.retromusic.App import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.Result.Error
import code.name.monkey.retromusic.Result.Success
import code.name.monkey.retromusic.adapter.HomeAdapter
import code.name.monkey.retromusic.loaders.* import code.name.monkey.retromusic.loaders.*
import code.name.monkey.retromusic.model.* import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
@ -27,6 +31,205 @@ import io.reactivex.schedulers.Schedulers
class RepositoryImpl(private val context: Context) : Repository { class RepositoryImpl(private val context: Context) : Repository {
override suspend fun allAlbums(): Result<ArrayList<Album>> {
return try {
val albums = AlbumLoader.getAllAlbums(context)
if (albums.isNotEmpty()) {
Success(albums)
} else {
Error(Throwable("No items found"))
}
} catch (e: Exception) {
Error(e)
}
}
override suspend fun allArtists(): Result<ArrayList<Artist>> {
return try {
val artists = ArtistLoader.getAllArtists(context)
if (artists.isNotEmpty()) {
Success(artists)
} else {
Error(Throwable("No items found"))
}
} catch (e: Exception) {
Error(e)
}
}
override suspend fun allPlaylists(): Result<ArrayList<Playlist>> {
return try {
val playlists = PlaylistLoader.getAllPlaylists(context)
if (playlists.isNotEmpty()) {
Success(playlists)
} else {
Error(Throwable("No items found"))
}
} catch (e: Exception) {
Error(e)
}
}
override suspend fun allGenres(): Result<ArrayList<Genre>> {
return try {
val genres = GenreLoader.getAllGenres(context)
if (genres.isNotEmpty()) {
Success(genres)
} else {
Error(Throwable("No items found"))
}
} catch (e: Exception) {
Error(e)
}
}
override suspend fun search(query: String?): Result<MutableList<Any>> {
return try {
val result = SearchLoader.searchAll(context, query)
if (result.isNotEmpty()) {
Success(result)
} else {
Error(Throwable("No items found"))
}
} catch (e: Exception) {
Error(e)
}
}
override suspend fun allSongs(): Result<ArrayList<Song>> {
return try {
val songs = SongLoader.getAllSongs(context);
if (songs.isEmpty()) {
Error(Throwable("No items found"))
} else {
Success(songs);
}
} catch (e: Exception) {
Error(e);
}
}
override suspend fun getPlaylistSongs(playlist: Playlist): Result<ArrayList<Song>> {
return try {
val songs: ArrayList<Song> = if (playlist is AbsCustomPlaylist) {
playlist.getSongs(context)
} else {
PlaylistSongsLoader.getPlaylistSongList(context, playlist.id)
}
Success(songs);
} catch (e: Exception) {
Error(e)
}
}
override suspend fun getGenre(genreId: Int): Result<ArrayList<Song>> {
return try {
val songs = GenreLoader.getSongs(context, genreId)
if (songs.isEmpty()) {
Error(Throwable("No items found"))
} else {
Success(songs);
}
} catch (e: Exception) {
Error(e)
}
}
override suspend fun recentArtists(): Result<Home> {
return try {
val artists = LastAddedSongsLoader.getLastAddedArtists(context)
if (artists.isEmpty()) {
Error(Throwable("No items found"))
} else {
Success(Home(0,
R.string.recent_artists,
R.string.recent_added_artists,
artists,
HomeAdapter.RECENT_ARTISTS,
R.drawable.ic_artist_white_24dp))
}
} catch (e: Exception) {
Error(e)
}
}
override suspend fun recentAlbums(): Result<Home> {
return try {
val albums = LastAddedSongsLoader.getLastAddedAlbums(context)
if (albums.isEmpty()) {
Error(Throwable("No items found"))
} else {
Success(Home(1,
R.string.recent_albums,
R.string.recent_added_albums,
albums,
HomeAdapter.RECENT_ALBUMS,
R.drawable.ic_album_white_24dp
));
}
} catch (e: Exception) {
Error(e)
}
}
override suspend fun topAlbums(): Result<Home> {
return try {
val albums = TopAndRecentlyPlayedTracksLoader.getTopAlbums(context)
if (albums.isEmpty()) {
Error(Throwable("No items found"))
} else {
Success(Home(3,
R.string.top_albums,
R.string.most_played_albums,
albums,
HomeAdapter.TOP_ALBUMS,
R.drawable.ic_album_white_24dp
));
}
} catch (e: Exception) {
Error(e)
}
}
override suspend fun topArtists(): Result<Home> {
return try {
val artists = TopAndRecentlyPlayedTracksLoader.getTopArtists(context)
if (artists.isEmpty()) {
Error(Throwable("No items found"))
} else {
Success(Home(2,
R.string.top_artists,
R.string.most_played_artists,
artists,
HomeAdapter.TOP_ARTISTS,
R.drawable.ic_artist_white_24dp
));
}
} catch (e: Exception) {
Error(e)
}
}
override suspend fun favoritePlaylist(): Result<Home> {
return try {
val playlists = PlaylistLoader.getFavoritePlaylist(context)
if (playlists.isEmpty()) {
Error(Throwable("No items found"))
} else {
Success(Home(4,
R.string.favorites,
R.string.favorites_songs,
playlists,
HomeAdapter.PLAYLISTS,
R.drawable.ic_favorite_white_24dp
));
}
} catch (e: Exception) {
Error(e)
}
}
override fun artistInfoFloable( override fun artistInfoFloable(
name: String, name: String,
lang: String?, lang: String?,
@ -37,41 +240,6 @@ class RepositoryImpl(private val context: Context) : Repository {
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
} }
override fun search(query: String?): MutableList<Any> {
return SearchLoader.searchAll(context, query)
}
override fun allAlbums(): ArrayList<Album> {
return AlbumLoader.getAllAlbums(context)
}
override fun recentAlbums(): ArrayList<Album> {
return LastAddedSongsLoader.getLastAddedAlbums(context)
}
override fun topAlbums(): ArrayList<Album> {
return TopAndRecentlyPlayedTracksLoader.getTopAlbums(context)
}
override fun allArtists(): ArrayList<Artist> {
return ArtistLoader.getAllArtists(context)
}
override fun recentArtists(): ArrayList<Artist> {
return LastAddedSongsLoader.getLastAddedArtists(context)
}
override fun topArtists(): ArrayList<Artist> {
return TopAndRecentlyPlayedTracksLoader.getTopArtists(context)
}
override fun allPlaylists(): ArrayList<Playlist> {
return PlaylistLoader.getAllPlaylists(context)
}
override fun allGenres(): ArrayList<Genre> {
return GenreLoader.getAllGenres(context)
}
override fun getSongFlowable(id: Int): Observable<Song> { override fun getSongFlowable(id: Int): Observable<Song> {
return SongLoader.getSongFlowable(context, id) return SongLoader.getSongFlowable(context, id)
@ -91,10 +259,9 @@ class RepositoryImpl(private val context: Context) : Repository {
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
} }
override fun getPlaylistSongsFlowable(playlist: Playlist): Observable<ArrayList<Song>> { override fun getPlaylistSongsFlowable(playlist: Playlist): Observable<ArrayList<Song>> {
return PlaylistSongsLoader.getPlaylistSongListFlowable(context, playlist) return PlaylistSongsLoader.getPlaylistSongListFlowable(context, playlist)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
} }
@ -104,12 +271,6 @@ class RepositoryImpl(private val context: Context) : Repository {
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
} }
override val favoritePlaylist: ArrayList<Playlist>
get() = PlaylistLoader.getFavoritePlaylist(context)
override fun allSongs(): ArrayList<Song> {
return SongLoader.getAllSongs(context)
}
override val favoritePlaylistFlowable: Observable<ArrayList<Playlist>> override val favoritePlaylistFlowable: Observable<ArrayList<Playlist>>
get() = PlaylistLoader.getFavoritePlaylistFlowable(context) get() = PlaylistLoader.getFavoritePlaylistFlowable(context)
@ -180,13 +341,5 @@ class RepositoryImpl(private val context: Context) : Repository {
return ArtistLoader.getArtist(context, artistId.toInt()) return ArtistLoader.getArtist(context, artistId.toInt())
} }
override fun getPlaylistSongs(playlist: Playlist): ArrayList<Song> {
return PlaylistSongsLoader.getPlaylistSongList(context, playlist)
}
override fun getGenre(genreId: Int): ArrayList<Song> {
return GenreLoader.getSongs(context, genreId)
}
} }

View file

@ -14,6 +14,7 @@
package code.name.monkey.retromusic.providers.interfaces package code.name.monkey.retromusic.providers.interfaces
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.* import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.rest.model.LastFmArtist import code.name.monkey.retromusic.rest.model.LastFmArtist
import io.reactivex.Observable import io.reactivex.Observable
@ -24,44 +25,52 @@ import io.reactivex.Observable
interface Repository { interface Repository {
val allSongsFlowable: Observable<ArrayList<Song>> suspend fun allAlbums(): Result<ArrayList<Album>>
fun allSongs(): ArrayList<Song> suspend fun allSongs(): Result<ArrayList<Song>>
suspend fun allArtists(): Result<ArrayList<Artist>>
suspend fun allPlaylists(): Result<ArrayList<Playlist>>
suspend fun allGenres(): Result<ArrayList<Genre>>
suspend fun search(query: String?): Result<MutableList<Any>>
suspend fun getPlaylistSongs(playlist: Playlist): Result<ArrayList<Song>>
suspend fun getGenre(genreId: Int): Result<ArrayList<Song>>
suspend fun recentArtists(): Result<Home>
suspend fun topArtists(): Result<Home>
suspend fun topAlbums(): Result<Home>
suspend fun recentAlbums(): Result<Home>
suspend fun favoritePlaylist(): Result<Home>
val allSongsFlowable: Observable<ArrayList<Song>>
val suggestionSongsFlowable: Observable<ArrayList<Song>> val suggestionSongsFlowable: Observable<ArrayList<Song>>
val allAlbumsFlowable: Observable<ArrayList<Album>> val allAlbumsFlowable: Observable<ArrayList<Album>>
fun allAlbums(): ArrayList<Album>
val recentAlbumsFlowable: Observable<ArrayList<Album>> val recentAlbumsFlowable: Observable<ArrayList<Album>>
fun recentAlbums(): ArrayList<Album>
val topAlbumsFlowable: Observable<ArrayList<Album>> val topAlbumsFlowable: Observable<ArrayList<Album>>
fun topAlbums(): ArrayList<Album>
val allArtistsFlowable: Observable<ArrayList<Artist>> val allArtistsFlowable: Observable<ArrayList<Artist>>
fun allArtists(): ArrayList<Artist>
val recentArtistsFlowable: Observable<ArrayList<Artist>> val recentArtistsFlowable: Observable<ArrayList<Artist>>
fun recentArtists(): ArrayList<Artist>
val topArtistsFlowable: Observable<ArrayList<Artist>> val topArtistsFlowable: Observable<ArrayList<Artist>>
fun topArtists(): ArrayList<Artist>
val allPlaylistsFlowable: Observable<ArrayList<Playlist>> val allPlaylistsFlowable: Observable<ArrayList<Playlist>>
fun allPlaylists(): ArrayList<Playlist>
val allGenresFlowable: Observable<ArrayList<Genre>> val allGenresFlowable: Observable<ArrayList<Genre>>
fun allGenres(): ArrayList<Genre>
fun getSongFlowable(id: Int): Observable<Song> fun getSongFlowable(id: Int): Observable<Song>
fun getSong(id: Int): Song fun getSong(id: Int): Song
@ -74,19 +83,13 @@ interface Repository {
fun getArtistById(artistId: Long): Artist fun getArtistById(artistId: Long): Artist
fun search(query: String?): MutableList<Any>
fun getPlaylistSongsFlowable(playlist: Playlist): Observable<ArrayList<Song>> fun getPlaylistSongsFlowable(playlist: Playlist): Observable<ArrayList<Song>>
fun getPlaylistSongs(playlist: Playlist): ArrayList<Song>
fun getGenreFlowable(genreId: Int): Observable<ArrayList<Song>> fun getGenreFlowable(genreId: Int): Observable<ArrayList<Song>>
fun getGenre(genreId: Int): ArrayList<Song>
val favoritePlaylistFlowable: Observable<ArrayList<Playlist>> val favoritePlaylistFlowable: Observable<ArrayList<Playlist>>
val favoritePlaylist: ArrayList<Playlist>
fun artistInfoFloable(name: String, fun artistInfoFloable(name: String,
lang: String?, lang: String?,

View file

@ -77,7 +77,6 @@ import code.name.monkey.retromusic.service.notification.PlayingNotificationImpl2
import code.name.monkey.retromusic.service.notification.PlayingNotificationOreo; import code.name.monkey.retromusic.service.notification.PlayingNotificationOreo;
import code.name.monkey.retromusic.service.playback.Playback; import code.name.monkey.retromusic.service.playback.Playback;
import code.name.monkey.retromusic.util.MusicUtil; import code.name.monkey.retromusic.util.MusicUtil;
import code.name.monkey.retromusic.util.PackageValidator;
import code.name.monkey.retromusic.util.PreferenceUtil; import code.name.monkey.retromusic.util.PreferenceUtil;
import code.name.monkey.retromusic.util.RetroUtil; import code.name.monkey.retromusic.util.RetroUtil;
@ -275,7 +274,6 @@ public class MusicService extends Service implements
} }
} }
}; };
private PackageValidator mPackageValidator;
private static String getTrackUri(@NonNull Song song) { private static String getTrackUri(@NonNull Song song) {
return MusicUtil.getSongFileUri(song.getId()).toString(); return MusicUtil.getSongFileUri(song.getId()).toString();
@ -341,9 +339,6 @@ public class MusicService extends Service implements
restoreState(); restoreState();
mPackageValidator = new PackageValidator(this, R.xml.allowed_media_browser_callers);
sendBroadcast(new Intent("code.name.monkey.retromusic.RETRO_MUSIC_SERVICE_CREATED")); sendBroadcast(new Intent("code.name.monkey.retromusic.RETRO_MUSIC_SERVICE_CREATED"));
registerHeadsetEvents(); registerHeadsetEvents();

View file

@ -23,6 +23,7 @@ import android.graphics.Color
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.widget.RemoteViews import android.widget.RemoteViews
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
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.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
@ -113,7 +114,7 @@ class PlayingNotificationOreo : PlayingNotification() {
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) { override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable) super.onLoadFailed(e, errorDrawable)
update(null, Color.TRANSPARENT) update(null, ATHUtil.resolveColor(service, R.attr.colorPrimary, Color.WHITE))
} }
private fun update(bitmap: Bitmap?, bgColor: Int) { private fun update(bitmap: Bitmap?, bgColor: Int) {
@ -127,7 +128,7 @@ class PlayingNotificationOreo : PlayingNotification() {
} }
if (!PreferenceUtil.getInstance(service).coloredNotification()) { if (!PreferenceUtil.getInstance(service).coloredNotification()) {
bgColorFinal = Color.WHITE bgColorFinal = ATHUtil.resolveColor(service, R.attr.colorPrimary, Color.WHITE)
} }
setBackgroundColor(bgColorFinal) setBackgroundColor(bgColorFinal)
setNotificationContent(ColorUtil.isColorLight(bgColorFinal)) setNotificationContent(ColorUtil.isColorLight(bgColorFinal))
@ -139,12 +140,8 @@ class PlayingNotificationOreo : PlayingNotification() {
} }
private fun setBackgroundColor(color: Int) { private fun setBackgroundColor(color: Int) {
notificationLayout.setInt(R.id.image, "setBackgroundColor", color) notificationLayout.setInt(R.id.image, "setBackgroundColor", color)
notificationLayoutBig.setInt(R.id.image, "setBackgroundColor", color) notificationLayoutBig.setInt(R.id.image, "setBackgroundColor", color)
notificationLayout.setInt(R.id.foregroundImage, "setColorFilter", color)
notificationLayoutBig.setInt(R.id.foregroundImage, "setColorFilter", color)
} }
private fun setNotificationContent(dark: Boolean) { private fun setNotificationContent(dark: Boolean) {

View file

@ -12,7 +12,7 @@
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
*/ */
package code.name.monkey.retromusic.transform package code.name.monkey.retromusic.util
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@ -20,7 +20,6 @@ import android.content.SharedPreferences
import android.graphics.Color import android.graphics.Color
import android.net.Uri import android.net.Uri
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.LayoutMode import com.afollestad.materialdialogs.LayoutMode
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.WhichButton import com.afollestad.materialdialogs.WhichButton
@ -58,7 +57,7 @@ object AppRater {
// Wait at least n days before opening // Wait at least n days before opening
if (launchCount >= LAUNCHES_UNTIL_PROMPT) { if (launchCount >= LAUNCHES_UNTIL_PROMPT) {
if (System.currentTimeMillis() >= dateFirstLaunch + DAYS_UNTIL_PROMPT * 24 * 60 * 60 * 1000) { if (System.currentTimeMillis() >= dateFirstLaunch + DAYS_UNTIL_PROMPT * 24 * 60 * 60 * 1000) {
showRateDialog(context, editor) showRateDialog(context, editor)
} }
} }

View file

@ -16,9 +16,7 @@ package code.name.monkey.retromusic.util;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.res.Resources;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.TypedValue;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -33,38 +31,9 @@ public class DensityUtil {
return displayMetrics.heightPixels; return displayMetrics.heightPixels;
} }
public static int getScreenWidth(@NonNull Context context) {
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.widthPixels;
}
public static int dip2px(@NonNull Context context, float dpVale) { public static int dip2px(@NonNull Context context, float dpVale) {
final float scale = context.getResources().getDisplayMetrics().density; final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpVale * scale + 0.5f); return (int) (dpVale * scale + 0.5f);
} }
public static int getStatusBarHeight(@NonNull Context context) {
Resources resources = context.getResources();
int resourcesId = resources.getIdentifier("status_bar_height", "dimen", "android");
int height = resources.getDimensionPixelSize(resourcesId);
return height;
}
/**
* Converts sp to px
*
* @param context Context
* @param sp the value in sp
* @return int
*/
public static int dip2sp(@NonNull Context context, float sp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, context.getResources().getDisplayMetrics());
}
public static int px2dip(@NonNull Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
} }

View file

@ -0,0 +1,101 @@
/*
* 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.util
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Environment
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
/**
* Created by hemanths on 2019-11-05.
*/
class ImageSaver(val context: Context) {
private var external: Boolean = false
private var directoryName: String = "RetroMusic"
private var fileName: String = "profile.png"
fun setFileName(fileName: String): ImageSaver {
this.fileName = fileName
return this
}
fun setDirectoryName(directoryName: String): ImageSaver {
this.directoryName = directoryName
return this
}
fun setStoreType(external: Boolean): ImageSaver {
this.external = external
return this
}
fun save(bitmap: Bitmap) {
var fileOutputStream: FileOutputStream? = null
try {
fileOutputStream = FileOutputStream(createFile())
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)
} catch (er: Exception) {
println(er)
} finally {
try {
fileOutputStream?.close()
} catch (er: IOException) {
println(er)
}
}
}
fun getFile(): File {
return createFile()
}
private fun createFile(): File {
val directory: File = if (external) {
getFileStorePlace(directoryName)
} else {
context.getDir(directoryName, Context.MODE_PRIVATE)
}
if (!directory.exists() && !directory.mkdirs()) {
println("Error in creating folders $directory")
}
println("Create file -> $directory/$fileName")
return File(directory, fileName)
}
private fun getFileStorePlace(directoryName: String): File {
return File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), directoryName)
}
fun load(): Bitmap? {
var inputStream: FileInputStream? = null
return try {
inputStream = FileInputStream(createFile())
BitmapFactory.decodeStream(inputStream)
} catch (er: Exception) {
try {
inputStream?.close()
} catch (e: IOException) {
e.printStackTrace()
}
null
}
}
}

View file

@ -16,6 +16,8 @@ package code.name.monkey.retromusic.util;
import android.util.Base64; import android.util.Base64;
import androidx.annotation.NonNull;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -25,8 +27,6 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import androidx.annotation.NonNull;
/** /**
* Created by hefuyi on 2016/11/8. * Created by hefuyi on 2016/11/8.
*/ */
@ -40,11 +40,11 @@ public class LyricUtil {
public static File writeLrcToLoc(@NonNull String title, @NonNull String artist, @NonNull String lrcContext) { public static File writeLrcToLoc(@NonNull String title, @NonNull String artist, @NonNull String lrcContext) {
FileWriter writer = null; FileWriter writer = null;
try { try {
File file = new File(getLrcPath(title, artist)); File file = new File(getLrcPath2(title, artist));
if (!file.getParentFile().exists()) { if (!file.exists()) {
file.getParentFile().mkdirs(); file.mkdirs();
} }
writer = new FileWriter(getLrcPath(title, artist)); writer = new FileWriter(getLrcPath2(title, artist));
writer.write(lrcContext); writer.write(lrcContext);
return file; return file;
} catch (IOException e) { } catch (IOException e) {
@ -70,17 +70,46 @@ public class LyricUtil {
return file.exists(); return file.exists();
} }
@NonNull public static boolean isLrcFile2Exist(@NonNull String title, @NonNull String artist) {
public static File getLocalLyricFile(@NonNull String title, @NonNull String artist) { File file = new File(getLrcPath2(title, artist));
File file = new File(getLrcPath(title, artist));
if (file.exists()) { return file.exists();
return file;
} else {
return new File("lyric file not exist");
}
} }
private static String getLrcPath(String title, String artist) { @NonNull
public static File getLocalLyricFile(@NonNull String title, @NonNull String artist) {
try{
File file = new File(getLrcPath(title, artist));
File file2 = new File(getLrcPath2(title, artist));
if (file.exists()) {
return file;
} else if (file2.exists()) {
return file2;
}
else {
return new File("lyric file not exist");
}} catch (Exception dfs){
dfs.printStackTrace();
return new File("lyric file not exist");
}
}
public static String getLrcPath2(String title, String artist) {
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;
}
public static String getLrcPath(String title, String artist) {
return lrcRootPath + title + " - " + artist + ".lrc"; return lrcRootPath + title + " - " + artist + ".lrc";
} }
@ -103,10 +132,18 @@ public class LyricUtil {
@NonNull @NonNull
public static String getStringFromFile(@NonNull String title, @NonNull String artist) throws Exception { public static String getStringFromFile(@NonNull String title, @NonNull String artist) throws Exception {
File file = new File(getLrcPath(title, artist)); File file;
File file2 = new File(getLrcPath(title, artist));
File file3 = new File(getLrcPath2(title, artist));
if(file2.exists()){
file = file2;
} else {
file = file3;
}
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);
return ret; return ret;
} }

Some files were not shown because too many files have changed in this diff Show more