Fix stroke in now playing

main
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
applicationId "code.name.monkey.retromusic"
versionCode 379
versionName '3.4.400-beta05'
versionCode 390
versionName '3.4.600'
multiDexEnabled true
@ -83,6 +83,7 @@ android {
kapt {
generateStubs = true
}
}
def getProperties(String fileName) {
@ -107,9 +108,9 @@ dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation project(':appthemehelper')
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.recyclerview:recyclerview:1.1.0-beta04'
implementation 'androidx.recyclerview:recyclerview:1.1.0-rc01'
implementation "androidx.gridlayout:gridlayout:1.0.0"
implementation "androidx.cardview:cardview: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.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.squareup.retrofit2:retrofit:2.6.1'
implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.1'
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.2'
implementation 'com.afollestad.material-dialogs:core: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.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 'com.github.ksoichiro:android-observablescrollview:1.6.0'
@ -162,5 +167,4 @@ dependencies {
kapt 'com.google.dagger:dagger-compiler:2.23.1'
}
}

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.
*/
package code.name.monkey.retromusic.util.schedulers;
import androidx.annotation.NonNull;
import io.reactivex.Scheduler;
package code.name.monkey.retromusic
/**
* Created by hemanths on 12/08/17.
* Created by hemanths on 2019-10-23.
*/
public interface BaseSchedulerProvider {
@NonNull
Scheduler computation();
@NonNull
Scheduler io();
@NonNull
Scheduler ui();
}
sealed class Result<out T : Any> {
class Success<out T : Any>(val data: T) : Result<T>()
class Error(val exception: Throwable) : Result<Nothing>()
}

View File

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

View File

@ -2,7 +2,6 @@ package code.name.monkey.retromusic.activities
import android.app.ActivityOptions
import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
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.ColorUtil
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.R
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.helper.MusicPlayerRemote
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.Artist
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.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import com.google.android.material.appbar.AppBarLayout
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.activity_album.*
import kotlinx.android.synthetic.main.activity_album_content.*
@ -66,6 +61,9 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
private fun setupWindowTransition() {
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)
window.enterTransition = slide
}
@ -75,21 +73,21 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
setupWindowTransition()
//setupWindowTransition()
super.onCreate(savedInstanceState)
App.musicComponent.inject(this)
toggleBottomNavigationView(true)
setLightNavigationBar(true)
setStatusbarColor(Color.TRANSPARENT)
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()
artistImage = findViewById(R.id.artistImage)
setupRecyclerView()
setupToolbarMarginHeight()
artistImage.setOnClickListener {
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() {
super.onDestroy()
disposable.dispose()
@ -178,8 +139,11 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
this.album = album
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()
simpleSongAdapter.swapDataSet(album.songs)
albumDetailsPresenter.loadMore(album.artistId)
@ -190,7 +154,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
override fun moreAlbums(albums: ArrayList<Album>) {
moreTitle.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)
moreRecyclerView.layoutManager = GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false)
@ -201,6 +165,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
ArtistGlideRequest.Builder.from(Glide.with(this), artist)
.generatePalette(this).build()
.dontAnimate()
.dontTransform()
.into(object : RetroMusicColoredTarget(artistImage) {
override fun onColorReady(color: Int) {
@ -213,7 +178,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
SongGlideRequest.Builder.from(Glide.with(this), album.safeGetFirstSong())
.checkIgnoreMediaStore(this)
.generatePalette(this).build()
.dontAnimate()
.dontAnimate().dontTransform()
.into(object : RetroMusicColoredTarget(image) {
override fun onColorReady(color: Int) {
setColors(color)
@ -244,7 +209,10 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
MaterialUtil.setTint(button = shuffleAction, 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.content.Intent
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.text.Html
import android.text.Spanned
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.widget.Toast
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.ColorUtil
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.R
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.RetroMusicColoredTarget
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.mvp.presenter.ArtistDetailsPresenter
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.util.*
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_details.*
import java.util.*
@ -70,12 +69,14 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
setupWindowTransitions()
// setupWindowTransitions()
super.onCreate(savedInstanceState)
contentContainer?.setCardBackgroundColor(ColorStateList.valueOf(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
toggleBottomNavigationView(true)
setStatusbarColor(Color.TRANSPARENT)
setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
setLightNavigationBar(true)
setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary)))
ActivityCompat.postponeEnterTransition(this)
@ -115,7 +116,6 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
private fun setUpViews() {
setupRecyclerView()
setupToolbarMarginHeight()
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() {
albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), false, null)
@ -261,7 +226,8 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
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)
songTitle.setTextColor(textColor)
@ -272,6 +238,10 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
MaterialUtil.setTint(button = shuffleAction, 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 code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.util.ATHUtil;
import code.name.monkey.appthemehelper.util.ColorUtil;
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
import code.name.monkey.retromusic.R;
@ -66,7 +65,7 @@ public class LicenseActivity extends AbsBaseActivity {
setLightNavigationBar(true);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ToolbarContentTintHelper.colorBackButton(toolbar, ATHUtil.INSTANCE.resolveColor(this, R.attr.colorOnSurface));
ToolbarContentTintHelper.colorBackButton(toolbar );
WebView webView = findViewById(R.id.license);
try {
StringBuilder buf = new StringBuilder();

View File

@ -150,8 +150,13 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
private fun showSyncedLyrics() {
var content = ""
try {
content = LyricUtil.getStringFromFile(song.title, song.artistName)
content = LyricUtil.getStringFromFile(song.data, song.artistName)
} catch (e: Exception) {
try {
content = LyricUtil.getStringFromFile(song.title, song.artistName)
} catch (e2: Exception) {
}
e.printStackTrace()
}
@ -161,7 +166,7 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
input(hint = getString(R.string.paste_lyrics_here),
prefill = content,
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) {
updateSong()
@ -215,7 +220,7 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
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,
val fragment: Fragment)
@ -364,8 +369,12 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
private fun loadLRCLyrics() {
val song = MusicPlayerRemote.currentSong
if (LyricUtil.isLrcFileExist(song.title, song.artistName)) {
showLyricsLocal(LyricUtil.getLocalLyricFile(song.title, song.artistName))
if (LyricUtil.isLrcFile2Exist(song.data, song.artistName)) {
showLyricsLocal(LyricUtil.getLocalLyricFile(song.data, song.artistName))
} else {
if (LyricUtil.isLrcFileExist(song.title, song.artistName)) {
showLyricsLocal(LyricUtil.getLocalLyricFile(song.title, song.artistName))
}
}
}
@ -375,4 +384,4 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPage
}
}
}
}
}

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.PlaylistSongsLoader
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 io.reactivex.disposables.CompositeDisposable
import java.util.*
@ -64,7 +64,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
}
if (savedInstanceState == null) {
selectedFragment(PreferenceUtil.getInstance(this).lastPage)
setMusicChooser(PreferenceUtil.getInstance(this).lastMusicChooser)
} else {
restoreCurrentFragment()
}
@ -129,7 +129,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
val uri = intent.data
val mimeType = intent.type
var handled = false
println("uri -> $uri")
if (intent.action != null && intent.action == MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) {
val songs = SearchQueryHelper.getSongs(this, intent.extras!!)
if (MusicPlayerRemote.shuffleMode == MusicService.SHUFFLE_MODE_SHUFFLE) {
@ -222,7 +221,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
if (key == PreferenceUtil.GENERAL_THEME ||
key==PreferenceUtil.BLACK_THEME||
key == PreferenceUtil.BLACK_THEME ||
key == PreferenceUtil.ADAPTIVE_COLOR_APP ||
key == PreferenceUtil.DOMINANT_COLOR ||
key == PreferenceUtil.USER_NAME ||
@ -244,6 +243,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
key == PreferenceUtil.ALBUM_COVER_STYLE ||
key == PreferenceUtil.HOME_ARTIST_GRID_STYLE ||
key == PreferenceUtil.ALBUM_COVER_TRANSFORM ||
key == PreferenceUtil.DESATURATED_COLOR ||
key == PreferenceUtil.TAB_TEXT_MODE ||
key == PreferenceUtil.LIBRARY_CATEGORIES)
postRecreate()
@ -264,7 +264,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
}*/
}
fun selectedFragment(itemId: Int) {
private fun selectedFragment(itemId: Int) {
when (itemId) {
R.id.action_album,
R.id.action_artist,
@ -272,16 +272,25 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
R.id.action_genre,
R.id.action_song -> setCurrentFragment(LibraryFragment.newInstance(itemId), itemId.toString())
R.id.action_home -> setCurrentFragment(BannerHomeFragment.newInstance(), BannerHomeFragment.TAG)
R.id.action_folder -> setCurrentFragment(FoldersFragment.newInstance(this), FoldersFragment.TAG)
else -> {
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 {
const val APP_INTRO_REQUEST = 2323
const val HOME = 0
const val FOLDER = 1
const val LIBRARY = 2
private const val TAG = "MainActivity"
private const val APP_USER_INFO_REQUEST = 9003
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.extensions.applyToolbar
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.util.DensityUtil
import code.name.monkey.retromusic.util.MusicUtil
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator
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.*
class PlayingQueueActivity : AbsMusicServiceActivity() {
open class PlayingQueueActivity : AbsMusicServiceActivity() {
private var wrappedAdapter: RecyclerView.Adapter<*>? = null
private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null
@ -29,7 +30,7 @@ class PlayingQueueActivity : AbsMusicServiceActivity() {
private lateinit var linearLayoutManager: LinearLayoutManager
protected fun getUpNextAndQueueTime(): String {
private fun getUpNextAndQueueTime(): String {
val duration = MusicPlayerRemote.getQueueDurationMillis(MusicPlayerRemote.position)
return MusicUtil.buildInfoString(
@ -55,6 +56,7 @@ class PlayingQueueActivity : AbsMusicServiceActivity() {
clearQueue.setOnClickListener {
MusicPlayerRemote.clearQueue()
}
checkForPadding()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
@ -76,7 +78,7 @@ class PlayingQueueActivity : AbsMusicServiceActivity() {
MusicPlayerRemote.playingQueue,
MusicPlayerRemote.position,
R.layout.item_queue)
wrappedAdapter = recyclerViewDragDropManager!!.createWrappedAdapter(playingQueueAdapter!!)
wrappedAdapter = recyclerViewDragDropManager?.createWrappedAdapter(playingQueueAdapter!!)
linearLayoutManager = LinearLayoutManager(this)
@ -84,7 +86,7 @@ class PlayingQueueActivity : AbsMusicServiceActivity() {
layoutManager = linearLayoutManager
adapter = wrappedAdapter
itemAnimator = animator
recyclerViewDragDropManager!!.attachRecyclerView(this)
recyclerViewDragDropManager?.attachRecyclerView(this)
}
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() {
if (MusicPlayerRemote.playingQueue.isEmpty()) {
finish()
return
}
checkForPadding()
updateQueue()
updateCurrentSong()
}
@ -124,13 +132,13 @@ class PlayingQueueActivity : AbsMusicServiceActivity() {
}
private fun updateQueuePosition() {
playingQueueAdapter!!.setCurrent(MusicPlayerRemote.position)
playingQueueAdapter?.setCurrent(MusicPlayerRemote.position)
resetToCurrentPosition()
playerQueueSubHeader.text = getUpNextAndQueueTime()
}
private fun updateQueue() {
playingQueueAdapter!!.swapDataSet(MusicPlayerRemote.playingQueue, MusicPlayerRemote.position)
playingQueueAdapter?.swapDataSet(MusicPlayerRemote.playingQueue, MusicPlayerRemote.position)
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.mvp.presenter.PlaylistSongsPresenter
import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsView
import code.name.monkey.retromusic.util.DensityUtil
import code.name.monkey.retromusic.util.PlaylistsUtil
import code.name.monkey.retromusic.util.RetroColorUtil
import code.name.monkey.retromusic.util.ViewUtil
@ -50,6 +51,9 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
super.onCreate(savedInstanceState)
App.musicComponent.inject(this)
playlistSongsPresenter.attachView(this)
setStatusbarColor(Color.TRANSPARENT)
setNavigationbarColorAuto()
@ -65,10 +69,6 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
finish()
}
App.musicComponent.inject(this)
playlistSongsPresenter.attachView(this)
setUpToolBar()
setUpRecyclerView()
}
@ -160,14 +160,12 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
override fun onMediaStoreChanged() {
super.onMediaStoreChanged()
if (playlist !is AbsCustomPlaylist) {
// Playlist deleted
if (!PlaylistsUtil.doesPlaylistExist(this, playlist.id)) {
finish()
return
}
// Playlist renamed
val playlistName = PlaylistsUtil.getNameForPlaylist(this, playlist.id.toLong())
if (playlistName != playlist.name) {
@ -182,8 +180,13 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
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
emptyText.visibility = if (adapter.itemCount == 0) View.VISIBLE else View.GONE
}

View File

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

View File

@ -39,7 +39,7 @@ class SettingsActivity : AbsBaseActivity() {
setTitleTextColor(ATHUtil.resolveColor(this@SettingsActivity, R.attr.colorOnPrimary))
setBackgroundColor(ATHUtil.resolveColor(this@SettingsActivity, R.attr.colorPrimary))
setNavigationOnClickListener { onBackPressed() }
ToolbarContentTintHelper.colorBackButton(toolbar, ATHUtil.resolveColor(this@SettingsActivity, R.attr.colorOnSecondary))
ToolbarContentTintHelper.colorBackButton(toolbar)
}
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.Toast
import androidx.annotation.LayoutRes
import androidx.appcompat.widget.AppCompatImageView
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
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.activities.base.AbsBaseActivity
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.SkuDetails
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()
init {
@ -218,7 +221,7 @@ class SkuDetailsAdapter(private var donationsDialog: SupportDevelopmentActivity,
var title: TextView = view.findViewById(R.id.itemTitle)
var text: TextView = view.findViewById(R.id.itemText)
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 {

View File

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

View File

@ -19,7 +19,6 @@ import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.util.ATHUtil;
import code.name.monkey.appthemehelper.util.ColorUtil;
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
import code.name.monkey.retromusic.R;
@ -67,7 +66,7 @@ public class WhatsNewActivity extends AbsBaseActivity {
//setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(v -> onBackPressed());
ToolbarContentTintHelper.colorBackButton(toolbar, ATHUtil.INSTANCE.resolveColor(this, R.attr.colorOnSecondary));
ToolbarContentTintHelper.colorBackButton(toolbar);
try {
StringBuilder buf = new StringBuilder();

View File

@ -2,7 +2,10 @@ package code.name.monkey.retromusic.activities.base
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.graphics.Color
import android.graphics.Rect
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
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.ColorUtil
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.NowPlayingScreen
import code.name.monkey.retromusic.fragments.NowPlayingScreen.*
@ -60,6 +65,8 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
override fun onSlide(bottomSheet: View, slideOffset: Float) {
setMiniPlayerAlphaProgress(slideOffset)
dimBackground.show()
dimBackground.alpha = slideOffset
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
@ -69,6 +76,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
}
BottomSheetBehavior.STATE_COLLAPSED -> {
onPanelCollapsed()
dimBackground.hide()
}
else -> {
@ -88,6 +96,9 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
updateTabs()
bottomSheetBehavior = BottomSheetBehavior.from(slidingPanel)
val themeColor = ATHUtil.resolveColor(this, R.attr.colorPrimary, Color.GRAY)
dimBackground.setBackgroundColor(ColorUtil.withAlpha(themeColor, 0.5f))
}
override fun onResume() {
@ -117,16 +128,13 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
return slidingMusicPanelLayout
}
fun setAntiDragView(antiDragView: View) {
//slidingLayout.setAntiDragView(antiDragView)
}
private fun collapsePanel() {
bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
}
fun expandPanel() {
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
setMiniPlayerAlphaProgress(1f)
}
private fun setMiniPlayerAlphaProgress(progress: Float) {
@ -175,7 +183,6 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
}
when (panelState) {
BottomSheetBehavior.STATE_EXPANDED -> {
onPanelExpanded()
}
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.core.content.ContextCompat
import code.name.monkey.appthemehelper.ATH
import code.name.monkey.appthemehelper.ATHActivity
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.ColorUtil
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.ThemeManager
abstract class AbsThemeActivity : ATHActivity(), Runnable {
abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
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.MaterialUtil
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsThemeActivity
import code.name.monkey.retromusic.activities.bugreport.model.DeviceInfo
@ -58,7 +59,6 @@ open class BugReportActivity : AbsThemeActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_bug_report)
setStatusbarColorAuto()
setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
@ -68,53 +68,51 @@ open class BugReportActivity : AbsThemeActivity() {
if (TextUtils.isEmpty(title))
setTitle(R.string.report_an_issue)
deviceInfo = DeviceInfo(this)
airTextDeviceInfo!!.text = deviceInfo!!.toString()
airTextDeviceInfo.text = deviceInfo.toString()
}
private fun initViews() {
val accentColor = ThemeStore.accentColor(this)
val primaryColor = ATHUtil.resolveColor(this, R.attr.colorPrimary)
toolbar!!.setBackgroundColor(primaryColor)
toolbar.setBackgroundColor(primaryColor)
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)
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() {
optionAnonymous.isChecked = false
sendFab.hide(object : FloatingActionButton.OnVisibilityChangedListener() {
override fun onHidden(fab: FloatingActionButton?) {
super.onHidden(fab)
sendFab!!.setImageResource(R.drawable.ic_send_white_24dp)
sendFab!!.show()
sendFab.setImageResource(R.drawable.ic_send_white_24dp)
sendFab.show()
}
})
}
TintHelper.setTintAuto(optionAnonymous!!, accentColor, false)
optionAnonymous!!.setOnClickListener {
inputTitle!!.isEnabled = false
inputDescription!!.isEnabled = false
inputUsername!!.isEnabled = false
inputPassword!!.isEnabled = false
TintHelper.setTintAuto(optionAnonymous, accentColor, false)
optionAnonymous.setOnClickListener {
inputTitle.isEnabled = false
inputDescription.isEnabled = false
inputUsername.isEnabled = false
inputPassword.isEnabled = false
optionUseAccount!!.isChecked = false
sendFab!!.hide(object : FloatingActionButton.OnVisibilityChangedListener() {
optionUseAccount.isChecked = false
sendFab.hide(object : FloatingActionButton.OnVisibilityChangedListener() {
override fun onHidden(fab: FloatingActionButton?) {
super.onHidden(fab)
sendFab!!.setImageResource(R.drawable.ic_open_in_browser_white_24dp)
sendFab!!.show()
sendFab.setImageResource(R.drawable.ic_open_in_browser_white_24dp)
sendFab.show()
}
})
}
inputPassword!!.setOnEditorActionListener { _, actionId, _ ->
inputPassword.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_SEND) {
reportIssue()
return@setOnEditorActionListener true
@ -122,10 +120,10 @@ open class BugReportActivity : AbsThemeActivity() {
false
}
airTextDeviceInfo!!.setOnClickListener { copyDeviceInfoToClipBoard() }
airTextDeviceInfo.setOnClickListener { copyDeviceInfoToClipBoard() }
TintHelper.setTintAuto(sendFab!!, accentColor, true)
sendFab!!.setOnClickListener { reportIssue() }
TintHelper.setTintAuto(sendFab, accentColor, true)
sendFab.setOnClickListener { reportIssue() }
MaterialUtil.setTint(inputLayoutTitle, false)
MaterialUtil.setTint(inputLayoutDescription, false)
@ -134,10 +132,10 @@ open class BugReportActivity : AbsThemeActivity() {
}
private fun reportIssue() {
if (optionUseAccount!!.isChecked) {
if (optionUseAccount.isChecked) {
if (!validateInput()) return
val username = inputUsername!!.text!!.toString()
val password = inputPassword!!.text!!.toString()
val username = inputUsername.text.toString()
val password = inputPassword.text.toString()
sendBugReport(GithubLogin(username, password))
} else {
copyDeviceInfoToClipBoard()
@ -151,43 +149,42 @@ open class BugReportActivity : AbsThemeActivity() {
private fun copyDeviceInfoToClipBoard() {
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText(getString(R.string.device_info), deviceInfo!!.toMarkdown())
clipboard.setPrimaryClip(clip)
val clip = ClipData.newPlainText(getString(R.string.device_info), deviceInfo?.toMarkdown())
clipboard.primaryClip = clip
Toast.makeText(this@BugReportActivity, R.string.copied_device_info_to_clipboard, Toast.LENGTH_LONG).show()
}
private fun validateInput(): Boolean {
var hasErrors = false
if (optionUseAccount!!.isChecked) {
if (TextUtils.isEmpty(inputUsername!!.text)) {
setError(inputLayoutUsername!!, R.string.bug_report_no_username)
if (optionUseAccount.isChecked) {
if (TextUtils.isEmpty(inputUsername.text)) {
setError(inputLayoutUsername, R.string.bug_report_no_username)
hasErrors = true
} else {
removeError(inputLayoutUsername!!)
removeError(inputLayoutUsername)
}
if (TextUtils.isEmpty(inputPassword!!.text)) {
setError(inputLayoutPassword!!, R.string.bug_report_no_password)
if (TextUtils.isEmpty(inputPassword.text)) {
setError(inputLayoutPassword, R.string.bug_report_no_password)
hasErrors = true
} else {
removeError(inputLayoutPassword!!)
removeError(inputLayoutPassword)
}
}
if (TextUtils.isEmpty(inputTitle!!.text)) {
setError(inputLayoutTitle!!, R.string.bug_report_no_title)
if (TextUtils.isEmpty(inputTitle.text)) {
setError(inputLayoutTitle, R.string.bug_report_no_title)
hasErrors = true
} else {
removeError(inputLayoutTitle!!)
removeError(inputLayoutTitle)
}
if (TextUtils.isEmpty(inputDescription!!.text)) {
setError(inputLayoutDescription!!, R.string.bug_report_no_description)
if (TextUtils.isEmpty(inputDescription.text)) {
setError(inputLayoutDescription, R.string.bug_report_no_description)
hasErrors = true
} else {
removeError(inputLayoutDescription!!)
removeError(inputLayoutDescription)
}
return !hasErrors
@ -204,8 +201,8 @@ open class BugReportActivity : AbsThemeActivity() {
private fun sendBugReport(login: GithubLogin) {
if (!validateInput()) return
val bugTitle = inputTitle!!.text!!.toString()
val bugDescription = inputDescription!!.text!!.toString()
val bugTitle = inputTitle.text.toString()
val bugDescription = inputDescription.text.toString()
val extraInfo = ExtraInfo()
onSaveExtraInfo()

View File

@ -51,7 +51,7 @@ class ContributorAdapter(
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val title: TextView = itemView.findViewById(R.id.title)
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) {
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.artist.ArtistAdapter
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.model.Album
import code.name.monkey.retromusic.model.Artist
@ -23,12 +24,13 @@ import com.google.android.material.textview.MaterialTextView
class HomeAdapter(
private val activity: AppCompatActivity,
private var homes: List<Home>,
private val displayMetrics: DisplayMetrics
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var list = ArrayList<Home>()
override fun getItemViewType(position: Int): Int {
return homes[position].homeSection
return list[position].homeSection
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
@ -43,89 +45,137 @@ class HomeAdapter(
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val home = homes[position]
println("ViewType ${getItemViewType(position)}")
when (getItemViewType(position)) {
RECENT_ALBUMS, TOP_ALBUMS -> {
RECENT_ALBUMS -> {
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
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 -> {
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 {
return homes.size
return list.size
}
fun swapData(finalList: List<Home>) {
homes = finalList
fun swapData(sections: ArrayList<Home>) {
list = sections
notifyDataSetChanged()
}
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)
annotation class HomeSection
const val RECENT_ALBUMS = 0
const val RECENT_ALBUMS = 3
const val TOP_ALBUMS = 1
const val RECENT_ARTISTS = 2
const val TOP_ARTISTS = 3
const val GENRES = 4
const val PLAYLISTS = 5
const val TOP_ARTISTS = 0
const val PLAYLISTS = 4
}
private inner class AlbumViewHolder(view: View) : AbsHomeViewItem(view) {
fun bindView(home: Home) {
recyclerView.apply {
adapter = AlbumFullWidthAdapter(activity, home.arrayList as ArrayList<Album>, displayMetrics)
fun bindView(list: ArrayList<Album>, titleRes: Int, subtitleRes: Int) {
if (list.isNotEmpty()) {
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) {
fun bindView(home: Home) {
recyclerView.apply {
layoutManager = GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
val artistAdapter = ArtistAdapter(activity, home.arrayList as ArrayList<Artist>,
PreferenceUtil.getInstance(activity).getHomeGridStyle(activity), false, null)
adapter = artistAdapter
inner class ArtistViewHolder(view: View) : AbsHomeViewItem(view) {
fun bindView(list: ArrayList<Artist>, titleRes: Int, subtitleRes: Int) {
if (list.isNotEmpty()) {
recyclerView.apply {
show()
layoutManager = GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
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) {
fun bindView(home: Home) {
val songs = PlaylistSongsLoader.getPlaylistSongList(activity, home.arrayList[0] as Playlist)
recyclerView.apply {
val songAdapter = SongAdapter(activity, songs, R.layout.item_album_card, false, null)
layoutManager = GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
adapter = songAdapter
fun bindView(arrayList: ArrayList<Playlist>, titleRes: Int, subtitleRes: Int) {
if (arrayList.isNotEmpty()) {
val songs = PlaylistSongsLoader.getPlaylistSongList(activity, arrayList[0])
if (songs.isNotEmpty()) {
recyclerView.apply {
show()
val songAdapter = SongAdapter(activity, songs, R.layout.item_album_card, 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 titleContainer: View = itemView.findViewById(R.id.titleContainer)
val title: MaterialTextView = itemView.findViewById(R.id.title)
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.NavigationUtil
import com.bumptech.glide.Glide
import java.util.*
import android.util.Pair as UtilPair
class SearchAdapter(
@ -57,7 +56,7 @@ class SearchAdapter(
holder.title?.text = artist.name
holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
ArtistGlideRequest.Builder.from(Glide.with(activity), artist)
.build().into(holder.image);
.build().into(holder.image)
}
SONG -> {
val song = dataSet?.get(position) as Song
@ -79,26 +78,22 @@ class SearchAdapter(
init {
itemView.setOnLongClickListener(null)
if (menu != null) {
if (itemViewType == SONG) {
menu!!.visibility = View.VISIBLE
menu!!.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
override val song: Song
get() = dataSet!![adapterPosition] as Song
})
} else {
menu!!.visibility = View.GONE
}
if (itemViewType == SONG) {
menu?.visibility = View.VISIBLE
menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
override val song: Song
get() = dataSet!![adapterPosition] as Song
})
} else {
menu?.visibility = View.GONE
}
when (itemViewType) {
ALBUM -> setImageTransitionName(activity.getString(R.string.transition_album_art))
ARTIST -> setImageTransitionName(activity.getString(R.string.transition_artist_image))
else -> {
val container = itemView.findViewById<View>(R.id.image_container)
if (container != null) {
container.visibility = View.GONE
}
val container = itemView.findViewById<View>(R.id.imageContainer)
container?.visibility = View.GONE
}
}
}
@ -126,7 +121,6 @@ class SearchAdapter(
}
companion object {
private const val HEADER = 0
private const val ALBUM = 1
private const val ARTIST = 2

View File

@ -55,12 +55,8 @@ class SongFileAdapter(
override fun onBindViewHolder(holder: ViewHolder, index: Int) {
val file = dataSet!![index]
holder.itemView.isActivated = isChecked(file)
if (holder.title != null) {
holder.title!!.text = getFileTitle(file)
}
holder.title?.text = getFileTitle(file)
if (holder.text != null) {
if (holder.itemViewType == 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) {
val album = dataSet[position]
val isChecked = isChecked(album)
holder.itemView.isActivated = isChecked
if (holder.title != null) {
holder.title!!.text = getAlbumTitle(album)
}
if (holder.text != null) {
holder.text!!.text = getAlbumText(album)
}
if (holder.playSongs != null) {
holder.playSongs!!.setOnClickListener { MusicPlayerRemote.openQueue(album.songs!!, 0, true) }
}
holder.title?.text = getAlbumTitle(album)
holder.text?.text = getAlbumText(album)
holder.playSongs?.setOnClickListener { album.songs?.let { songs -> MusicPlayerRemote.openQueue(songs, 0, true) } }
loadAlbumCover(album, holder)
}

View File

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

View File

@ -40,18 +40,10 @@ class AlbumFullWidthAdapter(private val activity: Activity, private val dataSet:
override fun onBindViewHolder(holder: FullMetalViewHolder, position: Int) {
// don't forget about calling supper.onBindViewHolder!
super.onBindViewHolder(holder, position)
val album = dataSet[position]
if (holder.title != null) {
holder.title!!.text = getAlbumTitle(album)
}
if (holder.text != null) {
holder.text!!.text = getAlbumText(album)
}
if (holder.playSongs != null) {
holder.playSongs!!.setOnClickListener { MusicPlayerRemote.openQueue(album.songs!!, 0, true) }
}
holder.title?.text = getAlbumTitle(album)
holder.text?.text = getAlbumText(album)
holder.playSongs?.setOnClickListener { album.songs?.let { songs -> MusicPlayerRemote.openQueue(songs, 0, true) } }
loadAlbumCover(album, holder)
}

View File

@ -126,9 +126,7 @@ class ArtistAdapter(val activity: AppCompatActivity,
init {
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?) {

View File

@ -14,7 +14,6 @@
package code.name.monkey.retromusic.adapter.base;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
@ -81,14 +80,14 @@ public class MediaEntryViewHolder extends RecyclerView.ViewHolder implements Vie
image = itemView.findViewById(R.id.image);
time = itemView.findViewById(R.id.time);
imageText = itemView.findViewById(R.id.image_text);
imageContainer = itemView.findViewById(R.id.image_container);
imageTextContainer = itemView.findViewById(R.id.image_text_container);
imageContainerCard = itemView.findViewById(R.id.image_container_card);
imageText = itemView.findViewById(R.id.imageText);
imageContainer = itemView.findViewById(R.id.imageContainer);
imageTextContainer = itemView.findViewById(R.id.imageTextContainer);
imageContainerCard = itemView.findViewById(R.id.imageContainerCard);
menu = itemView.findViewById(R.id.menu);
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);
mask = itemView.findViewById(R.id.mask);
playSongs = itemView.findViewById(R.id.playSongs);
@ -111,7 +110,7 @@ public class MediaEntryViewHolder extends RecyclerView.ViewHolder implements Vie
}
public void setImageTransitionName(@NonNull String transitionName) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && image != null) {
if (image != null) {
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.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.PopupMenu
import code.name.monkey.appthemehelper.ThemeStore
@ -30,15 +29,15 @@ import code.name.monkey.retromusic.util.NavigationUtil
import java.util.*
class PlaylistAdapter(protected val activity: AppCompatActivity, dataSet: ArrayList<Playlist>,
@param:LayoutRes protected var itemLayoutRes: Int, cabHolder: CabHolder?) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist>(activity, cabHolder, R.menu.menu_playlists_selection) {
var dataSet: ArrayList<Playlist>
protected set
class PlaylistAdapter(private val activity: AppCompatActivity,
var dataSet: ArrayList<Playlist>,
private var itemLayoutRes: Int,
cabHolder: CabHolder?) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist>(activity, cabHolder, R.menu.menu_playlists_selection) {
var songs = ArrayList<Song>()
init {
this.dataSet = dataSet
setHasStableIds(true)
}
@ -70,20 +69,11 @@ class PlaylistAdapter(protected val activity: AppCompatActivity, dataSet: ArrayL
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val playlist = dataSet[position]
val songs = getSongs(playlist)
holder.itemView.isActivated = isChecked(playlist)
if (holder.title != null) {
holder.title!!.text = getPlaylistTitle(playlist)
}
if (holder.text != null) {
holder.text!!.text = getPlaylistText(playlist)
}
if (holder.image != null) {
holder.image!!.setImageDrawable(getIconRes(playlist))
}
holder.title?.text = getPlaylistTitle(playlist)
holder.text?.text = getPlaylistText(playlist)
holder.image?.setImageDrawable(getIconRes(playlist))
}
private fun getIconRes(playlist: Playlist): Drawable {
@ -215,9 +205,7 @@ class PlaylistAdapter(protected val activity: AppCompatActivity, dataSet: ArrayL
}
companion object {
val TAG: String = PlaylistAdapter::class.java.simpleName
private const val SMART_PLAYLIST = 0
private const val DEFAULT_PLAYLIST = 1
}

View File

@ -100,9 +100,9 @@ class OrderablePlaylistSongAdapter(activity: AppCompatActivity,
init {
if (dragView != null) {
if (onMoveItemListener != null) {
dragView!!.visibility = View.VISIBLE
dragView?.visibility = View.VISIBLE
} 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.View
import android.widget.ImageView
import androidx.annotation.ColorInt
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote
@ -20,36 +18,27 @@ import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableI
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
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 {
return ViewHolder(view)
}
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
super.onBindViewHolder(holder, position)
if (holder.imageText != null) {
holder.imageText!!.text = (position - current).toString()
}
if (holder.time != null) {
holder.time!!.text = MusicUtil.getReadableDurationString(dataSet[position].duration)
}
holder.imageText?.text = (position - current).toString()
holder.time?.text = MusicUtil.getReadableDurationString(dataSet[position].duration)
if (holder.itemViewType == HISTORY || holder.itemViewType == CURRENT) {
setAlpha(holder, 0.5f)
}
@ -66,15 +55,10 @@ class PlayingQueueAdapter : SongAdapter, DraggableItemAdapter<PlayingQueueAdapte
holder.title!!.setTextColor(color)
}
}
if (holder.text != null) {
holder.text!!.setTextColor(white)
}
if (holder.time != null) {
holder.time!!.setTextColor(white)
}
if (holder.imageText != null) {
holder.imageText!!.setTextColor(white)
}
holder.text?.setTextColor(white)
holder.time?.setTextColor(white)
holder.imageText?.setTextColor(white)
if (holder.menu != null) {
(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) {
if (holder.image != null) {
holder.image!!.alpha = alpha
}
if (holder.title != null) {
holder.title!!.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
}
holder.image?.alpha = alpha
holder.title?.alpha = alpha
holder.text?.alpha = alpha
holder.imageText?.alpha = alpha
holder.paletteColorContainer?.alpha = alpha
}
override fun onCheckCanStartDrag(holder: ViewHolder, position: Int, x: Int, y: Int): Boolean {
@ -164,12 +138,8 @@ class PlayingQueueAdapter : SongAdapter, DraggableItemAdapter<PlayingQueueAdapte
}
init {
if (imageText != null) {
imageText!!.visibility = View.VISIBLE
}
if (dragView != null) {
dragView!!.visibility = View.VISIBLE
}
imageText?.visibility = View.VISIBLE
dragView?.visibility = View.VISIBLE
}
override fun onSongMenuItemClick(item: MenuItem): Boolean {

View File

@ -47,8 +47,7 @@ class AppWidgetCard : BaseAppWidget() {
* actions if service not running.
*/
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName,
R.layout.app_widget_card)
val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_card)
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
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
*/
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName,
R.layout.app_widget_card)
val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_card)
val isPlaying = service.isPlaying
val song = service.currentSong

View File

@ -49,6 +49,7 @@ class AppWidgetClassic : BaseAppWidget() {
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_classic)
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
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
*/
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName,
R.layout.app_widget_classic)
val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_classic)
val isPlaying = service.isPlaying
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.
*/
protected fun hasInstances(context: Context): Boolean {
private fun hasInstances(context: Context): Boolean {
val appWidgetManager = AppWidgetManager.getInstance(context)
val mAppWidgetIds = appWidgetManager.getAppWidgetIds(ComponentName(context,
javaClass))
return mAppWidgetIds.size > 0
return mAppWidgetIds.isNotEmpty()
}
protected fun buildPendingIntent(context: Context, action: String,

View File

@ -33,10 +33,9 @@ class AddToPlaylistDialog : DialogFragment() {
override fun onCreateDialog(
savedInstanceState: Bundle?
): Dialog {
val cntx = requireContext()
val playlists = PlaylistLoader.getAllPlaylists(cntx)
val playlists = PlaylistLoader.getAllPlaylists(requireContext())
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) {
playlistNames.add(p.name)
}
@ -51,7 +50,7 @@ class AddToPlaylistDialog : DialogFragment() {
activity?.supportFragmentManager?.let { CreatePlaylistDialog.create(songs).show(it, "ADD_TO_PLAYLIST") }
} else {
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.widget.TextView
import androidx.fragment.app.DialogFragment
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.retromusic.R
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 com.afollestad.materialdialogs.LayoutMode
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.customview.customView
import com.afollestad.materialdialogs.customview.getCustomView
@ -67,7 +64,6 @@ class CreatePlaylistDialog : DialogFragment() {
}
}
}
getActionButton(WhichButton.POSITIVE).updateTextColor(ThemeStore.accentColor(context))
}
val dialogView = materialDialog.getCustomView()
@ -77,12 +73,11 @@ class CreatePlaylistDialog : DialogFragment() {
MaterialUtil.setTint(actionNewPlaylistContainer, false)
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
}
companion object {
private const val SONGS = "songs"
@JvmOverloads
fun create(song: Song? = null): CreatePlaylistDialog {
val list = ArrayList<Song>()

View File

@ -35,8 +35,8 @@ class OptionsSheetDialogFragment : DialogFragment(), View.OnClickListener {
override fun onClick(view: View) {
val mainActivity = activity as MainActivity? ?: return
when (view.id) {
R.id.actionFolders -> mainActivity.selectedFragment(R.id.action_folder)
R.id.actionLibrary -> mainActivity.selectedFragment(PreferenceUtil.getInstance(requireContext()).lastPage)
R.id.actionFolders -> mainActivity.setMusicChooser(MainActivity.FOLDER)
R.id.actionLibrary -> mainActivity.setMusicChooser(MainActivity.LIBRARY)
R.id.actionSettings -> NavigationUtil.goToSettings(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.widget.TextView
import androidx.fragment.app.DialogFragment
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.retromusic.R
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 com.afollestad.materialdialogs.LayoutMode
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.customview.customView
import com.afollestad.materialdialogs.customview.getCustomView
@ -55,7 +52,6 @@ class RenamePlaylistDialog : DialogFragment() {
PlaylistsUtil.renamePlaylist(context, playlistId, playlistView.text!!.toString())
}
}
getActionButton(WhichButton.POSITIVE).updateTextColor(ThemeStore.accentColor(context))
}
val dialogView = materialDialog.getCustomView()

View File

@ -181,78 +181,7 @@ class SleepTimerDialog : DialogFragment() {
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) {
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.widget.Toolbar
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
@ -25,8 +24,9 @@ fun AppCompatActivity.applyToolbar(toolbar: Toolbar) {
toolbar.apply {
setNavigationOnClickListener { onBackPressed() }
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))
}
setSupportActionBar(toolbar)
}

View File

@ -12,19 +12,21 @@
* 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 androidx.annotation.AttrRes
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
object AttrsUtil {
@JvmOverloads
fun resolveColor(context: Context, @AttrRes attr: Int, fallback: Int = 0): Int {
val a = context.theme.obtainStyledAttributes(intArrayOf(attr))
try {
return a.getColor(0, fallback)
} finally {
a.recycle()
}
}
/**
* Created by hemanths on 2019-11-01.
*/
fun ArrayList<Song>.lastElement(): Boolean {
println("${this.size} ${this.indexOf(MusicPlayerRemote.currentSong)}")
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
}
fun View.hidden() {
visibility = View.INVISIBLE
}
fun View.showOrHide(show: Boolean) = if (show) show() else hide()
fun EditText.appHandleColor(): EditText {

View File

@ -3,7 +3,6 @@ package code.name.monkey.retromusic.fragments
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.os.AsyncTask
import android.os.Bundle
import android.text.SpannableString
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.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.*
import code.name.monkey.retromusic.util.NavigationUtil
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 kotlin.math.abs
@ -52,9 +53,9 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
actionPrevious.visibility = View.VISIBLE
actionPlayingQueue.visibility = View.VISIBLE
} else {
actionNext.visibility = if (PreferenceUtil.getInstance(requireContext()).isExtraMiniExtraControls) View.VISIBLE else View.GONE
actionPlayingQueue.visibility = if (PreferenceUtil.getInstance(requireContext()).isExtraMiniExtraControls) View.GONE else View.VISIBLE
actionPrevious.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()).isExtraControls) View.GONE else View.VISIBLE
actionPrevious.visibility = if (PreferenceUtil.getInstance(requireContext()).isExtraControls) View.VISIBLE else View.GONE
}
actionPlayingQueue.setOnClickListener(this)
@ -91,18 +92,17 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
override fun onServiceConnected() {
updateSongTitle()
updatePlayPauseDrawableState()
//updateIsFavorite()
}
override fun onPlayingMetaChanged() {
updateSongTitle()
//updateIsFavorite()
}
override fun onPlayStateChanged() {
updatePlayPauseDrawableState()
}
override fun onUpdateProgressViews(progress: Int, total: Int) {
progressBar.max = total
val animator = ObjectAnimator.ofInt(progressBar, "progress", progress)
@ -125,7 +125,7 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
if (MusicPlayerRemote.isPlaying) {
miniPlayerPlayPauseButton!!.setImageResource(R.drawable.ic_pause_white_24dp)
} 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)
}
}
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 code.name.monkey.appthemehelper.ThemeStore
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.ViewUtil
import com.google.android.material.appbar.AppBarLayout
@ -44,7 +45,7 @@ abstract class AbsLibraryPagerRecyclerViewFragment<A : RecyclerView.Adapter<*>,
private fun initAdapter() {
adapter = createAdapter()
adapter!!.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
adapter?.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onChanged() {
super.onChanged()
checkIsEmpty()
@ -63,8 +64,15 @@ abstract class AbsLibraryPagerRecyclerViewFragment<A : RecyclerView.Adapter<*>,
}
private fun checkForPadding() {
val height = DensityUtil.dip2px(requireContext(), 52f)
recyclerView.setPadding(0, 0, 0, (height * 2.3).toInt())
val itemCount: Int = adapter?.itemCount ?: 0
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() {

View File

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

View File

@ -213,7 +213,7 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
override fun doInBackground(vararg params: Song): Lyrics? {
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)) {
data = MusicUtil.getLyrics(params[0])
return if (TextUtils.isEmpty(data)) {

View File

@ -151,7 +151,7 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
});
getMainActivity().setSupportActionBar(toolbar);
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));
}

View File

@ -50,8 +50,8 @@ class PlaylistsFragment : AbsLibraryPagerRecyclerViewFragment<PlaylistAdapter, L
}
override fun onDestroyView() {
super.onDestroyView()
playlistsPresenter.detachView()
super.onDestroyView()
}
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.util.ATHUtil;
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.retromusic.R;
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.WrappedAsyncTaskLoader;
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.NavigationUtil;
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 int LOADER_ID = LoaderIds.Companion.getFOLDERS_FRAGMENT();
private View coordinatorLayout, container, empty;
private View coordinatorLayout, empty;
private MaterialCardView toolbarContainer;
@ -158,7 +158,6 @@ public class FoldersFragment extends AbsMainActivityFragment implements
breadCrumbs = view.findViewById(R.id.breadCrumbs);
toolbar = view.findViewById(R.id.toolbar);
empty = view.findViewById(android.R.id.empty);
container = view.findViewById(R.id.container);
}
private void setCrumb(BreadCrumbLayout.Crumb crumb, boolean addToHistory) {
@ -232,7 +231,6 @@ public class FoldersFragment extends AbsMainActivityFragment implements
private void setUpAppbarColor() {
int primaryColor = ATHUtil.INSTANCE.resolveColor(requireContext(), R.attr.colorPrimary);
getMainActivity().setSupportActionBar(toolbar);
TintHelper.setTintAuto(container, primaryColor, true);
appBarLayout.setBackgroundColor(primaryColor);
toolbar.setBackgroundColor(RetroColorUtil.toolbarColor(getMainActivity()));
toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp);
@ -467,8 +465,9 @@ public class FoldersFragment extends AbsMainActivityFragment implements
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
container.setPadding(container.getPaddingLeft(), container.getPaddingTop(),
container.getPaddingRight(), this.appBarLayout.getTotalScrollRange() + verticalOffset);
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(),
recyclerView.getPaddingRight(), DensityUtil.dip2px(requireContext(), 52f) +
this.appBarLayout.getTotalScrollRange() + verticalOffset);
}
private void checkIsEmpty() {

View File

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

View File

@ -12,12 +12,10 @@ import android.view.animation.DecelerateInterpolator
import android.view.animation.LinearInterpolator
import android.widget.SeekBar
import androidx.core.content.ContextCompat
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.ripAlpha
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
@ -38,9 +36,10 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
}
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_blur_player_playback_controls, container, false)
}
@ -56,6 +55,7 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
}
showBonceAnimation()
}
title.isSelected = true
text.isSelected = true
}
@ -114,7 +114,7 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
text.setTextColor(lastDisabledPlaybackControlsColor)
TintHelper.setTintAuto(progressSlider, lastPlaybackControlsColor , false)
TintHelper.setTintAuto(progressSlider, lastPlaybackControlsColor, false)
volumeFragment?.setTintableColor(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.retromusic.R
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.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
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.PreferenceUtil
import kotlinx.android.synthetic.main.fragment_card_player_playback_controls.*
@ -47,8 +47,6 @@ class CardPlaybackControlsFragment : AbsPlayerControlsFragment() {
super.onViewCreated(view, savedInstanceState)
setUpMusicControllers()
setupControls()
playPauseButton.setOnClickListener {
if (MusicPlayerRemote.isPlaying) {
MusicPlayerRemote.pauseSong()
@ -57,20 +55,14 @@ class CardPlaybackControlsFragment : AbsPlayerControlsFragment() {
}
showBonceAnimation(playPauseButton)
}
}
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)
}
title.isSelected = true
text.isSelected = true
}
private fun updateSong() {
val song = MusicPlayerRemote.currentSong
songTitle.text = song.title
songText.text = song.artistName
title.text = song.title
text.text = song.artistName
}

View File

@ -57,6 +57,8 @@ class ColorPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setUpMusicControllers()
title.isSelected = true
text.isSelected = true
}
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.retromusic.R
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.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
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.PreferenceUtil
import kotlinx.android.synthetic.main.fragment_player_playback_controls.*
@ -50,6 +50,9 @@ class FitPlaybackControlsFragment : AbsPlayerControlsFragment() {
super.onViewCreated(view, savedInstanceState)
setUpMusicControllers()
title.isSelected = true
text.isSelected = true
playPauseButton.setOnClickListener {
if (MusicPlayerRemote.isPlaying) {
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.retromusic.R
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.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper.Callback
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
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.PreferenceUtil
import code.name.monkey.retromusic.util.ViewUtil
@ -48,6 +48,8 @@ class FlatPlaybackControlsFragment : AbsPlayerControlsFragment(), Callback {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setUpMusicControllers()
title.isSelected = true
text.isSelected = true
}
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.retromusic.R
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.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
import code.name.monkey.retromusic.model.Song
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.PreferenceUtil
import code.name.monkey.retromusic.util.ViewUtil
@ -281,7 +281,7 @@ class FullPlaybackControlsFragment : AbsPlayerControlsFragment(), PopupMenu.OnMe
override fun doInBackground(vararg params: Song): Boolean? {
val activity = activity
return if (activity != null) {
MusicUtil.isFavorite(getActivity()!!, params[0])
MusicUtil.isFavorite(requireActivity(), params[0])
} else {
cancel(false)
null

View File

@ -48,6 +48,8 @@ class MaterialControlsFragment : AbsPlayerControlsFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setUpMusicControllers()
title.isSelected = true
text.isSelected = true
}
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.ToolbarContentTintHelper
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.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.ViewUtil
import code.name.monkey.retromusic.views.DrawableGradient
@ -100,16 +100,6 @@ class PlayerFragment : AbsPlayerFragment() {
super.onViewCreated(view, savedInstanceState)
setUpSubFragments()
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?) {
super.onViewCreated(view, savedInstanceState)
setUpMusicControllers()
playPauseButton.setOnClickListener {
if (MusicPlayerRemote.isPlaying) {
MusicPlayerRemote.pauseSong()
@ -57,6 +56,7 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
}
showBonceAnimation(playPauseButton)
}
title.isSelected = true
}
override fun setDark(color: Int) {

View File

@ -66,14 +66,20 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment() {
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)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
) {
super.onViewCreated(view, savedInstanceState)
setUpMusicControllers()
}
override fun show() {
@ -122,13 +128,13 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment() {
}
private fun updatePlayPauseDrawableState() {
when {
MusicPlayerRemote.isPlaying -> playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp)
else -> playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp)
if (MusicPlayerRemote.isPlaying) {
playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp)
} else {
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
}
}
private fun setUpMusicControllers() {
setUpPlayPauseFab()
setUpPrevNext()
@ -137,6 +143,20 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment() {
setUpProgressSlider()
}
private fun setUpShuffleButton() {
shuffleButton.setOnClickListener {
println("shuffleButton Click")
MusicPlayerRemote.toggleShuffleMode()
}
}
private fun setUpRepeatButton() {
repeatButton.setOnClickListener {
println("repeatButton Click")
MusicPlayerRemote.cycleRepeatMode()
}
}
override fun setUpProgressSlider() {
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
@ -165,9 +185,6 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment() {
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
private fun setUpShuffleButton() {
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
}
override fun updateShuffleState() {
when (MusicPlayerRemote.shuffleMode) {
@ -176,9 +193,6 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment() {
}
}
private fun setUpRepeatButton() {
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
}
override fun updateRepeatState() {
when (MusicPlayerRemote.repeatMode) {
@ -206,4 +220,12 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment() {
super.onServiceConnected()
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.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.util.NavigationUtil
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_peak_player.*
@ -46,6 +47,10 @@ class PeakPlayerFragment : AbsPlayerFragment() {
super.onViewCreated(view, savedInstanceState)
setUpPlayerToolbar()
setUpSubFragments()
title.isSelected = true
playerImage.setOnClickListener {
NavigationUtil.goToLyrics(requireActivity())
}
}
private fun setUpSubFragments() {
@ -111,10 +116,6 @@ class PeakPlayerFragment : AbsPlayerFragment() {
}
override fun onPlayStateChanged() {
super.onPlayStateChanged()
}
override fun onServiceConnected() {
super.onServiceConnected()
updateSong()
@ -124,7 +125,4 @@ class PeakPlayerFragment : AbsPlayerFragment() {
super.onPlayingMetaChanged()
updateSong()
}
}

View File

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

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.TintHelper
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.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
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.PreferenceUtil
import kotlinx.android.synthetic.main.fragment_simple_controls_fragment.*
@ -74,7 +74,7 @@ class SimplePlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setUpMusicControllers()
title.isSelected = true
playPauseButton.setOnClickListener {
if (MusicPlayerRemote.isPlaying) {
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.ToolbarContentTintHelper
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.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import kotlinx.android.synthetic.main.fragment_simple_player.*
/**
* @author Hemanth S (h4h13).
*/
class SimplePlayerFragment : AbsPlayerFragment() {
class SimplePlayerFragment : AbsPlayerFragment() {
override fun playerToolbar(): Toolbar {
return playerToolbar
}
@ -45,7 +45,6 @@ class SimplePlayerFragment : AbsPlayerFragment() {
val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
playerAlbumCoverFragment.setCallbacks(this)
simplePlaybackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as SimplePlaybackControlsFragment
}
override fun onShow() {
@ -61,14 +60,14 @@ class SimplePlayerFragment : AbsPlayerFragment() {
}
override fun toolbarIconColor(): Int {
return ATHUtil.resolveColor(context!!, R.attr.iconColor)
return ATHUtil.resolveColor(requireContext(), R.attr.iconColor)
}
override fun onColorChanged(color: Int) {
lastColor = color
callbacks!!.onPaletteColorChanged()
callbacks?.onPaletteColorChanged()
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() {
playerToolbar.apply {
inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { activity!!.onBackPressed() }
setNavigationOnClickListener { requireActivity().onBackPressed() }
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)
songTitle.setTextColor(textColorPrimary)
songText.setTextColor(textColorPrimaryDisabled)
title.setTextColor(textColorPrimary)
text.setTextColor(textColorPrimaryDisabled)
playerSongTotalTime.setTextColor(textColorPrimary)
@ -125,8 +125,8 @@ class TinyPlayerFragment : AbsPlayerFragment(), MusicProgressViewUpdateHelper.Ca
private fun updateSong() {
val song = MusicPlayerRemote.currentSong
songTitle.text = song.title
songText.text = String.format("%s \nby - %s", song.albumName, song.artistName)
title.text = song.title
text.text = String.format("%s \nby - %s", song.albumName, song.artistName)
}
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?) {
super.onViewCreated(view, savedInstanceState)
title.isSelected = true
progressBar.setOnClickListener(PlayPauseButtonOnClickHandler())
progressBar.setOnTouchListener(MiniPlayerFragment.FlingPlayBackController(activity!!))

View File

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

View File

@ -86,6 +86,16 @@ class ThemeSettingsFragment : AbsSettingsFragment() {
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")!!
if (!VersionUtils.hasNougatMR()) {
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.request.target.Target;
import java.util.ArrayList;
import java.util.List;
import code.name.monkey.retromusic.App;
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.palette.BitmapPaletteTranscoder;
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.Song;
import code.name.monkey.retromusic.util.ArtistSignatureUtil;
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)
*/
*//*
public class ArtistGlideRequest {
public static final int DEFAULT_ANIMATION = android.R.anim.fade_in;
@ -152,4 +255,4 @@ public class ArtistGlideRequest {
.signature(createSignature(builder.artist));
}
}
}
}*/

View File

@ -51,29 +51,4 @@ abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(vi
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 code.name.monkey.retromusic.glide.artistimage.ArtistImage
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.AudioFileCoverLoader
import com.bumptech.glide.Glide
@ -30,6 +31,6 @@ class RetroMusicGlideModule : GlideModule {
override fun registerComponents(context: Context, glide: Glide) {
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
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.media.MediaMetadataRetriever
import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverUtils
import code.name.monkey.retromusic.util.ImageUtil
import code.name.monkey.retromusic.deezer.Data
import code.name.monkey.retromusic.deezer.DeezerApiService
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Priority
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader
import com.bumptech.glide.load.data.DataFetcher
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.ModelLoaderFactory
import com.bumptech.glide.load.model.stream.StreamModelLoader
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import okhttp3.OkHttpClient
import java.io.IOException
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 ArtistImageFetcher(private val context: Context,
private val deezerApiService: DeezerApiService,
private val okHttp: OkHttpClient,
private val model: ArtistImage) : DataFetcher<InputStream> {
@Volatile
class ArtistImageFetcher(
private val context: Context,
private val deezerApiService: DeezerApiService,
val model: ArtistImage,
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 call: Call<DeezerResponse>? = null
private var streamFetcher: OkHttpStreamFetcher? = null
override fun getDataClass(): Class<InputStream> {
return InputStream::class.java
override fun cleanup() {
urlFetcher?.cleanup()
}
override fun getDataSource(): DataSource {
return DataSource.LOCAL
override fun getId(): String {
return model.artistName
}
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
try {
if (!MusicUtil.isArtistNameUnknown(model.artistName) && RetroUtil.isAllowedToDownloadMetadata(context)) {
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 cancel() {
isCancelled = true
urlFetcher?.cancel()
}
override fun onResponse(call: Call<DeezerResponse>, response: Response<DeezerResponse>) {
if (isCancelled) {
callback.onDataReady(null)
return
}
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"))
}
}
override fun loadData(priority: Priority?): InputStream? {
if (!MusicUtil.isArtistNameUnknown(model.artistName) && PreferenceUtil.isAllowedToDownloadMetadata(context)) {
val artists = model.artistName.split(",")
val response = deezerApiService.getArtistImage(artists[0]).execute()
})
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 {
imageUrl.pictureXl.isNotEmpty() -> imageUrl.pictureXl
imageUrl.pictureBig.isNotEmpty() -> imageUrl.pictureBig
@ -273,61 +93,49 @@ class ArtistImageFetcher(private val context: Context,
else -> ""
}
}
}
override fun cleanup() {
if (streamFetcher != null) {
streamFetcher!!.cleanup()
}
}
class ArtistImageLoader(
val context: Context,
private val deezerApiService: DeezerApiService,
private val urlLoader: ModelLoader<GlideUrl, InputStream>
) : StreamModelLoader<ArtistImage> {
override fun cancel() {
isCancelled = true
call?.cancel()
if (streamFetcher != null) {
streamFetcher!!.cancel()
}
}
companion object {
val TAG: String = ArtistImageFetcher::class.java.simpleName
override fun getResourceFetcher(model: ArtistImage, width: Int, height: Int): DataFetcher<InputStream> {
return ArtistImageFetcher(context, deezerApiService, model, urlLoader, width, height)
}
}
class ArtistImageLoader(private val context: Context,
private val deezerApiService: DeezerApiService,
private val okhttp: OkHttpClient) : ModelLoader<ArtistImage, InputStream> {
class Factory(
val context: Context
) : 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>? {
return ModelLoader.LoadData(ObjectKey(model.artistName), ArtistImageFetcher(context, deezerApiService, okhttp, model))
init {
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 {
return true
override fun build(context: Context?, factories: GenericLoaderFactory?): ModelLoader<ArtistImage, InputStream> {
return ArtistImageLoader(context!!, deezerApiService, okHttpFactory.build(context, factories))
}
class Factory(private val context: Context) : ModelLoaderFactory<ArtistImage, InputStream> {
private val deezerApiService: DeezerApiService =
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() {}
override fun teardown() {
okHttpFactory.teardown()
}
companion object {
// 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 code.name.monkey.retromusic.R
import io.reactivex.Observable
object SearchLoader {

View File

@ -42,8 +42,8 @@ public class LrcHelper {
private static final String CHARSET = "utf-8";
//[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 TIME_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,3})]";
public static List<Lrc> parseLrcFromAssets(Context context, String fileName) {
try {
@ -127,8 +127,14 @@ public class LrcHelper {
String mil = timeMatcher.group(3);
Lrc lrc = new Lrc();
if (content != null && content.length() != 0) {
lrc.setTime(Long.parseLong(min) * 60 * 1000 + Long.parseLong(sec) * 1000
+ Long.parseLong(mil) * 10);
if(Integer.parseInt(mil)< 100){
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);
lrcs.add(lrc);
}
@ -148,4 +154,4 @@ public class LrcHelper {
}
return time + "";
}
}
}

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
import androidx.annotation.CallSuper
/**
* Created by hemanths on 16/08/17.
*/
interface Presenter<T> {
@CallSuper
fun attachView(view: T)
@CallSuper
fun detachView()
}

View File

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

View File

@ -14,14 +14,16 @@
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.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.*
import java.util.*
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
/**
@ -37,21 +39,30 @@ interface AlbumsPresenter : Presenter<AlbumsView> {
class AlbumsPresenterImpl @Inject constructor(
private val repository: Repository
) : PresenterImpl<AlbumsView>(), AlbumsPresenter {
) : PresenterImpl<AlbumsView>(), AlbumsPresenter, CoroutineScope {
private val job = Job()
private var disposable: Disposable? = null
private fun showList(albums: ArrayList<Album>) {
if (albums.isNotEmpty()) view.albums(albums) else view.showEmptyView()
}
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
override fun detachView() {
super.detachView()
disposable?.dispose()
job.cancel()
}
override fun loadAlbums() {
disposable = repository.allAlbumsFlowable
.subscribe { this.showList(it) }
launch {
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?) {
disposable += repository.artistInfoFloable(name, lang, cache)
.subscribe {
view.artistInfo(it)
view?.artistInfo(it)
}
}
@ -60,20 +60,16 @@ interface ArtistDetailsPresenter : Presenter<ArtistDetailsView> {
override fun loadArtist(artistId: Int) {
disposable += repository.getArtistByIdFlowable(artistId)
.doOnComplete {
view.complete()
}
.subscribe {
this.showArtist(it)
view?.complete()
}
.subscribe({
view?.artist(it)
}, { t -> println(t) })
}
override fun detachView() {
super.detachView()
disposable.dispose()
}
private fun showArtist(artist: Artist) {
view.artist(artist)
}
}
}

View File

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

View File

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

View File

@ -14,14 +14,16 @@
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.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.*
import java.util.*
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
/**
* @author Hemanth S (h4h13).
@ -35,20 +37,25 @@ interface GenresPresenter : Presenter<GenresView> {
class GenresPresenterImpl @Inject constructor(
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() {
disposable = repository.allGenresFlowable
.subscribe { this.showList(it) }
override fun detachView() {
super.detachView()
job.cancel()
}
private fun showList(genres: ArrayList<Genre>) {
if (genres.isNotEmpty()) {
view.genres(genres)
} else {
view.showEmptyView()
override fun loadGenres() {
launch {
when (val result = repository.allGenres()) {
is Result.Success -> withContext(Dispatchers.Main) {
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
import code.name.monkey.retromusic.R
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.Result
import code.name.monkey.retromusic.model.Home
import code.name.monkey.retromusic.mvp.BaseView
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 io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.*
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
add(disposable)
@ -40,238 +37,38 @@ interface HomeView : BaseView {
interface HomePresenter : Presenter<HomeView> {
fun loadSections()
class HomePresenterImpl @Inject constructor(
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() {
loadRecentArtists()
loadRecentAlbums()
loadTopArtists()
loadATopAlbums()
loadFavorite()
//loadHomeSection()
}
private var disposable: CompositeDisposable = CompositeDisposable()
private fun showData(sections: ArrayList<Home>) {
if (sections.isEmpty()) {
view.showEmptyView()
} else {
view.sections(sections)
launch {
val list = ArrayList<Home>()
val recentArtistResult = listOf(
repository.topArtists(),
repository.topAlbums(),
repository.recentArtists(),
repository.recentAlbums(),
repository.favoritePlaylist()
)
for (r in recentArtistResult) {
when (r) {
is Result.Success -> list.add(r.data)
}
}
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
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.*
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
/**
@ -37,20 +39,28 @@ interface PlaylistsPresenter : Presenter<PlaylistView> {
class PlaylistsPresenterImpl @Inject constructor(
private val repository: Repository
) : PresenterImpl<PlaylistView>(), PlaylistsPresenter {
) : PresenterImpl<PlaylistView>(), PlaylistsPresenter, CoroutineScope {
private var disposable: Disposable? = null
private val job = Job()
override fun playlists() {
disposable = repository.allPlaylistsFlowable
.subscribe { this.showList(it) }
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
override fun detachView() {
super.detachView()
job.cancel()
}
private fun showList(arrayList: ArrayList<Playlist>) {
if (arrayList.isEmpty()) {
view.showEmptyView()
} else {
view.playlists(arrayList)
override fun playlists() {
launch {
when (val result = repository.allPlaylists()) {
is Result.Success -> withContext(Dispatchers.Main) {
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
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.*
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
/**
* Created by hemanths on 20/08/17.
@ -35,25 +37,29 @@ interface PlaylistSongsPresenter : Presenter<PlaylistSongsView> {
class PlaylistSongsPresenterImpl @Inject constructor(
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) {
disposable = repository.getPlaylistSongsFlowable(playlist)
.subscribe {
view.songs(it)
launch {
when (val songs = repository.getPlaylistSongs(playlist)) {
is Result.Success -> withContext(Dispatchers.Main) {
view?.songs(songs.data)
}
is Result.Error -> withContext(Dispatchers.Main) {
view?.showEmptyView()
}
}
}
}
override fun 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
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.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository
import kotlinx.coroutines.*
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
/**
* Created by hemanths on 20/08/17.
*/
interface SearchView {
interface SearchView : BaseView {
fun showData(data: MutableList<Any>)
fun showEmptyView()
}
interface SearchPresenter : Presenter<SearchView> {
@ -35,18 +38,27 @@ interface SearchPresenter : Presenter<SearchView> {
class SearchPresenterImpl @Inject constructor(
private val repository: Repository
) : PresenterImpl<SearchView>(), SearchPresenter {
) : PresenterImpl<SearchView>(), SearchPresenter, CoroutineScope {
override fun attachView(view: SearchView) {
super.attachView(view)
}
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
private var job: Job = Job()
override fun detachView() {
super.detachView()
job.cancel()
}
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
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.*
import java.util.*
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
/**
* Created by hemanths on 10/08/17.
@ -33,23 +35,27 @@ interface SongView {
interface SongPresenter : Presenter<SongView> {
fun loadSongs()
class SongPresenterImpl @Inject constructor(
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() {
disposable = repository.allSongsFlowable
.subscribe({
view?.songs(it)
}, { t -> print(t) })
launch {
when (val songs = repository.allSongs()) {
is Result.Success -> withContext(Dispatchers.Main) { view?.songs(songs.data) }
is Result.Error -> view?.showEmptyView()
}
}
}
override fun detachView() {
super.detachView()
disposable?.dispose()
job.cancel();
}
}
}

View File

@ -25,6 +25,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.ThemeStore
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.model.CategoryInfo
import code.name.monkey.retromusic.util.PreferenceUtil
@ -58,7 +59,7 @@ class LibraryPreferenceDialog : PreferenceDialogFragmentCompat() {
lateinit var adapter: CategoryInfoAdapter
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>
if (savedInstanceState != null) {
@ -68,14 +69,14 @@ class LibraryPreferenceDialog : PreferenceDialogFragmentCompat() {
}
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.adapter = adapter
adapter.attachToRecyclerView(recyclerView)
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)
.customView(view = view)
.positiveButton(android.R.string.ok) {
@ -85,7 +86,7 @@ class LibraryPreferenceDialog : PreferenceDialogFragmentCompat() {
.negativeButton(android.R.string.cancel) {
dismiss()
}
.neutralButton(code.name.monkey.retromusic.R.string.reset_action) {
.neutralButton(R.string.reset_action) {
adapter.categoryInfos = PreferenceUtil.getInstance(requireContext()).defaultLibraryCategoryInfos
}
.noAutoDismiss()

View File

@ -92,7 +92,7 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP
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) {
val nowPlayingScreen = NowPlayingScreen.values()[viewPagerPosition]
if (isNowPlayingThemes(nowPlayingScreen)) {

View File

@ -15,7 +15,11 @@
package code.name.monkey.retromusic.providers
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.model.*
import code.name.monkey.retromusic.providers.interfaces.Repository
@ -27,6 +31,205 @@ import io.reactivex.schedulers.Schedulers
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(
name: String,
lang: String?,
@ -37,41 +240,6 @@ class RepositoryImpl(private val context: Context) : Repository {
.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> {
return SongLoader.getSongFlowable(context, id)
@ -91,10 +259,9 @@ class RepositoryImpl(private val context: Context) : Repository {
.observeOn(AndroidSchedulers.mainThread())
}
override fun getPlaylistSongsFlowable(playlist: Playlist): Observable<ArrayList<Song>> {
return PlaylistSongsLoader.getPlaylistSongListFlowable(context, playlist)
.subscribeOn(Schedulers.io())
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
}
@ -104,12 +271,6 @@ class RepositoryImpl(private val context: Context) : Repository {
.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>>
get() = PlaylistLoader.getFavoritePlaylistFlowable(context)
@ -180,13 +341,5 @@ class RepositoryImpl(private val context: Context) : Repository {
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
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.rest.model.LastFmArtist
import io.reactivex.Observable
@ -24,44 +25,52 @@ import io.reactivex.Observable
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 allAlbumsFlowable: Observable<ArrayList<Album>>
fun allAlbums(): ArrayList<Album>
val recentAlbumsFlowable: Observable<ArrayList<Album>>
fun recentAlbums(): ArrayList<Album>
val topAlbumsFlowable: Observable<ArrayList<Album>>
fun topAlbums(): ArrayList<Album>
val allArtistsFlowable: Observable<ArrayList<Artist>>
fun allArtists(): ArrayList<Artist>
val recentArtistsFlowable: Observable<ArrayList<Artist>>
fun recentArtists(): ArrayList<Artist>
val topArtistsFlowable: Observable<ArrayList<Artist>>
fun topArtists(): ArrayList<Artist>
val allPlaylistsFlowable: Observable<ArrayList<Playlist>>
fun allPlaylists(): ArrayList<Playlist>
val allGenresFlowable: Observable<ArrayList<Genre>>
fun allGenres(): ArrayList<Genre>
fun getSongFlowable(id: Int): Observable<Song>
fun getSong(id: Int): Song
@ -74,19 +83,13 @@ interface Repository {
fun getArtistById(artistId: Long): Artist
fun search(query: String?): MutableList<Any>
fun getPlaylistSongsFlowable(playlist: Playlist): Observable<ArrayList<Song>>
fun getPlaylistSongs(playlist: Playlist): ArrayList<Song>
fun getGenreFlowable(genreId: Int): Observable<ArrayList<Song>>
fun getGenre(genreId: Int): ArrayList<Song>
val favoritePlaylistFlowable: Observable<ArrayList<Playlist>>
val favoritePlaylist: ArrayList<Playlist>
fun artistInfoFloable(name: 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.playback.Playback;
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.RetroUtil;
@ -275,7 +274,6 @@ public class MusicService extends Service implements
}
}
};
private PackageValidator mPackageValidator;
private static String getTrackUri(@NonNull Song song) {
return MusicUtil.getSongFileUri(song.getId()).toString();
@ -341,9 +339,6 @@ public class MusicService extends Service implements
restoreState();
mPackageValidator = new PackageValidator(this, R.xml.allowed_media_browser_callers);
sendBroadcast(new Intent("code.name.monkey.retromusic.RETRO_MUSIC_SERVICE_CREATED"));
registerHeadsetEvents();

View File

@ -23,6 +23,7 @@ import android.graphics.Color
import android.graphics.drawable.Drawable
import android.widget.RemoteViews
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.MaterialValueHelper
import code.name.monkey.retromusic.R
@ -113,7 +114,7 @@ class PlayingNotificationOreo : PlayingNotification() {
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
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) {
@ -127,7 +128,7 @@ class PlayingNotificationOreo : PlayingNotification() {
}
if (!PreferenceUtil.getInstance(service).coloredNotification()) {
bgColorFinal = Color.WHITE
bgColorFinal = ATHUtil.resolveColor(service, R.attr.colorPrimary, Color.WHITE)
}
setBackgroundColor(bgColorFinal)
setNotificationContent(ColorUtil.isColorLight(bgColorFinal))
@ -139,12 +140,8 @@ class PlayingNotificationOreo : PlayingNotification() {
}
private fun setBackgroundColor(color: Int) {
notificationLayout.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) {

View File

@ -12,7 +12,7 @@
* 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.Intent
@ -20,7 +20,6 @@ import android.content.SharedPreferences
import android.graphics.Color
import android.net.Uri
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.LayoutMode
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.WhichButton
@ -58,7 +57,7 @@ object AppRater {
// Wait at least n days before opening
if (launchCount >= LAUNCHES_UNTIL_PROMPT) {
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.content.Context;
import android.content.res.Resources;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import androidx.annotation.NonNull;
@ -33,38 +31,9 @@ public class DensityUtil {
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) {
final float scale = context.getResources().getDisplayMetrics().density;
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 androidx.annotation.NonNull;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
@ -25,8 +27,6 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import androidx.annotation.NonNull;
/**
* 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) {
FileWriter writer = null;
try {
File file = new File(getLrcPath(title, artist));
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
File file = new File(getLrcPath2(title, artist));
if (!file.exists()) {
file.mkdirs();
}
writer = new FileWriter(getLrcPath(title, artist));
writer = new FileWriter(getLrcPath2(title, artist));
writer.write(lrcContext);
return file;
} catch (IOException e) {
@ -70,17 +70,46 @@ public class LyricUtil {
return file.exists();
}
@NonNull
public static File getLocalLyricFile(@NonNull String title, @NonNull String artist) {
File file = new File(getLrcPath(title, artist));
if (file.exists()) {
return file;
} else {
return new File("lyric file not exist");
}
public static boolean isLrcFile2Exist(@NonNull String title, @NonNull String artist) {
File file = new File(getLrcPath2(title, artist));
return file.exists();
}
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";
}
@ -103,10 +132,18 @@ public class LyricUtil {
@NonNull
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);
String ret = convertStreamToString(fin);
fin.close();
// Log.d("damn2",ret);
return ret;
}

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