App shortcut fixed
This commit is contained in:
parent
1425bfe612
commit
0b6f043995
181 changed files with 1616 additions and 2052 deletions
app
build.gradle
normal/release
proguard-rules.prosans/release
src/main
AndroidManifest.xml
assets
java/code/name/monkey/retromusic
appshortcuts
AppShortcutIconGenerator.javaAppShortcutIconGenerator.ktAppShortcutLauncherActivity.javaAppShortcutLauncherActivity.ktDynamicShortcutManager.javaDynamicShortcutManager.kt
shortcuttype
appwidgets/base
cast
dialogs
glide
helper
ui
activities
AboutActivity.ktAlbumDetailsActivity.ktArtistDetailActivity.ktLyricsActivity.ktPlaylistDetailActivity.ktSearchActivity.ktSettingsActivity.ktUserInfoActivity.kt
base
bugreport
tageditor
adapter/album
fragments
util
views
res/drawable
ic_access_time_white_24dp.xmlic_add_photo_white_24dp.xmlic_album_selected_white_24dp.xmlic_album_white_24dp.xmlic_albums_white_24dp.xmlic_app_shortcut_search.xmlic_artist_selected_white_24dp.xmlic_artist_white_24dp.xmlic_audiotrack_black_24dp.xmlic_audiotrack_selected_black_24dp.xmlic_bug_report_white_24dp.xmlic_card_giftcard_white_24dp.xmlic_clear_all_black_24dp.xmlic_close_white_24dp.xmlic_delete_white_24dp.xmlic_disc_full_black_24dp.xmlic_edit_white_24dp.xmlic_equalizer_white_24dp.xmlic_favorite_border_white_24dp.xmlic_favorite_white_24dp.xml
|
@ -32,8 +32,8 @@ android {
|
|||
vectorDrawables.useSupportLibrary = true
|
||||
|
||||
applicationId "code.name.monkey.retromusic"
|
||||
versionCode 263
|
||||
versionName '3.0.130'
|
||||
versionCode 272
|
||||
versionName '3.0.501'
|
||||
|
||||
multiDexEnabled true
|
||||
|
||||
|
@ -134,10 +134,6 @@ dependencies {
|
|||
implementation "androidx.legacy:legacy-preference-v14:$supportLibVersion"
|
||||
implementation "com.google.android.material:material:$supportLibVersion"
|
||||
|
||||
//For casting
|
||||
implementation 'androidx.mediarouter:mediarouter:1.0.0'
|
||||
implementation 'com.google.android.gms:play-services-cast-framework:16.1.0'
|
||||
|
||||
implementation "com.squareup.retrofit2:retrofit:2.4.0"
|
||||
implementation "com.squareup.retrofit2:converter-gson:2.4.0"
|
||||
implementation "com.squareup.retrofit2:adapter-rxjava2:2.4.0"
|
||||
|
@ -145,10 +141,13 @@ dependencies {
|
|||
implementation "com.afollestad.material-dialogs:core:$materialDialog"
|
||||
implementation "com.afollestad.material-dialogs:commons:$materialDialog"
|
||||
implementation 'com.afollestad:material-cab:0.1.12'
|
||||
|
||||
implementation 'com.github.bumptech.glide:glide:4.8.0'
|
||||
implementation 'com.github.bumptech.glide:okhttp3-integration:4.8.0'
|
||||
|
||||
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
|
||||
implementation 'io.reactivex.rxjava2:rxjava:2.1.17'
|
||||
|
||||
implementation('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.11.0@aar') {
|
||||
transitive = true
|
||||
}
|
||||
|
|
BIN
app/normal/release/app.aab
Normal file
BIN
app/normal/release/app.aab
Normal file
Binary file not shown.
11
app/proguard-rules.pro
vendored
11
app/proguard-rules.pro
vendored
|
@ -41,17 +41,6 @@
|
|||
public *;
|
||||
}
|
||||
|
||||
# ButterKnife
|
||||
-keep class butterknife.** { *; }
|
||||
-dontwarn butterknife.internal.**
|
||||
-keep class **$$ViewBinder { *; }
|
||||
-keepclasseswithmembernames class * {
|
||||
@butterknife.* <fields>;
|
||||
}
|
||||
-keepclasseswithmembernames class * {
|
||||
@butterknife.* <methods>;
|
||||
}
|
||||
|
||||
-keep class !android.support.v7.internal.view.menu.**,** {*;}
|
||||
|
||||
-dontwarn
|
||||
|
|
1
app/sans/release/output.json
Normal file
1
app/sans/release/output.json
Normal file
|
@ -0,0 +1 @@
|
|||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":268,"versionName":"3.0.330_1218","enabled":true,"outputFile":"app-sans-release.apk","fullName":"sansRelease","baseName":"sans-release"},"path":"app-sans-release.apk","properties":{}}]
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="false"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
|
@ -116,14 +116,12 @@
|
|||
<activity android:name=".ui.activities.EqualizerActivity" />
|
||||
<activity android:name=".ui.activities.ErrorHandlerActivity" />
|
||||
<activity android:name=".ui.activities.WhatsNewActivity" />
|
||||
<activity
|
||||
android:name=".cast.ExpandedCastControlsActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleInstance"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/AppTheme.ExpandedCastController" />
|
||||
<activity android:name=".ui.activities.bugreport.BugReportActivity" />
|
||||
<activity android:name=".ui.activities.LockScreenActivity" />
|
||||
<activity
|
||||
android:name=".appshortcuts.AppShortcutLauncherActivity"
|
||||
android:launchMode="singleInstance"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
||||
|
||||
<service
|
||||
android:name=".service.MusicService"
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -35,7 +35,6 @@
|
|||
<p><b><a href="https://github.com/JetradarMobile/android-snowfall" title="Android-Snowfall"> Android-Snowfall</a></b> by JetRadar</p>
|
||||
<p><b><a href="https://github.com/umano/AndroidSlidingUpPanel" title="Android Sliding Up Panel"> Android Sliding Up Panel</a></b>by The Umano Team</p>
|
||||
<p><b><a href="http://developer.android.com/tools/support-library/index.html" title="AOSP Support Libraries"> AOSP Support Libraries</a></b>by AOSP contributors</p>
|
||||
<p><b><a href="https://github.com/JakeWharton/butterknife" title="Butter Knife"> Butter Knife</a></b> by Jake Wharton</p>
|
||||
<p><b><a href="https://github.com/bumptech/glide" title="Glide"> Glide</a></b> by Sam Judd</p>
|
||||
<p><b><a href="https://github.com/square/retrofit" title="Retrofit"> Retrofit</a></b> by Square team</p>
|
||||
<p><b><a href="https://github.com/afollestad/material-cab" title="Material Contextual Action Bar"> Material Contextual Action Bar</a></b> by Aidan Michael Follestad</p>
|
||||
|
|
|
@ -1 +1 @@
|
|||
<html>
<head>
<style type="text/css">
* {
word-wrap: break-word;
}
{style-placeholder}
a {
color: #{link-color};
}
a:active {
color: #{link-color-active};
}
ul {
list-style-position: outside;
padding-left: 0;
padding-right: 0;
margin-left: 1em;
}
li {
padding-top: 8px;
}
</style>
</head>
<body>
<h3>Version 3.0.00</h3>
<ul style="line-height:150%">
<li>Converted app to kotlin</li>
<li>Now you can add plain text home screen widget</li>
<li>Good old side navigation bar for options</li>
<li>Bug report for better tracking with milestones</li>
<li>Snow fall effect can be enable from other settings(Works only one normal theme)</li>
<li>Click new music mix to play songs</li>
<li>Gradient image option for gird list</li>
<li>Clear button for playing queue</li>
<li>Folder list back button</li>
<li>New theme Fit</li>
<li>On library click on toolbar for accessing main menu
</li>
<li>On home click on toolbar for accessing search
</li>
<li>BottomSheetDialogue is now adaptable to screens, background colour and text size
consistency.
</li>
<li>Removed coloured navigation bar option to making app adapt the primary colour</li>
<li>Swipe up gesture for now playing removed, replaced with "tap to open", To achieve
transparent navigation bar for desired themes.
</li>
<li>Improved tablet UI and home screen by adding suggestions toggle banner issues.</li>
<li>Improving lyrics page</li>
</ul>
<p style="line-height:150%"><a href="https://github.com/h4h13/RetroMusicPlayer/wiki/FAQ">FAQ's</a>
</p>
<p style="line-height:150%">*If you face any UI related issues you clear app data and cache, if its
not working try to
uninstall and install again. </p>
</body>
|
||||
<html>
<head>
<style type="text/css">
* {
word-wrap: break-word;
}
{style-placeholder}
a {
color: #{link-color};
}
a:active {
color: #{link-color-active};
}
ul {
list-style-position: outside;
padding-left: 0;
padding-right: 0;
margin-left: 1em;
}
li {
padding-top: 8px;
}
</style>
</head>
<body>
<h4>v3.0.501</h4>
<h3>Highlights</h3>
<ul style="line-height=150%">
<li>Kotlin conversion from Good old Java</li>
<li>Outline style system icons</li>
<li>New Material Design principles and Guide lines</li>
</style>
<h3>Version 3.0.00</h3>
</style>
<ul style="line-height:150%">
</style>
<li>Converted app to kotlin<ul style="line-height:150%">
<li>By default theme will be dark</li>
<li>Now you can add search app shortcut in home screen</li>
<li>Last selected Lyrics options saved</li>
<li>Now you can add plain text home screen widget</li>
<li>Good old side navigation bar for options</li>
<li>Bug report for better tracking with milestones</li>
<li>Snow fall effect can be enable from other settings(Works only one normal theme)</li>
<li>Click new music mix to play songs</li>
<li>Gradient image option for gird list</li>
<li>Clear button for playing queue</li>
<li>Folder list back button</li>
<li>New theme Fit</li>
<li>On library click on toolbar for accessing main menu
</li>
<li>On home click on toolbar for accessing search
</li>
<li>BottomSheetDialogue is now adaptable to screens, background colour and text size
consistency.
</li>
<li>Removed coloured navigation bar option to making app adapt the primary colour</li>
<li>Swipe up gesture for now playing removed, replaced with "tap to open", To achieve
transparent navigation bar for desired themes.
</li>
<li>Improved tablet UI and home screen by adding suggestions toggle banner issues.</li>
<li>Improving lyrics page</li>
<li>Updated image loading libraries(might loose your current artist images)</li>
</ul>
<p>If you see entire app white or dark or black select same theme in settings to fix </p>
<p style="line-height:150%"><a href="https://github.com/h4h13/RetroMusicPlayer/wiki/FAQ">FAQ's</a>
</p>
<p style="line-height:150%">*If you face any UI related issues you clear app data and cache, if its
not working try to
uninstall and install again. </p>
</body>
|
|
@ -1,70 +0,0 @@
|
|||
package code.name.monkey.retromusic.appshortcuts;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Build;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
@RequiresApi(Build.VERSION_CODES.N_MR1)
|
||||
public final class AppShortcutIconGenerator {
|
||||
public static Icon generateThemedIcon(Context context, int iconId) {
|
||||
if (PreferenceUtil.getInstance().coloredAppShortcuts()) {
|
||||
return generateUserThemedIcon(context, iconId);
|
||||
} else {
|
||||
return generateDefaultThemedIcon(context, iconId);
|
||||
}
|
||||
}
|
||||
|
||||
private static Icon generateDefaultThemedIcon(Context context, int iconId) {
|
||||
// Return an Icon of iconId with default colors
|
||||
return generateThemedIcon(context, iconId,
|
||||
context.getColor(R.color.app_shortcut_default_foreground),
|
||||
context.getColor(R.color.app_shortcut_default_background)
|
||||
);
|
||||
}
|
||||
|
||||
private static Icon generateUserThemedIcon(Context context, int iconId) {
|
||||
// Get background color from context's theme
|
||||
final TypedValue typedColorBackground = new TypedValue();
|
||||
context.getTheme().resolveAttribute(android.R.attr.colorBackground, typedColorBackground, true);
|
||||
|
||||
// Return an Icon of iconId with those colors
|
||||
return generateThemedIcon(context, iconId,
|
||||
ThemeStore.accentColor(context),
|
||||
typedColorBackground.data
|
||||
);
|
||||
}
|
||||
|
||||
private static Icon generateThemedIcon(Context context, int iconId, int foregroundColor, int backgroundColor) {
|
||||
// Get and tint foreground and background drawables
|
||||
Drawable vectorDrawable = RetroUtil.getTintedVectorDrawable(context, iconId, foregroundColor);
|
||||
Drawable backgroundDrawable = RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_app_shortcut_background, backgroundColor);
|
||||
|
||||
// Squash the two drawables together
|
||||
LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{backgroundDrawable, vectorDrawable});
|
||||
|
||||
// Return as an Icon
|
||||
return Icon.createWithBitmap(drawableToBitmap(layerDrawable));
|
||||
}
|
||||
|
||||
private static Bitmap drawableToBitmap(Drawable drawable) {
|
||||
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||
drawable.draw(canvas);
|
||||
return bitmap;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package code.name.monkey.retromusic.appshortcuts
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.Icon
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.os.Build
|
||||
import android.util.TypedValue
|
||||
|
||||
import androidx.annotation.RequiresApi
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N_MR1)
|
||||
object AppShortcutIconGenerator {
|
||||
fun generateThemedIcon(context: Context, iconId: Int): Icon {
|
||||
return if (PreferenceUtil.getInstance().coloredAppShortcuts()) {
|
||||
generateUserThemedIcon(context, iconId)
|
||||
} else {
|
||||
generateDefaultThemedIcon(context, iconId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateDefaultThemedIcon(context: Context, iconId: Int): Icon {
|
||||
// Return an Icon of iconId with default colors
|
||||
return generateThemedIcon(context, iconId,
|
||||
context.getColor(R.color.app_shortcut_default_foreground),
|
||||
context.getColor(R.color.app_shortcut_default_background)
|
||||
)
|
||||
}
|
||||
|
||||
private fun generateUserThemedIcon(context: Context, iconId: Int): Icon {
|
||||
// Get background color from context's theme
|
||||
val typedColorBackground = TypedValue()
|
||||
context.theme.resolveAttribute(android.R.attr.colorBackground, typedColorBackground, true)
|
||||
|
||||
// Return an Icon of iconId with those colors
|
||||
return generateThemedIcon(context, iconId,
|
||||
ThemeStore.accentColor(context),
|
||||
typedColorBackground.data
|
||||
)
|
||||
}
|
||||
|
||||
private fun generateThemedIcon(context: Context, iconId: Int, foregroundColor: Int, backgroundColor: Int): Icon {
|
||||
// Get and tint foreground and background drawables
|
||||
val vectorDrawable = RetroUtil.getTintedVectorDrawable(context, iconId, foregroundColor)
|
||||
val backgroundDrawable = RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_app_shortcut_background, backgroundColor)
|
||||
|
||||
// Squash the two drawables together
|
||||
val layerDrawable = LayerDrawable(arrayOf(backgroundDrawable, vectorDrawable))
|
||||
|
||||
// Return as an Icon
|
||||
return Icon.createWithBitmap(drawableToBitmap(layerDrawable))
|
||||
}
|
||||
|
||||
private fun drawableToBitmap(drawable: Drawable): Bitmap {
|
||||
val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(bitmap)
|
||||
drawable.setBounds(0, 0, canvas.width, canvas.height)
|
||||
drawable.draw(canvas)
|
||||
return bitmap
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
package code.name.monkey.retromusic.appshortcuts;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist;
|
||||
import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist;
|
||||
import code.name.monkey.retromusic.model.smartplaylist.ShuffleAllPlaylist;
|
||||
|
||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.LastAddedShortcutType;
|
||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.ShuffleAllShortcutType;
|
||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.TopTracksShortcutType;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
|
||||
import static code.name.monkey.retromusic.Constants.*;
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
|
||||
public class AppShortcutLauncherActivity extends Activity {
|
||||
public static final String KEY_SHORTCUT_TYPE = "code.name.monkey.retromusic.appshortcuts.ShortcutType";
|
||||
|
||||
public static final int SHORTCUT_TYPE_SHUFFLE_ALL = 0;
|
||||
public static final int SHORTCUT_TYPE_TOP_TRACKS = 1;
|
||||
public static final int SHORTCUT_TYPE_LAST_ADDED = 2;
|
||||
public static final int SHORTCUT_TYPE_NONE = 3;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
int shortcutType = SHORTCUT_TYPE_NONE;
|
||||
|
||||
// Set shortcutType from the intent extras
|
||||
Bundle extras = getIntent().getExtras();
|
||||
if (extras != null) {
|
||||
//noinspection WrongConstant
|
||||
shortcutType = extras.getInt(KEY_SHORTCUT_TYPE, SHORTCUT_TYPE_NONE);
|
||||
}
|
||||
|
||||
switch (shortcutType) {
|
||||
case SHORTCUT_TYPE_SHUFFLE_ALL:
|
||||
startServiceWithPlaylist(MusicService.SHUFFLE_MODE_SHUFFLE,
|
||||
new ShuffleAllPlaylist(getApplicationContext()));
|
||||
DynamicShortcutManager.reportShortcutUsed(this, ShuffleAllShortcutType.getId());
|
||||
break;
|
||||
case SHORTCUT_TYPE_TOP_TRACKS:
|
||||
startServiceWithPlaylist(MusicService.SHUFFLE_MODE_NONE,
|
||||
new MyTopTracksPlaylist(getApplicationContext()));
|
||||
DynamicShortcutManager.reportShortcutUsed(this, TopTracksShortcutType.getId());
|
||||
break;
|
||||
case SHORTCUT_TYPE_LAST_ADDED:
|
||||
startServiceWithPlaylist(MusicService.SHUFFLE_MODE_NONE,
|
||||
new LastAddedPlaylist(getApplicationContext()));
|
||||
DynamicShortcutManager.reportShortcutUsed(this, LastAddedShortcutType.getId());
|
||||
break;
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
private void startServiceWithPlaylist(int shuffleMode, Playlist playlist) {
|
||||
Intent intent = new Intent(this, MusicService.class);
|
||||
intent.setAction(ACTION_PLAY_PLAYLIST);
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(INTENT_EXTRA_PLAYLIST, playlist);
|
||||
bundle.putInt(INTENT_EXTRA_SHUFFLE_MODE, shuffleMode);
|
||||
|
||||
intent.putExtras(bundle);
|
||||
|
||||
startService(intent);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package code.name.monkey.retromusic.appshortcuts
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import code.name.monkey.retromusic.Constants.ACTION_PLAY_PLAYLIST
|
||||
import code.name.monkey.retromusic.Constants.INTENT_EXTRA_PLAYLIST
|
||||
import code.name.monkey.retromusic.Constants.INTENT_EXTRA_SHUFFLE_MODE
|
||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.LastAddedShortcutType
|
||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.SearchShortCutType
|
||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.ShuffleAllShortcutType
|
||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.TopTracksShortcutType
|
||||
import code.name.monkey.retromusic.model.Playlist
|
||||
import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist
|
||||
import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist
|
||||
import code.name.monkey.retromusic.model.smartplaylist.ShuffleAllPlaylist
|
||||
import code.name.monkey.retromusic.service.MusicService
|
||||
import code.name.monkey.retromusic.ui.activities.SearchActivity
|
||||
|
||||
|
||||
class AppShortcutLauncherActivity : Activity() {
|
||||
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
var shortcutType = SHORTCUT_TYPE_NONE
|
||||
|
||||
// Set shortcutType from the intent extras
|
||||
val extras = intent.extras
|
||||
if (extras != null) {
|
||||
shortcutType = extras.getInt(KEY_SHORTCUT_TYPE, SHORTCUT_TYPE_NONE)
|
||||
}
|
||||
|
||||
when (shortcutType) {
|
||||
SHORTCUT_TYPE_SHUFFLE_ALL -> {
|
||||
startServiceWithPlaylist(MusicService.SHUFFLE_MODE_SHUFFLE,
|
||||
ShuffleAllPlaylist(applicationContext))
|
||||
DynamicShortcutManager.reportShortcutUsed(this, ShuffleAllShortcutType.id)
|
||||
}
|
||||
SHORTCUT_TYPE_TOP_TRACKS -> {
|
||||
startServiceWithPlaylist(MusicService.SHUFFLE_MODE_NONE,
|
||||
MyTopTracksPlaylist(applicationContext))
|
||||
DynamicShortcutManager.reportShortcutUsed(this, TopTracksShortcutType.id)
|
||||
}
|
||||
SHORTCUT_TYPE_LAST_ADDED -> {
|
||||
startServiceWithPlaylist(MusicService.SHUFFLE_MODE_NONE,
|
||||
LastAddedPlaylist(applicationContext))
|
||||
DynamicShortcutManager.reportShortcutUsed(this, LastAddedShortcutType.id)
|
||||
}
|
||||
SHORTCUT_TYPE_SEARCH -> {
|
||||
startActivity(Intent(this, SearchActivity::class.java))
|
||||
DynamicShortcutManager.reportShortcutUsed(this, SearchShortCutType.id)
|
||||
}
|
||||
}
|
||||
finish()
|
||||
}
|
||||
|
||||
private fun startServiceWithPlaylist(shuffleMode: Int, playlist: Playlist) {
|
||||
val intent = Intent(this, MusicService::class.java)
|
||||
intent.action = ACTION_PLAY_PLAYLIST
|
||||
|
||||
val bundle = Bundle()
|
||||
bundle.putParcelable(INTENT_EXTRA_PLAYLIST, playlist)
|
||||
bundle.putInt(INTENT_EXTRA_SHUFFLE_MODE, shuffleMode)
|
||||
|
||||
intent.putExtras(bundle)
|
||||
|
||||
startService(intent)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KEY_SHORTCUT_TYPE = "code.name.monkey.retromusic.appshortcuts.ShortcutType"
|
||||
const val SHORTCUT_TYPE_SHUFFLE_ALL = 0
|
||||
const val SHORTCUT_TYPE_TOP_TRACKS = 1
|
||||
const val SHORTCUT_TYPE_LAST_ADDED = 2
|
||||
const val SHORTCUT_TYPE_SEARCH = 3
|
||||
const val SHORTCUT_TYPE_NONE = 4
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
package code.name.monkey.retromusic.appshortcuts;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.pm.ShortcutManager;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Build;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.LastAddedShortcutType;
|
||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.ShuffleAllShortcutType;
|
||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.TopTracksShortcutType;
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
public class DynamicShortcutManager {
|
||||
|
||||
private Context context;
|
||||
private ShortcutManager shortcutManager;
|
||||
|
||||
public DynamicShortcutManager(Context context) {
|
||||
this.context = context;
|
||||
shortcutManager = this.context.getSystemService(ShortcutManager.class);
|
||||
}
|
||||
|
||||
public static ShortcutInfo createShortcut(Context context, String id, String shortLabel, String longLabel, Icon icon, Intent intent) {
|
||||
return new ShortcutInfo.Builder(context, id)
|
||||
.setShortLabel(shortLabel)
|
||||
.setLongLabel(longLabel)
|
||||
.setIcon(icon)
|
||||
.setIntent(intent)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static void reportShortcutUsed(Context context, String shortcutId) {
|
||||
context.getSystemService(ShortcutManager.class).reportShortcutUsed(shortcutId);
|
||||
}
|
||||
|
||||
public void initDynamicShortcuts() {
|
||||
if (shortcutManager.getDynamicShortcuts().size() == 0) {
|
||||
shortcutManager.setDynamicShortcuts(getDefaultShortcuts());
|
||||
}
|
||||
}
|
||||
|
||||
public void updateDynamicShortcuts() {
|
||||
shortcutManager.updateShortcuts(getDefaultShortcuts());
|
||||
}
|
||||
|
||||
public List<ShortcutInfo> getDefaultShortcuts() {
|
||||
return (Arrays.asList(
|
||||
new ShuffleAllShortcutType(context).getShortcutInfo(),
|
||||
new TopTracksShortcutType(context).getShortcutInfo(),
|
||||
new LastAddedShortcutType(context).getShortcutInfo()
|
||||
));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package code.name.monkey.retromusic.appshortcuts
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.content.pm.ShortcutManager
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
|
||||
import java.util.Arrays
|
||||
|
||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.LastAddedShortcutType
|
||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.SearchShortCutType
|
||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.ShuffleAllShortcutType
|
||||
import code.name.monkey.retromusic.appshortcuts.shortcuttype.TopTracksShortcutType
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
class DynamicShortcutManager(private val context: Context) {
|
||||
private val shortcutManager: ShortcutManager = this.context.getSystemService(ShortcutManager::class.java)
|
||||
|
||||
private val defaultShortcuts: List<ShortcutInfo>
|
||||
get() = Arrays.asList(
|
||||
SearchShortCutType(context).shortcutInfo,
|
||||
ShuffleAllShortcutType(context).shortcutInfo,
|
||||
TopTracksShortcutType(context).shortcutInfo,
|
||||
LastAddedShortcutType(context).shortcutInfo
|
||||
|
||||
)
|
||||
|
||||
fun initDynamicShortcuts() {
|
||||
//if (shortcutManager.dynamicShortcuts.size == 0) {
|
||||
shortcutManager.dynamicShortcuts = defaultShortcuts
|
||||
//}
|
||||
}
|
||||
|
||||
fun updateDynamicShortcuts() {
|
||||
shortcutManager.updateShortcuts(defaultShortcuts)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun createShortcut(context: Context, id: String, shortLabel: String, longLabel: String, icon: Icon, intent: Intent): ShortcutInfo {
|
||||
return ShortcutInfo.Builder(context, id)
|
||||
.setShortLabel(shortLabel)
|
||||
.setLongLabel(longLabel)
|
||||
.setIcon(icon)
|
||||
.setIntent(intent)
|
||||
.build()
|
||||
}
|
||||
|
||||
fun reportShortcutUsed(context: Context, shortcutId: String) {
|
||||
context.getSystemService(ShortcutManager::class.java).reportShortcutUsed(shortcutId)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package code.name.monkey.retromusic.appshortcuts.shortcuttype;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity;
|
||||
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
public abstract class BaseShortcutType {
|
||||
|
||||
static final String ID_PREFIX = "code.name.monkey.retromusic.appshortcuts.id.";
|
||||
|
||||
Context context;
|
||||
|
||||
public BaseShortcutType(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
static public String getId() {
|
||||
return ID_PREFIX + "invalid";
|
||||
}
|
||||
|
||||
abstract ShortcutInfo getShortcutInfo();
|
||||
|
||||
/**
|
||||
* Creates an Intent that will launch MainActivtiy and immediately play {@param songs} in either shuffle or normal mode
|
||||
*
|
||||
* @param shortcutType Describes the type of shortcut to create (ShuffleAll, TopTracks, custom playlist, etc.)
|
||||
* @return
|
||||
*/
|
||||
Intent getPlaySongsIntent(int shortcutType) {
|
||||
Intent intent = new Intent(context, AppShortcutLauncherActivity.class);
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
|
||||
Bundle b = new Bundle();
|
||||
b.putInt(AppShortcutLauncherActivity.KEY_SHORTCUT_TYPE, shortcutType);
|
||||
|
||||
intent.putExtras(b);
|
||||
|
||||
return intent;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package code.name.monkey.retromusic.appshortcuts.shortcuttype
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
|
||||
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
abstract class BaseShortcutType(internal var context: Context) {
|
||||
|
||||
internal abstract val shortcutInfo: ShortcutInfo
|
||||
|
||||
/**
|
||||
* Creates an Intent that will launch MainActivtiy and immediately play {@param songs} in either shuffle or normal mode
|
||||
*
|
||||
* @param shortcutType Describes the type of shortcut to create (ShuffleAll, TopTracks, custom playlist, etc.)
|
||||
* @return
|
||||
*/
|
||||
internal fun getPlaySongsIntent(shortcutType: Int): Intent {
|
||||
val intent = Intent(context, AppShortcutLauncherActivity::class.java)
|
||||
intent.action = Intent.ACTION_VIEW
|
||||
val b = Bundle()
|
||||
b.putInt(AppShortcutLauncherActivity.KEY_SHORTCUT_TYPE, shortcutType)
|
||||
intent.putExtras(b)
|
||||
return intent
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal const val ID_PREFIX = "code.name.monkey.retromusic.appshortcuts.id."
|
||||
val id: String
|
||||
get() = ID_PREFIX + "invalid"
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package code.name.monkey.retromusic.appshortcuts.shortcuttype;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.Build;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator;
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity;
|
||||
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
public final class LastAddedShortcutType extends BaseShortcutType {
|
||||
public LastAddedShortcutType(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public static String getId() {
|
||||
return ID_PREFIX + "last_added";
|
||||
}
|
||||
|
||||
public ShortcutInfo getShortcutInfo() {
|
||||
return new ShortcutInfo.Builder(context, getId())
|
||||
.setShortLabel(context.getString(R.string.app_shortcut_last_added_short))
|
||||
.setLongLabel(context.getString(R.string.app_shortcut_last_added_long))
|
||||
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_last_added))
|
||||
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_LAST_ADDED))
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package code.name.monkey.retromusic.appshortcuts.shortcuttype
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.os.Build
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
class LastAddedShortcutType(context: Context) : BaseShortcutType(context) {
|
||||
|
||||
override val shortcutInfo: ShortcutInfo
|
||||
get() = ShortcutInfo.Builder(context, id)
|
||||
.setShortLabel(context.getString(R.string.app_shortcut_last_added_short))
|
||||
.setLongLabel(context.getString(R.string.app_shortcut_last_added_long))
|
||||
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_last_added))
|
||||
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_LAST_ADDED))
|
||||
.build()
|
||||
|
||||
companion object {
|
||||
|
||||
val id: String
|
||||
get() = BaseShortcutType.ID_PREFIX + "last_added"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package code.name.monkey.retromusic.appshortcuts.shortcuttype
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.os.Build
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
class SearchShortCutType(context: Context) : BaseShortcutType(context) {
|
||||
companion object {
|
||||
|
||||
val id: String
|
||||
get() = BaseShortcutType.ID_PREFIX + "search"
|
||||
}
|
||||
|
||||
override val shortcutInfo: ShortcutInfo
|
||||
get() = ShortcutInfo.Builder(context, id)
|
||||
.setShortLabel(context.getString(R.string.action_search))
|
||||
.setLongLabel(context.getString(R.string.search_hint))
|
||||
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_search))
|
||||
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_SEARCH))
|
||||
.build()
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package code.name.monkey.retromusic.appshortcuts.shortcuttype;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.Build;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator;
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
public final class ShuffleAllShortcutType extends BaseShortcutType {
|
||||
public ShuffleAllShortcutType(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public static String getId() {
|
||||
return ID_PREFIX + "shuffle_all";
|
||||
}
|
||||
|
||||
public ShortcutInfo getShortcutInfo() {
|
||||
return new ShortcutInfo.Builder(context, getId())
|
||||
.setShortLabel(context.getString(R.string.app_shortcut_shuffle_all_short))
|
||||
.setLongLabel(context.getString(R.string.app_shortcut_shuffle_all_long))
|
||||
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_shuffle_all))
|
||||
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_SHUFFLE_ALL))
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package code.name.monkey.retromusic.appshortcuts.shortcuttype
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.os.Build
|
||||
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
|
||||
import java.security.AccessController.getContext
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
class ShuffleAllShortcutType(context: Context) : BaseShortcutType(context) {
|
||||
|
||||
override val shortcutInfo: ShortcutInfo
|
||||
get() = ShortcutInfo.Builder(context, id)
|
||||
.setShortLabel(context.getString(R.string.app_shortcut_shuffle_all_short))
|
||||
.setLongLabel(context.getString(R.string.app_shortcut_shuffle_all_long))
|
||||
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_shuffle_all))
|
||||
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_SHUFFLE_ALL))
|
||||
.build()
|
||||
|
||||
companion object {
|
||||
|
||||
val id: String
|
||||
get() = BaseShortcutType.ID_PREFIX + "shuffle_all"
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package code.name.monkey.retromusic.appshortcuts.shortcuttype;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.Build;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator;
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author Adrian Campos
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
public final class TopTracksShortcutType extends BaseShortcutType {
|
||||
public TopTracksShortcutType(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public static String getId() {
|
||||
return ID_PREFIX + "top_tracks";
|
||||
}
|
||||
|
||||
public ShortcutInfo getShortcutInfo() {
|
||||
return new ShortcutInfo.Builder(context, getId())
|
||||
.setShortLabel(context.getString(R.string.app_shortcut_top_tracks_short))
|
||||
.setLongLabel(context.getString(R.string.app_shortcut_top_tracks_long))
|
||||
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_top_tracks))
|
||||
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_TOP_TRACKS))
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package code.name.monkey.retromusic.appshortcuts.shortcuttype
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.os.Build
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutIconGenerator
|
||||
import code.name.monkey.retromusic.appshortcuts.AppShortcutLauncherActivity
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
class TopTracksShortcutType(context: Context) : BaseShortcutType(context) {
|
||||
|
||||
override val shortcutInfo: ShortcutInfo
|
||||
get() = ShortcutInfo.Builder(context, id)
|
||||
.setShortLabel(context.getString(R.string.app_shortcut_top_tracks_short))
|
||||
.setLongLabel(context.getString(R.string.app_shortcut_top_tracks_long))
|
||||
.setIcon(AppShortcutIconGenerator.generateThemedIcon(context, R.drawable.ic_app_shortcut_top_tracks))
|
||||
.setIntent(getPlaySongsIntent(AppShortcutLauncherActivity.SHORTCUT_TYPE_TOP_TRACKS))
|
||||
.build()
|
||||
|
||||
companion object {
|
||||
|
||||
val id: String
|
||||
get() = BaseShortcutType.ID_PREFIX + "top_tracks"
|
||||
}
|
||||
}
|
|
@ -136,16 +136,7 @@ abstract class BaseAppWidget : AppWidgetProvider() {
|
|||
}
|
||||
|
||||
protected fun composeRoundedRectPath(rect: RectF, tl: Float, tr: Float, bl: Float, br: Float): Path {
|
||||
var tlf = tl
|
||||
var trf = tr
|
||||
var blf = bl
|
||||
var brf = br
|
||||
val path = Path()
|
||||
tlf = if (tl < 0) 0F else tl
|
||||
trf = if (tr < 0) 0f else tr
|
||||
blf = if (bl < 0) 0f else bl
|
||||
brf = if (br < 0) 0f else br
|
||||
|
||||
path.moveTo(rect.left + tl, rect.top)
|
||||
path.lineTo(rect.right - tr, rect.top)
|
||||
path.quadTo(rect.right, rect.top, rect.right, rect.top + tr)
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
package code.name.monkey.retromusic.cast;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import com.google.android.gms.cast.MediaInfo;
|
||||
import com.google.android.gms.cast.MediaLoadOptions;
|
||||
import com.google.android.gms.cast.MediaMetadata;
|
||||
import com.google.android.gms.cast.framework.CastSession;
|
||||
import com.google.android.gms.cast.framework.media.RemoteMediaClient;
|
||||
import com.google.android.gms.common.images.WebImage;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import code.name.monkey.retromusic.Constants;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
import static code.name.monkey.retromusic.Constants.CAST_SERVER_PORT;
|
||||
|
||||
public class CastHelper {
|
||||
|
||||
public static void startCasting(CastSession castSession, Song song) {
|
||||
|
||||
String ipAddress = RetroUtil.getIPAddress(true);
|
||||
URL baseUrl;
|
||||
try {
|
||||
baseUrl = new URL("https", ipAddress,CAST_SERVER_PORT, "");
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
String songUrl = baseUrl.toString() + "/song?id=" + song.getId();
|
||||
String albumArtUrl = baseUrl.toString() + "/albumart?id=" + song.getAlbumId();
|
||||
|
||||
|
||||
MediaMetadata musicMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MUSIC_TRACK);
|
||||
|
||||
musicMetadata.putString(MediaMetadata.KEY_TITLE, song.getTitle());
|
||||
musicMetadata.putString(MediaMetadata.KEY_ARTIST, song.getArtistName());
|
||||
musicMetadata.putString(MediaMetadata.KEY_ALBUM_TITLE, song.getAlbumName());
|
||||
musicMetadata.putInt(MediaMetadata.KEY_TRACK_NUMBER, song.getTrackNumber());
|
||||
musicMetadata.addImage(new WebImage(Uri.parse(albumArtUrl)));
|
||||
|
||||
try {
|
||||
MediaInfo mediaInfo = new MediaInfo.Builder(songUrl)
|
||||
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
|
||||
.setContentType("audio/mpeg")
|
||||
.setMetadata(musicMetadata)
|
||||
.setStreamDuration(song.getDuration())
|
||||
.build();
|
||||
RemoteMediaClient remoteMediaClient = castSession.getRemoteMediaClient();
|
||||
remoteMediaClient.load(mediaInfo, new MediaLoadOptions.Builder()
|
||||
.build());
|
||||
//remoteMediaClient.load(mediaInfo, true, 0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
package code.name.monkey.retromusic.cast;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.google.android.gms.cast.framework.CastOptions;
|
||||
import com.google.android.gms.cast.framework.OptionsProvider;
|
||||
import com.google.android.gms.cast.framework.SessionProvider;
|
||||
import com.google.android.gms.cast.framework.media.CastMediaOptions;
|
||||
import com.google.android.gms.cast.framework.media.MediaIntentReceiver;
|
||||
import com.google.android.gms.cast.framework.media.NotificationOptions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
public class CastOptionsProvider implements OptionsProvider {
|
||||
@Override
|
||||
public CastOptions getCastOptions(Context context) {
|
||||
List<String> buttonActions = new ArrayList<>();
|
||||
buttonActions.add(MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK);
|
||||
buttonActions.add(MediaIntentReceiver.ACTION_STOP_CASTING);
|
||||
int[] compatButtonActionsIndicies = new int[]{ 0, 1 };
|
||||
|
||||
NotificationOptions notificationOptions = new NotificationOptions.Builder()
|
||||
.setActions(buttonActions, compatButtonActionsIndicies)
|
||||
.setTargetActivityClassName(ExpandedCastControlsActivity.class.getName())
|
||||
.build();
|
||||
|
||||
CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
|
||||
.setNotificationOptions(notificationOptions)
|
||||
.setExpandedControllerActivityClassName(ExpandedCastControlsActivity.class.getName())
|
||||
.build();
|
||||
|
||||
return new CastOptions.Builder()
|
||||
.setReceiverApplicationId(context.getString(R.string.cast_app_id))
|
||||
.setCastMediaOptions(mediaOptions)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SessionProvider> getAdditionalSessionProviders(Context context) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package code.name.monkey.retromusic.cast;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.View;
|
||||
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory;
|
||||
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
|
||||
public class ExpandedCastControlsActivity extends ExpandedControllerActivity {
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
getMenuInflater().inflate(R.menu.menu_expanded_controller, menu);
|
||||
CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
package code.name.monkey.retromusic.cast;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
|
||||
import code.name.monkey.retromusic.Constants;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
import fi.iki.elonen.NanoHTTPD;
|
||||
|
||||
import static code.name.monkey.retromusic.Constants.CAST_SERVER_PORT;
|
||||
|
||||
public class WebServer extends NanoHTTPD {
|
||||
|
||||
private Context context;
|
||||
private Uri songUri, albumArtUri;
|
||||
|
||||
public WebServer(Context context) {
|
||||
super(CAST_SERVER_PORT);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response serve(String uri, Method method,
|
||||
Map<String, String> header,
|
||||
Map<String, String> parameters,
|
||||
Map<String, String> files) {
|
||||
if (uri.contains("albumart")) {
|
||||
//serve the picture
|
||||
|
||||
String albumId = parameters.get("id");
|
||||
this.albumArtUri = RetroUtil.getAlbumArtUri(Long.parseLong(albumId));
|
||||
|
||||
if (albumArtUri != null) {
|
||||
String mediasend = "image/jpg";
|
||||
InputStream fisAlbumArt = null;
|
||||
try {
|
||||
fisAlbumArt = context.getContentResolver().openInputStream(albumArtUri);
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Response.Status st = Response.Status.OK;
|
||||
|
||||
//serve the song
|
||||
return newChunkedResponse(st, mediasend, fisAlbumArt);
|
||||
}
|
||||
|
||||
} else if (uri.contains("song")) {
|
||||
|
||||
String songId = parameters.get("id");
|
||||
this.songUri = RetroUtil.getSongUri(context, Long.parseLong(songId));
|
||||
|
||||
if (songUri != null) {
|
||||
String mediasend = "audio/mp3";
|
||||
FileInputStream fisSong = null;
|
||||
File song = new File(songUri.getPath());
|
||||
try {
|
||||
fisSong = new FileInputStream(song);
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Response.Status st = Response.Status.OK;
|
||||
|
||||
//serve the song
|
||||
return newFixedLengthResponse(st, mediasend, fisSong, song.length());
|
||||
}
|
||||
|
||||
}
|
||||
return newFixedLengthResponse("Error");
|
||||
}
|
||||
|
||||
}
|
|
@ -32,7 +32,7 @@ class AddToPlaylistDialog : RoundedBottomSheetDialogFragment() {
|
|||
|
||||
actionAddPlaylist.setOnClickListener {
|
||||
val songs = arguments!!.getParcelableArrayList<Song>("songs")
|
||||
CreatePlaylistDialog.create(songs).show(activity!!.supportFragmentManager, "ADD_TO_PLAYLIST")
|
||||
CreatePlaylistDialog.create(songs!!).show(activity!!.supportFragmentManager, "ADD_TO_PLAYLIST")
|
||||
dismiss()
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ class DeleteSongsDialog : RoundedBottomSheetDialogFragment() {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
title.setTextColor(ThemeStore.textColorPrimary(context!!))
|
||||
MaterialUtil.setTint(actionDelete, true)
|
||||
MaterialUtil.setTint(actionCancel, false)
|
||||
MaterialUtil.setTint(actionDelete)
|
||||
MaterialUtil.setTint(actionCancel)
|
||||
|
||||
//noinspection unchecked,ConstantConditions
|
||||
val songs = arguments!!.getParcelableArrayList<Song>("songs")
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package code.name.monkey.retromusic.dialogs
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
|
@ -57,7 +58,11 @@ class OptionsSheetDialogFragment : RoundedBottomSheetDialogFragment(), View.OnCl
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
actionBuyPro.visibility = if (!App.isProVersion) View.VISIBLE else View.GONE
|
||||
actionBuyPro.let {
|
||||
it.visibility = if (!App.isProVersion) View.VISIBLE else View.GONE
|
||||
it.iconTint = ColorStateList.valueOf(ThemeStore.accentColor(it.context))
|
||||
it.setTextColor(ColorStateList.valueOf(ThemeStore.accentColor(it.context)))
|
||||
}
|
||||
text!!.setTextColor(ThemeStore.textColorSecondary(context!!))
|
||||
titleWelcome!!.setTextColor(ThemeStore.textColorPrimary(context!!))
|
||||
titleWelcome!!.text = String.format("%s %s!", timeOfTheDay, PreferenceUtil.getInstance().userName)
|
||||
|
|
|
@ -85,8 +85,8 @@ class BlurTransformation : BitmapTransformation {
|
|||
return StackBlur.blur(out, blurRadius)
|
||||
}
|
||||
|
||||
override fun equals(o: Any?): Boolean {
|
||||
return o is BlurTransformation
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return other is BlurTransformation
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
|
@ -138,7 +138,7 @@ class BlurTransformation : BitmapTransformation {
|
|||
|
||||
companion object {
|
||||
|
||||
val DEFAULT_BLUR_RADIUS = 5f
|
||||
private val ID = "com.poupa.vinylmusicplayer.glide.BlurTransformation"
|
||||
const val DEFAULT_BLUR_RADIUS = 5f
|
||||
private const val ID = "code.name.monkey.retromusic.glide.BlurTransformation"
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package code.name.monkey.retromusic.glide;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.GenericTransitionOptions;
|
||||
import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.RequestBuilder;
|
||||
|
@ -8,11 +10,11 @@ import com.bumptech.glide.annotation.GlideOption;
|
|||
import com.bumptech.glide.annotation.GlideType;
|
||||
import com.bumptech.glide.load.Key;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.bumptech.glide.signature.MediaStoreSignature;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import code.name.monkey.retromusic.App;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.artistimage.ArtistImage;
|
||||
|
@ -34,6 +36,7 @@ public final class RetroGlideExtension {
|
|||
public static void asBitmapPalette(RequestBuilder<BitmapPaletteWrapper> requestBuilder) {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@GlideOption
|
||||
public static RequestOptions artistOptions(@NonNull RequestOptions requestOptions, Artist artist) {
|
||||
return requestOptions
|
||||
|
@ -46,11 +49,12 @@ public final class RetroGlideExtension {
|
|||
}
|
||||
|
||||
@GlideOption
|
||||
@NonNull
|
||||
public static RequestOptions songOptions(@NonNull RequestOptions requestOptions, Song song) {
|
||||
return requestOptions
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.error(R.drawable.default_album_art)
|
||||
.placeholder(R.drawable.default_album_art)
|
||||
//.placeholder(R.drawable.default_album_art)
|
||||
.signature(createSignature(song));
|
||||
}
|
||||
|
||||
|
@ -93,4 +97,5 @@ public final class RetroGlideExtension {
|
|||
public static <TranscodeType> GenericTransitionOptions<TranscodeType> getDefaultTransition() {
|
||||
return new GenericTransitionOptions<TranscodeType>().transition(android.R.anim.fade_in);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.artistimage
|
||||
|
||||
|
||||
class ArtistImage(val artistName: String, val skipOkHttpCache: Boolean)
|
|
@ -1,98 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.artistimage
|
||||
|
||||
import android.content.Context
|
||||
import android.text.TextUtils
|
||||
import code.name.monkey.retromusic.rest.LastFMRestClient
|
||||
import code.name.monkey.retromusic.rest.model.LastFmArtist
|
||||
import code.name.monkey.retromusic.util.LastFMUtil
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.bumptech.glide.Priority
|
||||
import com.bumptech.glide.integration.okhttp3.OkHttpStreamFetcher
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.data.DataFetcher
|
||||
import com.bumptech.glide.load.model.GlideUrl
|
||||
|
||||
import okhttp3.OkHttpClient
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
import java.io.InputStream
|
||||
|
||||
|
||||
class ArtistImageFetcher(private val context: Context, private val lastFMRestClient: LastFMRestClient, private val okHttp: OkHttpClient, private val model: ArtistImage, width: Int, height: Int) : DataFetcher<InputStream> {
|
||||
@Volatile
|
||||
private var isCancelled: Boolean = false
|
||||
private var call: Call<LastFmArtist>? = null
|
||||
private var streamFetcher: OkHttpStreamFetcher? = null
|
||||
|
||||
|
||||
override fun getDataClass(): Class<InputStream> {
|
||||
return InputStream::class.java
|
||||
}
|
||||
|
||||
|
||||
override fun getDataSource(): DataSource {
|
||||
return DataSource.REMOTE
|
||||
}
|
||||
|
||||
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
|
||||
try {
|
||||
if (!MusicUtil.isArtistNameUnknown(model.artistName) && RetroUtil.isAllowedToDownloadMetadata(context)) {
|
||||
call = lastFMRestClient.apiService.getArtistInfo(model.artistName, null, if (model.skipOkHttpCache) "no-cache" else null)
|
||||
call!!.enqueue(object : Callback<LastFmArtist> {
|
||||
override fun onResponse(call: Call<LastFmArtist>, response: Response<LastFmArtist>) {
|
||||
if (isCancelled) {
|
||||
callback.onDataReady(null)
|
||||
return
|
||||
}
|
||||
|
||||
val lastFmArtist = response.body()
|
||||
if (lastFmArtist == null || lastFmArtist.artist == null || lastFmArtist.artist.image == null) {
|
||||
callback.onLoadFailed(Exception("No artist image url found"))
|
||||
return
|
||||
}
|
||||
|
||||
val url = LastFMUtil.getLargestArtistImageUrl(lastFmArtist.artist.image)
|
||||
if (TextUtils.isEmpty(url) || TextUtils.isEmpty(url.trim { it <= ' ' })) {
|
||||
callback.onLoadFailed(Exception("No artist image url found"))
|
||||
return
|
||||
}
|
||||
|
||||
streamFetcher = OkHttpStreamFetcher(okHttp, GlideUrl(url))
|
||||
streamFetcher!!.loadData(priority, callback)
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<LastFmArtist>, throwable: Throwable) {
|
||||
callback.onLoadFailed(Exception(throwable))
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
callback.onLoadFailed(e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun cleanup() {
|
||||
if (streamFetcher != null) {
|
||||
streamFetcher!!.cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
isCancelled = true
|
||||
if (call != null) {
|
||||
call!!.cancel()
|
||||
}
|
||||
if (streamFetcher != null) {
|
||||
streamFetcher!!.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TAG: String = ArtistImageFetcher::class.java.simpleName
|
||||
}
|
||||
}
|
|
@ -1,17 +1,109 @@
|
|||
package code.name.monkey.retromusic.glide.artistimage
|
||||
|
||||
import android.content.Context
|
||||
import android.text.TextUtils
|
||||
import code.name.monkey.retromusic.rest.LastFMRestClient
|
||||
import code.name.monkey.retromusic.rest.model.LastFmArtist
|
||||
import code.name.monkey.retromusic.util.LastFMUtil
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.bumptech.glide.Priority
|
||||
import com.bumptech.glide.integration.okhttp3.OkHttpStreamFetcher
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.Options
|
||||
import com.bumptech.glide.load.data.DataFetcher
|
||||
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.MultiModelLoaderFactory
|
||||
import com.bumptech.glide.signature.ObjectKey
|
||||
import okhttp3.OkHttpClient
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import java.io.InputStream
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
class ArtistImage(val artistName: String, val skipOkHttpCache: Boolean)
|
||||
|
||||
class ArtistImageFetcher(private val context: Context, private val lastFMRestClient: LastFMRestClient, private val okHttp: OkHttpClient, private val model: ArtistImage, width: Int, height: Int) : DataFetcher<InputStream> {
|
||||
@Volatile
|
||||
private var isCancelled: Boolean = false
|
||||
private var call: Call<LastFmArtist>? = null
|
||||
private var streamFetcher: OkHttpStreamFetcher? = null
|
||||
|
||||
|
||||
override fun getDataClass(): Class<InputStream> {
|
||||
return InputStream::class.java
|
||||
}
|
||||
|
||||
|
||||
override fun getDataSource(): DataSource {
|
||||
return DataSource.REMOTE
|
||||
}
|
||||
|
||||
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
|
||||
try {
|
||||
if (!MusicUtil.isArtistNameUnknown(model.artistName) && RetroUtil.isAllowedToDownloadMetadata(context)) {
|
||||
call = lastFMRestClient.apiService.getArtistInfo(model.artistName, null, if (model.skipOkHttpCache) "no-cache" else null)
|
||||
call!!.enqueue(object : Callback<LastFmArtist> {
|
||||
override fun onResponse(call: Call<LastFmArtist>, response: Response<LastFmArtist>) {
|
||||
if (isCancelled) {
|
||||
callback.onDataReady(null)
|
||||
return
|
||||
}
|
||||
|
||||
val lastFmArtist = response.body()
|
||||
if (lastFmArtist == null || lastFmArtist.artist == null || lastFmArtist.artist.image == null) {
|
||||
callback.onLoadFailed(Exception("No artist image url found"))
|
||||
return
|
||||
}
|
||||
|
||||
val url = LastFMUtil.getLargestArtistImageUrl(lastFmArtist.artist.image)
|
||||
if (TextUtils.isEmpty(url) || TextUtils.isEmpty(url.trim { it <= ' ' })) {
|
||||
callback.onLoadFailed(Exception("No artist image url found"))
|
||||
return
|
||||
}
|
||||
|
||||
streamFetcher = OkHttpStreamFetcher(okHttp, GlideUrl(url))
|
||||
streamFetcher!!.loadData(priority, callback)
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<LastFmArtist>, throwable: Throwable) {
|
||||
callback.onLoadFailed(Exception(throwable))
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
callback.onLoadFailed(e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun cleanup() {
|
||||
if (streamFetcher != null) {
|
||||
streamFetcher!!.cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
isCancelled = true
|
||||
if (call != null) {
|
||||
call!!.cancel()
|
||||
}
|
||||
if (streamFetcher != null) {
|
||||
streamFetcher!!.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TAG: String = ArtistImageFetcher::class.java.simpleName
|
||||
}
|
||||
}
|
||||
|
||||
class ArtistImageLoader(private val context: Context, private val lastFMClient: LastFMRestClient, private val okhttp: OkHttpClient) : ModelLoader<ArtistImage, InputStream> {
|
||||
|
||||
override fun buildLoadData(model: ArtistImage, width: Int, height: Int, options: Options): ModelLoader.LoadData<InputStream>? {
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.audiocover
|
||||
|
||||
|
||||
class AudioFileCover(val filePath: String)
|
|
@ -1,92 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.audiocover
|
||||
|
||||
import android.media.MediaMetadataRetriever
|
||||
import com.bumptech.glide.Priority
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.data.DataFetcher
|
||||
import org.jaudiotagger.audio.mp3.MP3File
|
||||
import java.io.*
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
class AudioFileCoverFetcher(private val model: AudioFileCover) : DataFetcher<InputStream> {
|
||||
private var stream: FileInputStream? = null
|
||||
|
||||
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
|
||||
val retriever = MediaMetadataRetriever()
|
||||
val data: InputStream?
|
||||
try {
|
||||
retriever.setDataSource(model.filePath)
|
||||
val picture = retriever.embeddedPicture
|
||||
if (picture != null) {
|
||||
data = ByteArrayInputStream(picture)
|
||||
} else {
|
||||
data = fallback(model.filePath)
|
||||
}
|
||||
callback.onDataReady(data)
|
||||
} catch (e: FileNotFoundException) {
|
||||
callback.onLoadFailed(e)
|
||||
} finally {
|
||||
retriever.release()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun getDataClass(): Class<InputStream> {
|
||||
return InputStream::class.java
|
||||
}
|
||||
|
||||
|
||||
override fun getDataSource(): DataSource {
|
||||
return DataSource.LOCAL
|
||||
}
|
||||
|
||||
@Throws(FileNotFoundException::class)
|
||||
private fun fallback(path: String): InputStream? {
|
||||
try {
|
||||
val mp3File = MP3File(path)
|
||||
if (mp3File.hasID3v2Tag()) {
|
||||
val art = mp3File.tag.firstArtwork
|
||||
if (art != null) {
|
||||
val imageData = art.binaryData
|
||||
return ByteArrayInputStream(imageData)
|
||||
}
|
||||
}
|
||||
// If there are any exceptions, we ignore them and continue to the other fallback method
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
|
||||
// Method 2: look for album art in external files
|
||||
val parent = File(path).parentFile
|
||||
for (fallback in FALLBACKS) {
|
||||
val cover = File(parent, fallback)
|
||||
if (cover.exists()) {
|
||||
stream = FileInputStream(cover)
|
||||
return stream
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun cleanup() {
|
||||
// already cleaned up in loadData and ByteArrayInputStream will be GC'd
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream!!.close()
|
||||
} catch (ignore: IOException) {
|
||||
// can't do much about it
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
// cannot cancel
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val FALLBACKS = arrayOf("cover.jpg", "album.jpg", "folder.jpg", "cover.png", "album.png", "folder.png")
|
||||
}
|
||||
}
|
|
@ -1,14 +1,102 @@
|
|||
package code.name.monkey.retromusic.glide.audiocover
|
||||
|
||||
import android.media.MediaMetadataRetriever
|
||||
import com.bumptech.glide.Priority
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.Options
|
||||
import com.bumptech.glide.load.data.DataFetcher
|
||||
import com.bumptech.glide.load.model.ModelLoader
|
||||
import com.bumptech.glide.load.model.ModelLoader.LoadData
|
||||
import com.bumptech.glide.load.model.ModelLoaderFactory
|
||||
import com.bumptech.glide.load.model.MultiModelLoaderFactory
|
||||
import com.bumptech.glide.signature.ObjectKey
|
||||
import java.io.InputStream
|
||||
import org.jaudiotagger.audio.mp3.MP3File
|
||||
import java.io.*
|
||||
|
||||
|
||||
class AudioFileCover(val filePath: String)
|
||||
|
||||
class AudioFileCoverFetcher(private val model: AudioFileCover) : DataFetcher<InputStream> {
|
||||
private var stream: FileInputStream? = null
|
||||
|
||||
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
|
||||
val retriever = MediaMetadataRetriever()
|
||||
val data: InputStream?
|
||||
try {
|
||||
retriever.setDataSource(model.filePath)
|
||||
val picture = retriever.embeddedPicture
|
||||
if (picture != null) {
|
||||
data = ByteArrayInputStream(picture)
|
||||
} else {
|
||||
data = fallback(model.filePath)
|
||||
}
|
||||
callback.onDataReady(data)
|
||||
} catch (e: FileNotFoundException) {
|
||||
callback.onLoadFailed(e)
|
||||
} finally {
|
||||
retriever.release()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun getDataClass(): Class<InputStream> {
|
||||
return InputStream::class.java
|
||||
}
|
||||
|
||||
|
||||
override fun getDataSource(): DataSource {
|
||||
return DataSource.LOCAL
|
||||
}
|
||||
|
||||
@Throws(FileNotFoundException::class)
|
||||
private fun fallback(path: String): InputStream? {
|
||||
try {
|
||||
val mp3File = MP3File(path)
|
||||
if (mp3File.hasID3v2Tag()) {
|
||||
val art = mp3File.tag.firstArtwork
|
||||
if (art != null) {
|
||||
val imageData = art.binaryData
|
||||
return ByteArrayInputStream(imageData)
|
||||
}
|
||||
}
|
||||
// If there are any exceptions, we ignore them and continue to the other fallback method
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
|
||||
// Method 2: look for album art in external files
|
||||
val parent = File(path).parentFile
|
||||
for (fallback in FALLBACKS) {
|
||||
val cover = File(parent, fallback)
|
||||
if (cover.exists()) {
|
||||
stream = FileInputStream(cover)
|
||||
return stream
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun cleanup() {
|
||||
// already cleaned up in loadData and ByteArrayInputStream will be GC'd
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream!!.close()
|
||||
} catch (ignore: IOException) {
|
||||
// can't do much about it
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
// cannot cancel
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val FALLBACKS = arrayOf("cover.jpg", "album.jpg", "folder.jpg", "cover.png", "album.png", "folder.png")
|
||||
}
|
||||
}
|
||||
|
||||
class AudioFileCoverLoader : ModelLoader<AudioFileCover, InputStream> {
|
||||
override fun buildLoadData(model: AudioFileCover, width: Int, height: Int,
|
||||
options: Options): LoadData<InputStream>? {
|
||||
|
|
|
@ -1,8 +1,33 @@
|
|||
package code.name.monkey.retromusic.glide.palette
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.widget.ImageView
|
||||
import androidx.palette.graphics.Palette
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||
import com.bumptech.glide.load.Options
|
||||
import com.bumptech.glide.load.engine.Resource
|
||||
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder
|
||||
import com.bumptech.glide.request.target.ImageViewTarget
|
||||
import com.bumptech.glide.util.Util
|
||||
|
||||
class BitmapPaletteTranscoder : ResourceTranscoder<Bitmap, BitmapPaletteWrapper> {
|
||||
override fun transcode(bitmapResource: Resource<Bitmap>, options: Options): Resource<BitmapPaletteWrapper>? {
|
||||
val bitmap = bitmapResource.get()
|
||||
val bitmapPaletteWrapper = BitmapPaletteWrapper(bitmap, RetroColorUtil.generatePalette(bitmap)!!)
|
||||
return BitmapPaletteResource(bitmapPaletteWrapper)
|
||||
}
|
||||
}
|
||||
|
||||
class BitmapPaletteWrapper(val bitmap: Bitmap, val palette: Palette)
|
||||
|
||||
open class BitmapPaletteTarget(view: ImageView) : ImageViewTarget<BitmapPaletteWrapper>(view) {
|
||||
|
||||
override fun setResource(bitmapPaletteWrapper: BitmapPaletteWrapper?) {
|
||||
if (bitmapPaletteWrapper != null) {
|
||||
view.setImageBitmap(bitmapPaletteWrapper.bitmap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BitmapPaletteResource(private val bitmapPaletteWrapper: BitmapPaletteWrapper) : Resource<BitmapPaletteWrapper> {
|
||||
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.palette
|
||||
|
||||
import android.widget.ImageView
|
||||
|
||||
import com.bumptech.glide.request.target.ImageViewTarget
|
||||
|
||||
open class BitmapPaletteTarget(view: ImageView) : ImageViewTarget<BitmapPaletteWrapper>(view) {
|
||||
|
||||
override fun setResource(bitmapPaletteWrapper: BitmapPaletteWrapper?) {
|
||||
if (bitmapPaletteWrapper != null) {
|
||||
view.setImageBitmap(bitmapPaletteWrapper.bitmap)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.palette
|
||||
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||
import com.bumptech.glide.load.Options
|
||||
import com.bumptech.glide.load.engine.Resource
|
||||
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder
|
||||
|
||||
class BitmapPaletteTranscoder : ResourceTranscoder<Bitmap, BitmapPaletteWrapper> {
|
||||
override fun transcode(bitmapResource: Resource<Bitmap>, options: Options): Resource<BitmapPaletteWrapper>? {
|
||||
val bitmap = bitmapResource.get()
|
||||
val bitmapPaletteWrapper = BitmapPaletteWrapper(bitmap, RetroColorUtil.generatePalette(bitmap)!!)
|
||||
return BitmapPaletteResource(bitmapPaletteWrapper)
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.palette
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import androidx.palette.graphics.Palette
|
||||
|
||||
class BitmapPaletteWrapper(val bitmap: Bitmap, val palette: Palette)
|
|
@ -12,13 +12,10 @@ import android.provider.MediaStore
|
|||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.App
|
||||
import code.name.monkey.retromusic.loaders.SongLoader
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.service.MusicService
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import com.google.android.gms.cast.framework.CastContext
|
||||
import com.google.android.gms.cast.framework.CastSession
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
@ -28,19 +25,6 @@ object MusicPlayerRemote {
|
|||
val TAG = MusicPlayerRemote::class.java.simpleName
|
||||
private val mConnectionMap = WeakHashMap<Context, ServiceBinder>()
|
||||
var musicService: MusicService? = null
|
||||
private var playbackLocation = PlaybackLocation.LOCAL
|
||||
|
||||
|
||||
private val castSession: CastSession?
|
||||
get() {
|
||||
val castSession = CastContext.getSharedInstance(App.instance).sessionManager.currentCastSession
|
||||
if (castSession != null) {
|
||||
playbackLocation = PlaybackLocation.REMOTE
|
||||
} else {
|
||||
playbackLocation = PlaybackLocation.LOCAL
|
||||
}
|
||||
return castSession
|
||||
}
|
||||
|
||||
val isPlaying: Boolean
|
||||
get() = musicService != null && musicService!!.isPlaying
|
||||
|
|
|
@ -88,7 +88,7 @@ class AboutActivity : AbsBaseActivity(), View.OnClickListener {
|
|||
toolbar.setBackgroundColor(ThemeStore.primaryColor(this))
|
||||
setSupportActionBar(toolbar)
|
||||
title = null
|
||||
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this))
|
||||
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.textColorSecondary(this))
|
||||
}
|
||||
|
||||
private fun openUrl(url: String) {
|
||||
|
@ -161,8 +161,7 @@ class AboutActivity : AbsBaseActivity(), View.OnClickListener {
|
|||
.setText(String.format(getString(R.string.app_share), packageName))
|
||||
.intent
|
||||
if (shareIntent.resolveActivity(packageManager) != null) {
|
||||
startActivity(
|
||||
Intent.createChooser(shareIntent, resources.getText(R.string.action_share)))
|
||||
startActivity(Intent.createChooser(shareIntent, resources.getText(R.string.action_share)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.os.Bundle
|
|||
import android.transition.Slide
|
||||
import android.view.*
|
||||
import android.view.animation.AnimationUtils
|
||||
import android.widget.ImageView
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.util.Pair
|
||||
import androidx.core.widget.NestedScrollView
|
||||
|
@ -39,6 +40,9 @@ import code.name.monkey.retromusic.util.NavigationUtil
|
|||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.android.synthetic.main.activity_album.*
|
||||
import kotlinx.android.synthetic.main.activity_album_content.*
|
||||
import java.util.*
|
||||
|
@ -47,6 +51,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
|
|||
|
||||
private lateinit var albumDetailsPresenter: AlbumDetailsPresenter
|
||||
private lateinit var simpleSongAdapter: SimpleSongAdapter
|
||||
private var disposable = CompositeDisposable()
|
||||
|
||||
var album: Album? = null
|
||||
private set
|
||||
|
@ -68,11 +73,11 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
|
|||
setDrawUnderStatusBar()
|
||||
setupWindowTransition()
|
||||
super.onCreate(savedInstanceState)
|
||||
toggleBottomNavigationView(true)
|
||||
|
||||
setLightNavigationBar(true)
|
||||
setNavigationbarColorAuto()
|
||||
|
||||
toggleBottomNavigationView(true)
|
||||
|
||||
ActivityCompat.postponeEnterTransition(this)
|
||||
|
||||
|
@ -95,6 +100,8 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
|
|||
}
|
||||
|
||||
actionShuffleAll.setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(album!!.songs!!, true) }
|
||||
|
||||
artistImage = findViewById(R.id.artistImage)
|
||||
artistImage.setOnClickListener {
|
||||
val artistPairs = arrayOf<Pair<*, *>>(Pair.create(image, resources.getString(R.string.transition_artist_image)))
|
||||
NavigationUtil.goToArtist(this, album!!.artistId, *artistPairs)
|
||||
|
@ -134,24 +141,22 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
|
|||
toolbar!!.layoutParams = params
|
||||
}
|
||||
|
||||
if (appBarLayout != null) {
|
||||
appBarLayout!!.apply {
|
||||
addOnOffsetChangedListener(object : AppBarStateChangeListener() {
|
||||
override fun onStateChanged(appBarLayout: AppBarLayout, state: AppBarStateChangeListener.State) {
|
||||
val color: Int = when (state) {
|
||||
AppBarStateChangeListener.State.COLLAPSED -> {
|
||||
setLightStatusbar(ColorUtil.isColorLight(ThemeStore.primaryColor(this@AlbumDetailsActivity)))
|
||||
ThemeStore.primaryColor(this@AlbumDetailsActivity)
|
||||
}
|
||||
AppBarStateChangeListener.State.EXPANDED, AppBarStateChangeListener.State.IDLE -> {
|
||||
setLightStatusbar(false)
|
||||
Color.TRANSPARENT
|
||||
}
|
||||
appBarLayout!!.apply {
|
||||
addOnOffsetChangedListener(object : AppBarStateChangeListener() {
|
||||
override fun onStateChanged(appBarLayout: AppBarLayout, state: AppBarStateChangeListener.State) {
|
||||
val color: Int = when (state) {
|
||||
AppBarStateChangeListener.State.COLLAPSED -> {
|
||||
setLightStatusbar(ColorUtil.isColorLight(ThemeStore.primaryColor(this@AlbumDetailsActivity)))
|
||||
ThemeStore.primaryColor(this@AlbumDetailsActivity)
|
||||
}
|
||||
AppBarStateChangeListener.State.EXPANDED, AppBarStateChangeListener.State.IDLE -> {
|
||||
setLightStatusbar(false)
|
||||
Color.TRANSPARENT
|
||||
}
|
||||
ToolbarContentTintHelper.setToolbarContentColorBasedOnToolbarColor(this@AlbumDetailsActivity, toolbar, color)
|
||||
}
|
||||
})
|
||||
}
|
||||
ToolbarContentTintHelper.setToolbarContentColorBasedOnToolbarColor(this@AlbumDetailsActivity, toolbar, color)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,6 +165,11 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
|
|||
albumDetailsPresenter.unsubscribe()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
disposable.dispose()
|
||||
}
|
||||
|
||||
override fun loading() {
|
||||
|
||||
}
|
||||
|
@ -188,33 +198,42 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
|
|||
simpleSongAdapter.swapDataSet(list.songs)
|
||||
}
|
||||
|
||||
private lateinit var artistImage: ImageView
|
||||
|
||||
private fun loadMoreFrom(album: Album) {
|
||||
if (artistImage != null) {
|
||||
/*ArtistGlideRequest.Builder.from(Glide.with(this),
|
||||
ArtistLoader.getArtist(this, album.artistId).blockingFirst())
|
||||
.forceDownload(false)
|
||||
.generatePalette(this).build()
|
||||
.dontAnimate()
|
||||
.into(object : RetroMusicColoredTarget(artistImage as CircularImageView) {
|
||||
override fun onColorReady(color: Int) {
|
||||
//setColors(color);
|
||||
}
|
||||
})*/
|
||||
}
|
||||
disposable.add(ArtistLoader.getArtist(this, album.artistId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.map {
|
||||
GlideApp.with(this@AlbumDetailsActivity)
|
||||
.asBitmapPalette()
|
||||
.load(RetroGlideExtension.getArtistModel(it))
|
||||
.transition(RetroGlideExtension.getDefaultTransition())
|
||||
.artistOptions(it)
|
||||
.dontAnimate()
|
||||
.into(object : RetroMusicColoredTarget(artistImage) {
|
||||
override fun onColorReady(color: Int) {
|
||||
|
||||
val albums = ArtistLoader.getArtist(this, album.artistId).blockingFirst().albums
|
||||
albums!!.remove(album)
|
||||
if (!albums.isEmpty()) {
|
||||
moreTitle.visibility = View.VISIBLE
|
||||
moreRecyclerView.visibility = View.VISIBLE
|
||||
} else {
|
||||
return
|
||||
}
|
||||
moreTitle.text = String.format("More from %s", album.artistName)
|
||||
}
|
||||
})
|
||||
return@map it.albums!!
|
||||
}
|
||||
.subscribe {
|
||||
|
||||
val albumAdapter = HorizontalAlbumAdapter(this, albums, false, null)
|
||||
moreRecyclerView.layoutManager = GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false)
|
||||
moreRecyclerView.adapter = albumAdapter
|
||||
it.remove(album)
|
||||
if (!it.isEmpty()) {
|
||||
moreTitle.visibility = View.VISIBLE
|
||||
moreRecyclerView.visibility = View.VISIBLE
|
||||
} else {
|
||||
return@subscribe
|
||||
}
|
||||
moreTitle.text = String.format("More from %s", album.artistName)
|
||||
|
||||
val albumAdapter = HorizontalAlbumAdapter(this, it, false, null)
|
||||
moreRecyclerView.layoutManager = GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false)
|
||||
moreRecyclerView.adapter = albumAdapter
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
private fun loadAlbumCover() {
|
||||
|
|
|
@ -55,7 +55,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac
|
|||
private var albumAdapter: AlbumAdapter? = null
|
||||
private var forceDownload: Boolean = false
|
||||
|
||||
private fun setupWindowTransistion() {
|
||||
private fun setupWindowTransitions() {
|
||||
val slide = Slide(Gravity.BOTTOM)
|
||||
slide.interpolator = AnimationUtils.loadInterpolator(this, android.R.interpolator.linear_out_slow_in)
|
||||
window.enterTransition = slide
|
||||
|
@ -68,7 +68,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setDrawUnderStatusBar()
|
||||
setupWindowTransistion()
|
||||
setupWindowTransitions()
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
||||
|
@ -143,15 +143,14 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac
|
|||
if (appBarLayout != null) {
|
||||
appBarLayout!!.addOnOffsetChangedListener(object : AppBarStateChangeListener() {
|
||||
override fun onStateChanged(appBarLayout: AppBarLayout, state: AppBarStateChangeListener.State) {
|
||||
val color: Int
|
||||
when (state) {
|
||||
val color: Int = when (state) {
|
||||
AppBarStateChangeListener.State.COLLAPSED -> {
|
||||
setLightStatusbar(ColorUtil.isColorLight(ThemeStore.primaryColor(appBarLayout.context)))
|
||||
color = ThemeStore.primaryColor(appBarLayout.context)
|
||||
ThemeStore.primaryColor(appBarLayout.context)
|
||||
}
|
||||
AppBarStateChangeListener.State.EXPANDED, AppBarStateChangeListener.State.IDLE -> {
|
||||
setLightStatusbar(false)
|
||||
color = Color.TRANSPARENT
|
||||
Color.TRANSPARENT
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -204,8 +203,8 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac
|
|||
ActivityCompat.startPostponedEnterTransition(this)
|
||||
}
|
||||
|
||||
override fun showData(artist: Artist) {
|
||||
setArtist(artist)
|
||||
override fun showData(list: Artist) {
|
||||
setArtist(list)
|
||||
}
|
||||
|
||||
private fun getArtist(): Artist {
|
||||
|
@ -296,7 +295,6 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac
|
|||
|
||||
actionShuffleAll.setColor(textColor)
|
||||
|
||||
|
||||
findViewById<View>(R.id.root).setBackgroundColor(ThemeStore.primaryColor(this))
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import androidx.core.content.ContextCompat
|
|||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.App
|
||||
|
@ -23,6 +24,7 @@ import code.name.monkey.retromusic.ui.activities.tageditor.WriteTagsAsyncTask
|
|||
import code.name.monkey.retromusic.ui.fragments.base.AbsMusicServiceFragment
|
||||
import code.name.monkey.retromusic.util.LyricUtil
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import kotlinx.android.synthetic.main.activity_lyrics.*
|
||||
|
@ -32,7 +34,19 @@ import org.jaudiotagger.tag.FieldKey
|
|||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener {
|
||||
class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener, ViewPager.OnPageChangeListener {
|
||||
override fun onPageScrollStateChanged(state: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onPageSelected(position: Int) {
|
||||
PreferenceUtil.getInstance().lyricsOptions = position
|
||||
}
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
when (viewPager.currentItem) {
|
||||
0 -> showSyncedLyrics()
|
||||
|
@ -41,7 +55,7 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener {
|
|||
}
|
||||
|
||||
private lateinit var song: Song
|
||||
private var lyrics: Lyrics? = null
|
||||
private var lyricsString: String? = null
|
||||
|
||||
private val googleSearchLrcUrl: String
|
||||
get() {
|
||||
|
@ -73,7 +87,10 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener {
|
|||
|
||||
viewPager.apply {
|
||||
adapter = PagerAdapter(supportFragmentManager)
|
||||
currentItem = PreferenceUtil.getInstance().lyricsOptions
|
||||
addOnPageChangeListener(this@LyricsActivity)
|
||||
}
|
||||
|
||||
tabs.apply {
|
||||
setupWithViewPager(viewPager)
|
||||
setSelectedTabIndicator(TintHelper.createTintedDrawable(ContextCompat.getDrawable(this@LyricsActivity, R.drawable.tab_indicator), ThemeStore.accentColor(this@LyricsActivity)))
|
||||
|
@ -132,10 +149,10 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener {
|
|||
}
|
||||
|
||||
private fun showLyricsSaveDialog() {
|
||||
val content: String = if (lyrics == null) {
|
||||
val content: String = if (lyricsString == null) {
|
||||
""
|
||||
} else {
|
||||
lyrics!!.data
|
||||
lyricsString!!
|
||||
}
|
||||
MaterialDialog.Builder(this)
|
||||
.title("Add lyrics")
|
||||
|
@ -163,155 +180,160 @@ class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener {
|
|||
baseUrl += query
|
||||
return baseUrl
|
||||
}
|
||||
}
|
||||
|
||||
class PagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
|
||||
override fun getItem(position: Int): Fragment {
|
||||
return when (position) {
|
||||
0 -> SyncedLyricsFragment()
|
||||
1 -> OfflineLyricsFragment()
|
||||
else -> {
|
||||
SyncedLyricsFragment()
|
||||
class PagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
|
||||
override fun getItem(position: Int): Fragment {
|
||||
return when (position) {
|
||||
0 -> SyncedLyricsFragment()
|
||||
1 -> OfflineLyricsFragment()
|
||||
else -> SyncedLyricsFragment()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPageTitle(position: Int): CharSequence? {
|
||||
return when (position) {
|
||||
0 -> App.context.getString(R.string.synced_lyrics)
|
||||
1 -> App.context.getString(R.string.normal_lyrics)
|
||||
else -> {
|
||||
App.context.getString(R.string.synced_lyrics)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getCount(): Int {
|
||||
return 2
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class OfflineLyricsFragment : AbsMusicServiceFragment() {
|
||||
|
||||
private var updateLyricsAsyncTask: AsyncTask<*, *, *>? = null
|
||||
private var lyrics: Lyrics? = null
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private fun loadSongLyrics() {
|
||||
if (updateLyricsAsyncTask != null) {
|
||||
updateLyricsAsyncTask!!.cancel(false)
|
||||
}
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
updateLyricsAsyncTask = object : AsyncTask<Void?, Void?, Lyrics?>() {
|
||||
override fun doInBackground(vararg params: Void?): Lyrics? {
|
||||
val data = MusicUtil.getLyrics(song)
|
||||
return if (TextUtils.isEmpty(data)) {
|
||||
null
|
||||
} else Lyrics.parse(song, data)
|
||||
}
|
||||
|
||||
override fun onPreExecute() {
|
||||
super.onPreExecute()
|
||||
lyrics = null
|
||||
}
|
||||
|
||||
override fun onPostExecute(l: Lyrics?) {
|
||||
lyrics = l
|
||||
offlineLyrics.visibility = View.VISIBLE
|
||||
if (l == null) {
|
||||
offlineLyrics.setText(R.string.no_lyrics_found)
|
||||
return
|
||||
override fun getPageTitle(position: Int): CharSequence? {
|
||||
return when (position) {
|
||||
0 -> App.context.getString(R.string.synced_lyrics)
|
||||
1 -> App.context.getString(R.string.normal_lyrics)
|
||||
else -> {
|
||||
App.context.getString(R.string.synced_lyrics)
|
||||
}
|
||||
offlineLyrics.text = l.data
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCancelled(s: Lyrics?) {
|
||||
onPostExecute(null)
|
||||
override fun getCount(): Int {
|
||||
return 2
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract class BaseLyricsFragment : AbsMusicServiceFragment() {
|
||||
abstract fun upDateSong()
|
||||
|
||||
override fun onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged()
|
||||
upDateSong()
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {
|
||||
super.onServiceConnected()
|
||||
upDateSong()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class OfflineLyricsFragment : BaseLyricsFragment() {
|
||||
override fun upDateSong() {
|
||||
loadSongLyrics()
|
||||
}
|
||||
|
||||
private var updateLyricsAsyncTask: AsyncTask<*, *, *>? = null
|
||||
private var lyrics: Lyrics? = null
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private fun loadSongLyrics() {
|
||||
if (updateLyricsAsyncTask != null) {
|
||||
updateLyricsAsyncTask!!.cancel(false)
|
||||
}
|
||||
}.execute()
|
||||
}
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
updateLyricsAsyncTask = object : AsyncTask<Void?, Void?, Lyrics?>() {
|
||||
override fun doInBackground(vararg params: Void?): Lyrics? {
|
||||
val data = MusicUtil.getLyrics(song)
|
||||
return if (TextUtils.isEmpty(data)) {
|
||||
null
|
||||
} else Lyrics.parse(song, data)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
if (updateLyricsAsyncTask != null && !updateLyricsAsyncTask!!.isCancelled) {
|
||||
updateLyricsAsyncTask!!.cancel(true)
|
||||
override fun onPreExecute() {
|
||||
super.onPreExecute()
|
||||
lyrics = null
|
||||
}
|
||||
|
||||
override fun onPostExecute(l: Lyrics?) {
|
||||
lyrics = l
|
||||
offlineLyrics.visibility = View.VISIBLE
|
||||
if (l == null) {
|
||||
offlineLyrics.setText(R.string.no_lyrics_found)
|
||||
return
|
||||
}
|
||||
(activity as LyricsActivity).lyricsString = l.data
|
||||
offlineLyrics.text = l.data
|
||||
}
|
||||
|
||||
override fun onCancelled(s: Lyrics?) {
|
||||
onPostExecute(null)
|
||||
}
|
||||
}.execute()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
if (updateLyricsAsyncTask != null && !updateLyricsAsyncTask!!.isCancelled) {
|
||||
updateLyricsAsyncTask!!.cancel(true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_lyrics, container, false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
loadSongLyrics()
|
||||
}
|
||||
class SyncedLyricsFragment : BaseLyricsFragment(), MusicProgressViewUpdateHelper.Callback {
|
||||
override fun upDateSong() {
|
||||
loadLRCLyrics()
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_lyrics, container, false)
|
||||
}
|
||||
}
|
||||
private lateinit var updateHelper: MusicProgressViewUpdateHelper
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_synced, container, false)
|
||||
}
|
||||
|
||||
class SyncedLyricsFragment : AbsMusicServiceFragment(), MusicProgressViewUpdateHelper.Callback {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
updateHelper = MusicProgressViewUpdateHelper(this, 500, 1000)
|
||||
}
|
||||
|
||||
private lateinit var updateHelper: MusicProgressViewUpdateHelper
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_synced, container, false)
|
||||
}
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setupLyricsView()
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
updateHelper = MusicProgressViewUpdateHelper(this, 500, 1000)
|
||||
}
|
||||
private fun setupLyricsView() {
|
||||
lyricsView.apply {
|
||||
setOnPlayerClickListener { progress, _ -> MusicPlayerRemote.seekTo(progress.toInt()) }
|
||||
setDefaultColor(ContextCompat.getColor(context, R.color.md_grey_400))
|
||||
setHintColor(ThemeStore.textColorPrimary(context))
|
||||
setHighLightColor(ThemeStore.textColorPrimary(context))
|
||||
setTextSize(RetroUtil.convertDpToPixel(18f, context).toInt())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setupLyricsView()
|
||||
}
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
updateHelper.start()
|
||||
}
|
||||
|
||||
private fun setupLyricsView() {
|
||||
lyricsView.apply {
|
||||
setOnPlayerClickListener { progress, _ -> MusicPlayerRemote.seekTo(progress.toInt()) }
|
||||
setDefaultColor(ContextCompat.getColor(context, R.color.md_grey_400))
|
||||
setHintColor(ThemeStore.textColorPrimary(context))
|
||||
setHighLightColor(ThemeStore.textColorPrimary(context))
|
||||
setTextSize(RetroUtil.convertDpToPixel(18f, context).toInt())
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
updateHelper.stop()
|
||||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
lyricsView.setCurrentTimeMillis(progress.toLong())
|
||||
}
|
||||
|
||||
private fun loadLRCLyrics() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
if (LyricUtil.isLrcFileExist(song.title, song.artistName)) {
|
||||
showLyricsLocal(LyricUtil.getLocalLyricFile(song.title, song.artistName))
|
||||
}
|
||||
}
|
||||
|
||||
private fun showLyricsLocal(file: File?) {
|
||||
if (file == null) {
|
||||
lyricsView.reset()
|
||||
} else {
|
||||
lyricsView.setLyricFile(file, "UTF-8")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged()
|
||||
loadLRCLyrics()
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {
|
||||
super.onServiceConnected()
|
||||
loadLRCLyrics()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
updateHelper.start()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
updateHelper.stop()
|
||||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
lyricsView.setCurrentTimeMillis(progress.toLong())
|
||||
}
|
||||
|
||||
private fun loadLRCLyrics() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
if (LyricUtil.isLrcFileExist(song.title, song.artistName)) {
|
||||
showLyricsLocal(LyricUtil.getLocalLyricFile(song.title, song.artistName))
|
||||
}
|
||||
}
|
||||
|
||||
private fun showLyricsLocal(file: File?) {
|
||||
if (file == null) {
|
||||
lyricsView!!.reset()
|
||||
} else {
|
||||
lyricsView!!.setLyricFile(file, "UTF-8")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,7 +37,6 @@ import java.util.*
|
|||
|
||||
class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, PlaylistSongsContract.PlaylistSongsView {
|
||||
|
||||
|
||||
private var playlist: Playlist? = null
|
||||
private var cab: MaterialCab? = null
|
||||
private lateinit var adapter: SongAdapter
|
||||
|
@ -49,7 +48,6 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
|
|||
setDrawUnderStatusBar()
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
||||
setStatusbarColor(Color.TRANSPARENT)
|
||||
setNavigationbarColorAuto()
|
||||
setTaskDescriptionColorAuto()
|
||||
|
@ -203,6 +201,7 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
|
|||
|
||||
private fun checkIsEmpty() {
|
||||
empty.visibility = if (adapter.itemCount == 0) View.VISIBLE else View.GONE
|
||||
emptyText.visibility = if (adapter.itemCount == 0) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
public override fun onPause() {
|
||||
|
@ -239,7 +238,8 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
|
|||
override fun loading() {}
|
||||
|
||||
override fun showEmptyView() {
|
||||
empty!!.visibility = View.VISIBLE
|
||||
empty.visibility = View.VISIBLE
|
||||
emptyText.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
override fun completed() {}
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.app.SearchManager
|
|||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
import android.os.Bundle
|
||||
import android.speech.RecognizerIntent
|
||||
import android.text.Editable
|
||||
|
@ -15,6 +16,8 @@ import android.widget.Toast
|
|||
import androidx.appcompat.widget.SearchView.OnQueryTextListener
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.mvp.contract.SearchContract
|
||||
import code.name.monkey.retromusic.mvp.presenter.SearchPresenter
|
||||
|
@ -35,7 +38,6 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, SearchCon
|
|||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_search)
|
||||
|
||||
|
||||
searchPresenter = SearchPresenter(this)
|
||||
|
||||
setStatusbarColorAuto()
|
||||
|
@ -57,10 +59,12 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, SearchCon
|
|||
}
|
||||
back.setOnClickListener { onBackPressed() }
|
||||
voiceSearch.setOnClickListener { startMicSearch() }
|
||||
|
||||
searchContainer.setCardBackgroundColor(ColorStateList.valueOf(ColorUtil.darkenColor(ThemeStore.primaryColor(this))))
|
||||
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
|
||||
searchAdapter = SearchAdapter(this, emptyList())
|
||||
searchAdapter!!.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||
override fun onChanged() {
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package code.name.monkey.retromusic.ui.activities
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.MenuItem
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.StringRes
|
||||
|
@ -13,6 +10,7 @@ import code.name.monkey.appthemehelper.ThemeStore
|
|||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils
|
||||
import code.name.monkey.retromusic.App.Companion.context
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity
|
||||
|
@ -67,11 +65,13 @@ class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback, Sh
|
|||
private fun setupToolbar() {
|
||||
setSupportActionBar(toolbar)
|
||||
title = null
|
||||
toolbar.setBackgroundColor(ThemeStore.primaryColor(this))
|
||||
toolbar.apply {
|
||||
setBackgroundColor(ThemeStore.primaryColor(context))
|
||||
setNavigationOnClickListener { onBackPressed() }
|
||||
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.textColorSecondary(context))
|
||||
}
|
||||
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this))
|
||||
toolbar.setNavigationOnClickListener { onBackPressed() }
|
||||
settingsTitle.setTextColor(ThemeStore.textColorPrimary(this))
|
||||
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this))
|
||||
}
|
||||
|
||||
fun setupFragment(fragment: Fragment, @StringRes titleName: Int) {
|
||||
|
@ -126,6 +126,6 @@ class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback, Sh
|
|||
|
||||
|
||||
companion object {
|
||||
const val TAG: String = "SettingsActivity"
|
||||
const val TAG: String = "SettingsActivity"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ class UserInfoActivity : AbsBaseActivity() {
|
|||
}
|
||||
|
||||
private fun loadBannerFromStorage(profileImagePath: String) {
|
||||
disposable!!.add(Compressor(this)
|
||||
disposable.add(Compressor(this)
|
||||
.setQuality(100)
|
||||
.setCompressFormat(Bitmap.CompressFormat.WEBP)
|
||||
.compressToBitmapAsFlowable(File(profileImagePath, USER_BANNER))
|
||||
|
@ -190,7 +190,7 @@ class UserInfoActivity : AbsBaseActivity() {
|
|||
}
|
||||
|
||||
private fun loadImageFromStorage(path: String) {
|
||||
disposable!!.add(Compressor(this)
|
||||
disposable.add(Compressor(this)
|
||||
.setMaxHeight(300)
|
||||
.setMaxWidth(300)
|
||||
.setQuality(75)
|
||||
|
|
|
@ -1,135 +0,0 @@
|
|||
package code.name.monkey.retromusic.ui.activities.base
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import code.name.monkey.retromusic.cast.WebServer
|
||||
import com.google.android.gms.cast.framework.CastContext
|
||||
import com.google.android.gms.cast.framework.CastSession
|
||||
import com.google.android.gms.cast.framework.SessionManagerListener
|
||||
import com.google.android.gms.common.ConnectionResult
|
||||
import com.google.android.gms.common.GoogleApiAvailability
|
||||
import java.io.IOException
|
||||
|
||||
abstract class AbsCastActivity : AbsCheckPiracy() {
|
||||
|
||||
var playServicesAvailable = false
|
||||
|
||||
private var castContext: CastContext? = null
|
||||
private var sessionManagerListener: SessionManagerListener<CastSession>? = null
|
||||
var castSession: CastSession? = null
|
||||
private set
|
||||
private var castServer: WebServer? = null
|
||||
|
||||
private fun setupCastListener() {
|
||||
sessionManagerListener = object : SessionManagerListener<CastSession> {
|
||||
|
||||
override fun onSessionEnded(session: CastSession, error: Int) {
|
||||
onApplicationDisconnected()
|
||||
Log.i(TAG, "onSessionEnded: ")
|
||||
}
|
||||
|
||||
override fun onSessionResumed(session: CastSession, wasSuspended: Boolean) {
|
||||
onApplicationConnected(session)
|
||||
Log.i(TAG, "onSessionResumed: ")
|
||||
}
|
||||
|
||||
override fun onSessionResumeFailed(session: CastSession, error: Int) {
|
||||
onApplicationDisconnected()
|
||||
Log.i(TAG, "onSessionResumeFailed: ")
|
||||
}
|
||||
|
||||
override fun onSessionStarted(session: CastSession, sessionId: String) {
|
||||
onApplicationConnected(session)
|
||||
Log.i(TAG, "onSessionStarted: ")
|
||||
}
|
||||
|
||||
override fun onSessionStartFailed(session: CastSession, error: Int) {
|
||||
onApplicationDisconnected()
|
||||
Log.i(TAG, "onSessionStartFailed: ")
|
||||
}
|
||||
|
||||
override fun onSessionStarting(session: CastSession) {}
|
||||
|
||||
override fun onSessionEnding(session: CastSession) {}
|
||||
|
||||
override fun onSessionResuming(session: CastSession, sessionId: String) {}
|
||||
|
||||
override fun onSessionSuspended(session: CastSession, reason: Int) {}
|
||||
|
||||
private fun onApplicationConnected(castSession: CastSession) {
|
||||
this@AbsCastActivity.castSession = castSession
|
||||
castServer = WebServer(applicationContext)
|
||||
try {
|
||||
castServer!!.start()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
invalidateOptionsMenu()
|
||||
showCastMiniController()
|
||||
}
|
||||
|
||||
private fun onApplicationDisconnected() {
|
||||
if (castServer != null) {
|
||||
castServer!!.stop()
|
||||
}
|
||||
invalidateOptionsMenu()
|
||||
hideCastMiniController()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
try {
|
||||
playServicesAvailable = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS
|
||||
} catch (ignored: Exception) {
|
||||
|
||||
}
|
||||
|
||||
if (playServicesAvailable)
|
||||
initCast()
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
if (playServicesAvailable) {
|
||||
castContext!!.sessionManager.addSessionManagerListener(sessionManagerListener!!, CastSession::class.java)
|
||||
}
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
if (playServicesAvailable) {
|
||||
castContext!!.sessionManager.removeSessionManagerListener(sessionManagerListener, CastSession::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
private fun initCast() {
|
||||
setupCastListener()
|
||||
castContext = CastContext.getSharedInstance(this)
|
||||
castSession = castContext!!.sessionManager.currentCastSession
|
||||
}
|
||||
|
||||
/* @Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_cast, menu);
|
||||
if (playServicesAvailable) {
|
||||
CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), menu, R.id.media_route_menu_item);
|
||||
}
|
||||
return true;
|
||||
}*/
|
||||
|
||||
open fun showCastMiniController() {
|
||||
//implement by overriding in activities
|
||||
}
|
||||
|
||||
open fun hideCastMiniController() {
|
||||
//implement by overriding in activities
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = "AbsCastActivity"
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package code.name.monkey.retromusic.ui.activities.base;
|
||||
|
||||
abstract public class AbsCheckPiracy extends AbsBaseActivity {
|
||||
|
||||
}
|
|
@ -17,7 +17,7 @@ import java.lang.ref.WeakReference
|
|||
import java.util.*
|
||||
|
||||
|
||||
abstract class AbsMusicServiceActivity : AbsCastActivity(), MusicServiceEventListener {
|
||||
abstract class AbsMusicServiceActivity : AbsBaseActivity(), MusicServiceEventListener {
|
||||
|
||||
private val mMusicServiceEventListeners = ArrayList<MusicServiceEventListener>()
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ import code.name.monkey.retromusic.ui.fragments.player.plain.PlainPlayerFragment
|
|||
import code.name.monkey.retromusic.ui.fragments.player.simple.SimplePlayerFragment
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.views.BottomNavigationBarTinted
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import com.sothree.slidinguppanel.SlidingUpPanelLayout
|
||||
import com.sothree.slidinguppanel.SlidingUpPanelLayout.PanelState
|
||||
import kotlinx.android.synthetic.main.sliding_music_panel_layout.*
|
||||
|
@ -125,13 +124,6 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
|
|||
return false
|
||||
}
|
||||
|
||||
override fun onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged()
|
||||
castSession ?: return
|
||||
//MusicPlayerRemote.setZeroVolume();
|
||||
//CastHelper.startCasting(castSession, MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
fun toggleBottomNavigationView(toggle: Boolean) {
|
||||
bottomNavigationView.visibility = if (toggle) View.GONE else View.VISIBLE
|
||||
}
|
||||
|
@ -189,7 +181,7 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
|
|||
playerFragment!!.onHide()
|
||||
}
|
||||
|
||||
open fun onPanelExpanded() {
|
||||
open fun onPanelExpanded() {
|
||||
val playerFragmentColor = playerFragment!!.paletteColor
|
||||
super.setTaskDescriptionColor(playerFragmentColor)
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ open class BugReportActivity : AbsThemeActivity() {
|
|||
})
|
||||
}
|
||||
|
||||
inputPassword!!.setOnEditorActionListener { _, actionId, event ->
|
||||
inputPassword!!.setOnEditorActionListener { _, actionId, _ ->
|
||||
if (actionId == EditorInfo.IME_ACTION_SEND) {
|
||||
reportIssue()
|
||||
return@setOnEditorActionListener true
|
||||
|
|
|
@ -4,7 +4,9 @@ import android.net.Uri
|
|||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import androidx.core.content.ContextCompat
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.loaders.SongLoader
|
||||
import kotlinx.android.synthetic.main.activity_song_tag_editor.*
|
||||
|
@ -19,11 +21,14 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
|||
|
||||
private fun setupToolbar() {
|
||||
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this))
|
||||
toolbar.setBackgroundColor(ThemeStore.primaryColor(this))
|
||||
toolbar.setNavigationOnClickListener { onBackPressed() }
|
||||
toolbar.apply {
|
||||
setBackgroundColor(ThemeStore.primaryColor(context))
|
||||
navigationIcon = TintHelper.createTintedDrawable(ContextCompat.getDrawable(context, R.drawable.ic_keyboard_backspace_black_24dp), ThemeStore.textColorPrimary(context))
|
||||
setNavigationOnClickListener { onBackPressed() }
|
||||
setSupportActionBar(toolbar)
|
||||
}
|
||||
title = null
|
||||
bannerTitle!!.setTextColor(ThemeStore.textColorPrimary(this))
|
||||
setSupportActionBar(toolbar)
|
||||
bannerTitle.setTextColor(ThemeStore.textColorPrimary(this))
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
@ -113,5 +118,4 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
|||
companion object {
|
||||
val TAG: String = SongTagEditorActivity::class.java.simpleName
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
||||
import java.util.*
|
||||
|
||||
|
@ -131,6 +131,7 @@ open class AlbumAdapter(protected val activity: AppCompatActivity,
|
|||
GlideApp.with(activity)
|
||||
.asBitmapPalette()
|
||||
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
|
||||
|
||||
.transition(RetroGlideExtension.getDefaultTransition())
|
||||
.songOptions(album.safeGetFirstSong())
|
||||
.dontAnimate()
|
||||
|
|
|
@ -44,12 +44,15 @@ class HorizontalAlbumAdapter(activity: AppCompatActivity, dataSet: ArrayList<Alb
|
|||
.dontAnimate()
|
||||
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
||||
override fun onColorReady(color: Int) {
|
||||
setColors(color, holder)
|
||||
if (usePalette)
|
||||
setColors(color, holder)
|
||||
else
|
||||
setColors(albumArtistFooterColor, holder)
|
||||
}
|
||||
|
||||
override fun onLoadFailed(errorDrawable: Drawable?) {
|
||||
super.onLoadFailed(errorDrawable)
|
||||
setColors(defaultFooterColor, holder)
|
||||
setColors(albumArtistFooterColor, holder)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -32,7 +32,8 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
|
|||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_mini_player, container, false)
|
||||
}
|
||||
override fun onClick(view: View) {
|
||||
|
||||
override fun onClick(view: View) {
|
||||
when (view.id) {
|
||||
R.id.actionPlayingQueue -> NavigationUtil.goToPlayingQueue(activity!!)
|
||||
R.id.actionNext -> MusicPlayerRemote.playNextSong()
|
||||
|
@ -49,13 +50,13 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
|
|||
setUpMiniPlayer()
|
||||
|
||||
if (RetroUtil.isTablet()) {
|
||||
actionNext!!.visibility = View.VISIBLE
|
||||
actionPrevious!!.visibility = View.VISIBLE
|
||||
actionPlayingQueue!!.visibility = View.VISIBLE
|
||||
actionNext.visibility = View.VISIBLE
|
||||
actionPrevious.visibility = View.VISIBLE
|
||||
actionPlayingQueue.visibility = View.VISIBLE
|
||||
} else {
|
||||
actionNext!!.visibility = if (PreferenceUtil.getInstance().isExtraMiniExtraControls) View.VISIBLE else View.GONE
|
||||
actionPlayingQueue!!.visibility = if (PreferenceUtil.getInstance().isExtraMiniExtraControls) View.GONE else View.VISIBLE
|
||||
actionPrevious!!.visibility = if (PreferenceUtil.getInstance().isExtraMiniExtraControls) View.VISIBLE else View.GONE
|
||||
actionNext.visibility = if (PreferenceUtil.getInstance().isExtraMiniExtraControls) View.VISIBLE else View.GONE
|
||||
actionPlayingQueue.visibility = if (PreferenceUtil.getInstance().isExtraMiniExtraControls) View.GONE else View.VISIBLE
|
||||
actionPrevious.visibility = if (PreferenceUtil.getInstance().isExtraMiniExtraControls) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
actionPlayingQueue.setOnClickListener(this)
|
||||
|
@ -65,7 +66,7 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
|
|||
|
||||
private fun setUpMiniPlayer() {
|
||||
setUpPlayPauseButton()
|
||||
progressBar!!.progressTintList = ColorStateList.valueOf(ThemeStore.accentColor(activity!!))
|
||||
progressBar.progressTintList = ColorStateList.valueOf(ThemeStore.accentColor(activity!!))
|
||||
}
|
||||
|
||||
private fun setUpPlayPauseButton() {
|
||||
|
@ -128,14 +129,13 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
|
|||
}
|
||||
|
||||
fun setColor(playerFragmentColor: Int) {
|
||||
|
||||
view!!.setBackgroundColor(playerFragmentColor)
|
||||
}
|
||||
|
||||
|
||||
class FlingPlayBackController(context: Context) : View.OnTouchListener {
|
||||
|
||||
internal var flingPlayBackController: GestureDetector
|
||||
var flingPlayBackController: GestureDetector
|
||||
|
||||
init {
|
||||
flingPlayBackController = GestureDetector(context,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package code.name.monkey.retromusic.ui.fragments
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.graphics.PorterDuff
|
||||
import android.media.AudioManager
|
||||
|
@ -10,7 +11,7 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import android.widget.SeekBar
|
||||
import androidx.fragment.app.Fragment
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
|
@ -33,7 +34,7 @@ class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolum
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setTintable(ATHUtil.resolveColor(context, R.attr.iconColor))
|
||||
setTintable(ThemeStore.textColorSecondary(context!!))
|
||||
volumeDown.setOnClickListener(this)
|
||||
volumeUp.setOnClickListener(this)
|
||||
}
|
||||
|
@ -98,7 +99,13 @@ class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolum
|
|||
}
|
||||
|
||||
private fun setProgressBarColor(newColor: Int) {
|
||||
TintHelper.setTintAuto(volumeSeekBar, newColor, false)
|
||||
|
||||
val text = ColorStateList(arrayOf(intArrayOf(-android.R.attr.state_checked), intArrayOf(android.R.attr.state_checked)), intArrayOf(ThemeStore.textColorSecondary(context!!), ThemeStore.textColorPrimary(context!!)))
|
||||
|
||||
volumeSeekBar.progressTintList = text
|
||||
volumeSeekBar.progressBackgroundTintList = text
|
||||
|
||||
//TintHelper.setTint(volumeSeekBar, newColor, false)
|
||||
volumeDown.setColorFilter(newColor, PorterDuff.Mode.SRC_IN)
|
||||
volumeUp.setColorFilter(newColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ abstract class AbsLibraryPagerRecyclerViewFragment<A : RecyclerView.Adapter<*>,
|
|||
get() = R.string.empty
|
||||
|
||||
private fun checkIsEmpty() {
|
||||
empty.setText(emptyMessage)
|
||||
emptyText.setText(emptyMessage)
|
||||
empty.visibility = if (adapter!!.itemCount == 0) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,12 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
|||
private ImageView userImage;
|
||||
private CompositeDisposable disposable = new CompositeDisposable();
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
disposable.dispose();
|
||||
}
|
||||
|
||||
public static Fragment newInstance(int tab) {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(CURRENT_TAB_ID, tab);
|
||||
|
|
|
@ -17,6 +17,7 @@ import code.name.monkey.appthemehelper.util.TintHelper
|
|||
import code.name.monkey.retromusic.Constants.USER_BANNER
|
||||
import code.name.monkey.retromusic.Constants.USER_PROFILE
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.glide.GlideApp
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
|
||||
import code.name.monkey.retromusic.loaders.SongLoader
|
||||
|
@ -35,7 +36,6 @@ 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.RetroUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
@ -91,11 +91,11 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
|
|||
private fun loadTimeImage(day: String) {
|
||||
if (bannerImage != null) {
|
||||
if (PreferenceUtil.getInstance().bannerImage.isEmpty()) {
|
||||
/*Glide.with(activity).load(day)
|
||||
.asBitmap()
|
||||
GlideApp.with(activity!!)
|
||||
.load(day)
|
||||
.placeholder(R.drawable.material_design_default)
|
||||
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
|
||||
.into(bannerImage!!)*/
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.into(bannerImage!!)
|
||||
} else {
|
||||
disposable.add(Compressor(context!!)
|
||||
.setQuality(100)
|
||||
|
@ -176,7 +176,7 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
|
|||
}
|
||||
|
||||
private fun setupToolbar() {
|
||||
toolbar.navigationIcon = TintHelper.createTintedDrawable(ContextCompat.getDrawable(context!!, R.drawable.ic_search_white_24dp), ThemeStore.textColorPrimary(context!!))
|
||||
toolbar.navigationIcon = TintHelper.createTintedDrawable(ContextCompat.getDrawable(context!!, R.drawable.ic_search_white_24dp), ThemeStore.textColorSecondary(context!!))
|
||||
mainActivity.title = null
|
||||
mainActivity.setSupportActionBar(toolbar)
|
||||
toolbar.setBackgroundColor(Color.TRANSPARENT)
|
||||
|
@ -188,7 +188,7 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
|
|||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
disposable.clear()
|
||||
disposable.dispose()
|
||||
homePresenter.unsubscribe()
|
||||
}
|
||||
|
||||
|
@ -236,8 +236,7 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
|
|||
|
||||
override fun topAlbums(albums: ArrayList<Album>) {
|
||||
topAlbumsContainer.visibility = View.VISIBLE
|
||||
val artistAdapter = AlbumFullWithAdapter(mainActivity,
|
||||
displayMetrics)
|
||||
val artistAdapter = AlbumFullWithAdapter(mainActivity, displayMetrics)
|
||||
artistAdapter.swapData(albums)
|
||||
topAlbum.adapter = artistAdapter
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import android.view.animation.LinearInterpolator
|
||||
import android.widget.SeekBar
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.normal
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ArgbEvaluator
|
||||
import android.animation.ValueAnimator
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewAnimationUtils
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
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
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment
|
||||
|
@ -19,6 +24,8 @@ import code.name.monkey.retromusic.util.PreferenceUtil
|
|||
import code.name.monkey.retromusic.util.ViewUtil
|
||||
import code.name.monkey.retromusic.views.DrawableGradient
|
||||
import kotlinx.android.synthetic.main.fragment_player.*
|
||||
import kotlinx.android.synthetic.main.fragment_player_playback_controls.*
|
||||
import kotlinx.android.synthetic.main.media_button.*
|
||||
|
||||
|
||||
class PlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
||||
|
@ -59,7 +66,7 @@ class PlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
|||
}
|
||||
|
||||
override fun toolbarIconColor(): Int {
|
||||
return ATHUtil.resolveColor(context, R.attr.iconColor)
|
||||
return ATHUtil.resolveColor(context, code.name.monkey.retromusic.R.attr.iconColor)
|
||||
}
|
||||
|
||||
override fun onColorChanged(color: Int) {
|
||||
|
@ -67,7 +74,7 @@ class PlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
|||
lastColor = color
|
||||
callbacks!!.onPaletteColorChanged()
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, R.attr.iconColor), activity)
|
||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, code.name.monkey.retromusic.R.attr.iconColor), activity)
|
||||
|
||||
if (PreferenceUtil.getInstance().adaptiveColor) {
|
||||
colorize(color)
|
||||
|
@ -89,28 +96,28 @@ class PlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
|||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
|
||||
return inflater.inflate(R.layout.fragment_player, container, false)
|
||||
return inflater.inflate(code.name.monkey.retromusic.R.layout.fragment_player, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
snowfall.visibility= if (PreferenceUtil.getInstance().isSnowFall) View.VISIBLE else View.GONE
|
||||
snowfall.visibility = if (PreferenceUtil.getInstance().isSnowFall) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
private fun setUpSubFragments() {
|
||||
playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as PlayerPlaybackControlsFragment
|
||||
val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
|
||||
playbackControlsFragment = childFragmentManager.findFragmentById(code.name.monkey.retromusic.R.id.playbackControlsFragment) as PlayerPlaybackControlsFragment
|
||||
val playerAlbumCoverFragment = childFragmentManager.findFragmentById(code.name.monkey.retromusic.R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
|
||||
playerAlbumCoverFragment.setCallbacks(this)
|
||||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
playerToolbar.inflateMenu(code.name.monkey.retromusic.R.menu.menu_player)
|
||||
playerToolbar.setNavigationOnClickListener { activity!!.onBackPressed() }
|
||||
playerToolbar.setOnMenuItemClickListener(this)
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, R.attr.iconColor), activity)
|
||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, code.name.monkey.retromusic.R.attr.iconColor), activity)
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {
|
||||
|
@ -133,3 +140,4 @@ class PlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,12 @@ import android.annotation.SuppressLint;
|
|||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.signature.ObjectKey;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import code.name.monkey.retromusic.App;
|
||||
|
||||
|
||||
public class ArtistSignatureUtil {
|
||||
private static final String ARTIST_SIGNATURE_PREFS = "artist_signatures";
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ class CustomArtistImageUtil private constructor(context: Context) {
|
|||
object : AsyncTask<Void, Void, Void>() {
|
||||
@SuppressLint("ApplySharedPref")
|
||||
override fun doInBackground(vararg params: Void): Void? {
|
||||
val dir = File(App.context.getFilesDir(), FOLDER_NAME)
|
||||
val dir = File(App.context.filesDir, FOLDER_NAME)
|
||||
if (!dir.exists()) {
|
||||
if (!dir.mkdirs()) { // create the folder
|
||||
return null
|
||||
|
@ -63,7 +63,7 @@ class CustomArtistImageUtil private constructor(context: Context) {
|
|||
if (succesful) {
|
||||
mPreferences.edit().putBoolean(getFileName(artist), true).commit()
|
||||
ArtistSignatureUtil.getInstance().updateArtistSignature(artist.name)
|
||||
App.context.getContentResolver().notifyChange(Uri.parse("content://media"), null) // trigger media store changed to force artist image reload
|
||||
App.context.contentResolver.notifyChange(Uri.parse("content://media"), null) // trigger media store changed to force artist image reload
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ class CustomArtistImageUtil private constructor(context: Context) {
|
|||
|
||||
@JvmStatic
|
||||
fun getFile(artist: Artist): File {
|
||||
val dir = File(App.context.getFilesDir(), FOLDER_NAME)
|
||||
val dir = File(App.context.filesDir, FOLDER_NAME)
|
||||
return File(dir, getFileName(artist))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package code.name.monkey.retromusic.util;
|
|||
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.audiofx.AudioEffect;
|
||||
import android.widget.Toast;
|
||||
|
@ -12,8 +11,8 @@ import androidx.annotation.Nullable;
|
|||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.app.ActivityOptionsCompat;
|
||||
import androidx.core.util.Pair;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.cast.ExpandedCastControlsActivity;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.model.Genre;
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
|
@ -137,20 +136,7 @@ public class NavigationUtil {
|
|||
openUrl(activity, RATE_ON_GOOGLE_PLAY);
|
||||
}
|
||||
|
||||
public static void gotoExpandedController(Activity activity) {
|
||||
ActivityCompat.startActivity(activity, new Intent(activity, ExpandedCastControlsActivity.class), null);
|
||||
}
|
||||
|
||||
public static void gotoWhatNews(Activity activity) {
|
||||
ActivityCompat.startActivity(activity, new Intent(activity, WhatsNewActivity.class), null);
|
||||
}
|
||||
|
||||
public static void gotoNowPlayingActivity(Context context, @Nullable Pair... sharedElements) {
|
||||
//ActivityCompat.startActivity(context, new Intent(context, NowPayingActivity.class), ActivityOptionsCompat.makeSceneTransitionAnimation((Activity) context, sharedElements).toBundle());
|
||||
|
||||
}
|
||||
|
||||
public static void gotoNowPlaying(Activity activity) {
|
||||
//ActivityCompat.startActivity(activity, new Intent(activity, NowPayingActivity.class),null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,30 +7,24 @@ import android.content.SharedPreferences.Editor;
|
|||
import android.content.res.TypedArray;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import com.google.android.material.bottomnavigation.LabelVisibilityMode;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StyleRes;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.google.android.material.bottomnavigation.LabelVisibilityMode;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Objects;
|
||||
|
||||
import code.name.monkey.retromusic.App;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.SortOrder;
|
||||
import code.name.monkey.retromusic.model.CategoryInfo;
|
||||
import code.name.monkey.retromusic.transform.CascadingPageTransformer;
|
||||
import code.name.monkey.retromusic.transform.DepthTransformation;
|
||||
import code.name.monkey.retromusic.transform.HingeTransformation;
|
||||
import code.name.monkey.retromusic.transform.HorizontalFlipTransformation;
|
||||
import code.name.monkey.retromusic.transform.NormalPageTransformer;
|
||||
import code.name.monkey.retromusic.transform.StackPagerTransformer;
|
||||
import code.name.monkey.retromusic.transform.StackTransformer;
|
||||
import code.name.monkey.retromusic.transform.VerticalFlipTransformation;
|
||||
import code.name.monkey.retromusic.ui.activities.MainActivity;
|
||||
|
@ -71,7 +65,6 @@ public final class PreferenceUtil {
|
|||
public static final String ALBUM_COVER_TRANSFORM = "album_cover_transform";
|
||||
public static final String TAB_TEXT_MODE = "tab_text_mode";
|
||||
private static final String GENRE_SORT_ORDER = "genre_sort_order";
|
||||
private static final String LIBRARY_CATEGORIES = "library_categories";
|
||||
private static final String LAST_PAGE = "last_start_page";
|
||||
private static final String LAST_MUSIC_CHOOSER = "last_music_chooser";
|
||||
private static final String DEFAULT_START_PAGE = "default_start_page";
|
||||
|
@ -106,7 +99,7 @@ public final class PreferenceUtil {
|
|||
private static final String LOCK_SCREEN = "lock_screen";
|
||||
private static final String ALBUM_DETAIL_SONG_SORT_ORDER = "album_detail_song_sort_order";
|
||||
private static final String ARTIST_DETAIL_SONG_SORT_ORDER = "artist_detail_song_sort_order";
|
||||
private static final String LYRICS_OPTIONS = "lyrics_options";
|
||||
private static final String LYRICS_OPTIONS = "lyrics_tab_position";
|
||||
private static final String CHOOSE_EQUALIZER = "choose_equalizer";
|
||||
private static final String TOGGLE_SHUFFLE = "toggle_shuffle";
|
||||
private static final String SONG_GRID_STYLE = "song_grid_style";
|
||||
|
@ -133,17 +126,17 @@ public final class PreferenceUtil {
|
|||
@StyleRes
|
||||
public static int getThemeResFromPrefValue(String themePrefValue) {
|
||||
switch (themePrefValue) {
|
||||
case "dark":
|
||||
return R.style.Theme_RetroMusic;
|
||||
case "light":
|
||||
return R.style.Theme_RetroMusic_Light;
|
||||
case "color":
|
||||
return R.style.Theme_RetroMusic_Color;
|
||||
case "acolor":
|
||||
return R.style.Theme_RetroMusic_Black;
|
||||
case "black":
|
||||
return R.style.Theme_RetroMusic_Black;
|
||||
case "light":
|
||||
case "dark":
|
||||
default:
|
||||
return R.style.Theme_RetroMusic_Light;
|
||||
return R.style.Theme_RetroMusic;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,8 +163,7 @@ public final class PreferenceUtil {
|
|||
}
|
||||
|
||||
public final String getArtistAlbumSortOrder() {
|
||||
return mPreferences
|
||||
.getString(ARTIST_ALBUM_SORT_ORDER, SortOrder.ArtistAlbumSortOrder.ALBUM_YEAR);
|
||||
return mPreferences.getString(ARTIST_ALBUM_SORT_ORDER, SortOrder.ArtistAlbumSortOrder.ALBUM_YEAR);
|
||||
}
|
||||
|
||||
public final String getAlbumSortOrder() {
|
||||
|
@ -221,51 +213,10 @@ public final class PreferenceUtil {
|
|||
return mPreferences.getBoolean(TOGGLE_ADD_CONTROLS, false);
|
||||
}
|
||||
|
||||
public boolean circularAlbumArt() {
|
||||
return mPreferences.getBoolean(CIRCULAR_ALBUM_ART, false);
|
||||
}
|
||||
|
||||
public boolean carouselEffect() {
|
||||
return mPreferences.getBoolean(CAROUSEL_EFFECT, false);
|
||||
}
|
||||
|
||||
public ArrayList<CategoryInfo> getLibraryCategoryInfos() {
|
||||
String data = mPreferences.getString(LIBRARY_CATEGORIES, null);
|
||||
if (data != null) {
|
||||
Gson gson = new Gson();
|
||||
Type collectionType = new TypeToken<ArrayList<CategoryInfo>>() {
|
||||
}.getType();
|
||||
|
||||
try {
|
||||
return gson.fromJson(data, collectionType);
|
||||
} catch (JsonSyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return getDefaultLibraryCategoryInfos();
|
||||
}
|
||||
|
||||
public void setLibraryCategoryInfos(ArrayList<CategoryInfo> categories) {
|
||||
Gson gson = new Gson();
|
||||
Type collectionType = new TypeToken<ArrayList<CategoryInfo>>() {
|
||||
}.getType();
|
||||
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putString(LIBRARY_CATEGORIES, gson.toJson(categories, collectionType));
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public ArrayList<CategoryInfo> getDefaultLibraryCategoryInfos() {
|
||||
ArrayList<CategoryInfo> defaultCategoryInfos = new ArrayList<>(5);
|
||||
defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.SONGS, true));
|
||||
defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.ALBUMS, true));
|
||||
defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.ARTISTS, true));
|
||||
defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.GENRES, true));
|
||||
defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.PLAYLISTS, true));
|
||||
return defaultCategoryInfos;
|
||||
}
|
||||
|
||||
public boolean isRoundCorners() {
|
||||
return mPreferences.getBoolean(ROUND_CORNERS, false);
|
||||
}
|
||||
|
@ -552,7 +503,7 @@ public final class PreferenceUtil {
|
|||
}
|
||||
|
||||
public int getGeneralTheme() {
|
||||
return getThemeResFromPrefValue(mPreferences.getString(GENERAL_THEME, "light"));
|
||||
return getThemeResFromPrefValue(mPreferences.getString(GENERAL_THEME, "dark"));
|
||||
}
|
||||
|
||||
public void setGeneralTheme(String theme) {
|
||||
|
@ -611,10 +562,6 @@ public final class PreferenceUtil {
|
|||
mPreferences.edit().putInt(TOGGLE_FULL_SCREEN, newValue).apply();
|
||||
}
|
||||
|
||||
public String lyricsOptions() {
|
||||
return mPreferences.getString(LYRICS_OPTIONS, "offline");
|
||||
}
|
||||
|
||||
public void saveProfileImage(String profileImagePath) {
|
||||
mPreferences.edit().putString(PROFILE_IMAGE_PATH, profileImagePath)
|
||||
.apply();
|
||||
|
|
|
@ -1,24 +1,53 @@
|
|||
package code.name.monkey.retromusic.util;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import android.os.Build;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.PathInterpolator;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.core.view.ViewCompat;
|
||||
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
public class ViewUtil {
|
||||
|
||||
public final static int RETRO_MUSIC_ANIM_TIME = 1000;
|
||||
|
||||
public static Animator createTextColorTransition(final TextView v, @ColorInt final int startColor, @ColorInt final int endColor) {
|
||||
return createColorAnimator(v, "textColor", startColor, endColor);
|
||||
}
|
||||
|
||||
private static Animator createColorAnimator(Object target, String propertyName, @ColorInt int startColor, @ColorInt int endColor) {
|
||||
ObjectAnimator animator;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
animator = ObjectAnimator.ofArgb(target, propertyName, startColor, endColor);
|
||||
} else {
|
||||
animator = ObjectAnimator.ofInt(target, propertyName, startColor, endColor);
|
||||
animator.setEvaluator(new ArgbEvaluator());
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
animator.setInterpolator(new PathInterpolator(0.4f, 0f, 1f, 1f));
|
||||
}
|
||||
animator.setDuration(RETRO_MUSIC_ANIM_TIME);
|
||||
return animator;
|
||||
}
|
||||
|
||||
public static void setStatusBarHeight(final Context context, View statusBar) {
|
||||
ViewGroup.LayoutParams lp = statusBar.getLayoutParams();
|
||||
lp.height = getStatusBarHeight(context);
|
||||
|
@ -59,4 +88,9 @@ public class ViewUtil {
|
|||
DisplayMetrics metrics = resources.getDisplayMetrics();
|
||||
return dp * metrics.density;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Animator createBackgroundColorTransition(@Nullable View colorGradientBackground, int lastColor, int newColor) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -13,7 +13,6 @@ import android.graphics.Path;
|
|||
import android.graphics.Rect;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Looper;
|
||||
import androidx.annotation.IntDef;
|
||||
import android.text.Layout;
|
||||
import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
|
@ -25,7 +24,12 @@ import android.view.View;
|
|||
import android.view.ViewConfiguration;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
|
||||
import org.mozilla.universalchardet.UniversalDetector;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
@ -38,7 +42,8 @@ import java.lang.annotation.RetentionPolicy;
|
|||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.mozilla.universalchardet.UniversalDetector;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
/**
|
||||
* Created by zhengken.me on 2016/11/27.
|
||||
|
@ -588,7 +593,7 @@ public class LyricView extends View {
|
|||
mTextPaint = new TextPaint();
|
||||
mTextPaint.setDither(true);
|
||||
mTextPaint.setAntiAlias(true);
|
||||
Typeface typeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/circular_std_book.otf");
|
||||
Typeface typeface = ResourcesCompat.getFont(getContext(), R.font.font);
|
||||
mTextPaint.setTypeface(typeface);
|
||||
|
||||
switch (mTextAlign) {
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
package code.name.monkey.retromusic.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
|
||||
public class MaterialButtonTextColor extends MaterialButton {
|
||||
public MaterialButtonTextColor(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public MaterialButtonTextColor(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, -1);
|
||||
}
|
||||
|
||||
public MaterialButtonTextColor(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setTextColor(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(ThemeStore.primaryColor(getContext()))));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package code.name.monkey.retromusic.views
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.util.AttributeSet
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.google.android.material.button.MaterialButton
|
||||
|
||||
class MaterialButtonTextColor @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = -1) : MaterialButton(context, attrs, defStyleAttr) {
|
||||
|
||||
init {
|
||||
setTextColor(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(ThemeStore.primaryColor(getContext()))))
|
||||
iconTint = ColorStateList.valueOf(ATHUtil.resolveColor(context, R.attr.iconColor))
|
||||
iconPadding = RetroUtil.convertDpToPixel(16f, getContext()).toInt()
|
||||
rippleColor = ColorStateList.valueOf(ColorUtil.withAlpha(ThemeStore.accentColor(context), 0.4f))
|
||||
minHeight = RetroUtil.convertDpToPixel(52f, context).toInt()
|
||||
}
|
||||
}
|
|
@ -4,9 +4,8 @@ import android.content.Context;
|
|||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.GlideApp;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
|
@ -33,10 +32,11 @@ public class NetworkImageView extends CircularImageView {
|
|||
}
|
||||
|
||||
public void setImageUrl(Context context, String imageUrl) {
|
||||
/*Glide.with(context).load(imageUrl).asBitmap()
|
||||
GlideApp.with(context)
|
||||
.load(imageUrl)
|
||||
.error(R.drawable.ic_person_flat)
|
||||
.placeholder(R.drawable.ic_person_flat)
|
||||
.into(this);*/
|
||||
.into(this);
|
||||
}
|
||||
|
||||
private void init(Context context, AttributeSet attributeSet) {
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package code.name.monkey.retromusic.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.WindowInsets;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
public class StatusBarMarginFrameLayout extends FrameLayout {
|
||||
|
||||
|
||||
public StatusBarMarginFrameLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public StatusBarMarginFrameLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public StatusBarMarginFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
|
||||
lp.topMargin = insets.getSystemWindowInsetTop();
|
||||
setLayoutParams(lp);
|
||||
}
|
||||
return super.onApplyWindowInsets(insets);
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
package code.name.monkey.retromusic.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
import androidx.mediarouter.app.MediaRouteActionProvider;
|
||||
import androidx.mediarouter.app.MediaRouteButton;
|
||||
import androidx.appcompat.view.ContextThemeWrapper;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
|
||||
public class ThemeableMediaRouteActionProvider extends MediaRouteActionProvider {
|
||||
public ThemeableMediaRouteActionProvider(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaRouteButton onCreateMediaRouteButton() {
|
||||
MediaRouteButton button = super.onCreateMediaRouteButton();
|
||||
colorWorkaroundForCastIcon(button);
|
||||
return button;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MediaRouteButton getMediaRouteButton() {
|
||||
MediaRouteButton button = super.getMediaRouteButton();
|
||||
colorWorkaroundForCastIcon(button);
|
||||
return button;
|
||||
}
|
||||
|
||||
private void colorWorkaroundForCastIcon(MediaRouteButton button) {
|
||||
if (button == null) return;
|
||||
Context castContext = new ContextThemeWrapper(getContext(), androidx.mediarouter.R.style.Theme_MediaRouter);
|
||||
|
||||
TypedArray a = castContext.obtainStyledAttributes(null,
|
||||
androidx.mediarouter.R.styleable.MediaRouteButton, androidx.mediarouter.R.attr.mediaRouteButtonStyle, 0);
|
||||
Drawable drawable = a.getDrawable(
|
||||
androidx.mediarouter.R.styleable.MediaRouteButton_externalRouteEnabledDrawable);
|
||||
a.recycle();
|
||||
if (drawable != null) {
|
||||
DrawableCompat.setTint(drawable, ThemeStore.textColorPrimary(getContext()));
|
||||
drawable.setState(button.getDrawableState());
|
||||
button.setRemoteIndicatorDrawable(drawable);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,6 @@ class TintIconColorToolbar : Toolbar {
|
|||
|
||||
override fun setNavigationIcon(icon: Drawable?) {
|
||||
super.setNavigationIcon(icon)
|
||||
icon?.setColorFilter(ThemeStore.accentColor(context), PorterDuff.Mode.SRC_IN)
|
||||
icon?.setColorFilter(ThemeStore.textColorSecondary(context), PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,7 @@
|
|||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path android:pathData="M0,0h24v24H0V0z" />
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12C22,6.48,17.52,2,11.99,2z M12,20 c-4.42,0-8-3.58-8-8c0-4.42,3.58-8,8-8s8,3.58,8,8C20,16.42,16.42,20,12,20z" />
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M11.78,7h-0.06C11.32,7,11,7.32,11,7.72v4.72c0,0.35,0.18,0.68,0.49,0.86l4.15,2.49c0.34,0.2,0.78,0.1,0.98-0.24v0 c0.21-0.34,0.1-0.79-0.25-0.99l-3.87-2.3V7.72C12.5,7.32,12.18,7,11.78,7z" />
|
||||
android:pathData="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm0.5-13H11v6l5.25 3.15 0.75 -1.23-4.5-2.67z" />
|
||||
</vector>
|
12
app/src/main/res/drawable/ic_add_photo_white_24dp.xml
Normal file
12
app/src/main/res/drawable/ic_add_photo_white_24dp.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M18 20H4V6h9V4H4c-1.1 0-2 0.9-2 2v14c0 1.1 0.9 2 2 2h14c1.1 0 2-0.9 2-2v-9h-2v9zm-7.79-3.17l-1.96-2.36L5.5 18h11l-3.54-4.71zM20 4V1h-2v3h-3c0.01 0.01 0 2 0 2h3v2.99c0.01 0.01 2 0 2 0V6h3V4h-3z" />
|
||||
</vector>
|
11
app/src/main/res/drawable/ic_album_selected_white_24dp.xml
Normal file
11
app/src/main/res/drawable/ic_album_selected_white_24dp.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-0.55 0-1 0.45-1 1s0.45 1 1 1 1-0.45 1-1-0.45-1-1-1z" />
|
||||
</vector>
|
|
@ -5,7 +5,8 @@
|
|||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-0.55 0-1 0.45-1 1s0.45 1 1 1 1-0.45 1-1-0.45-1-1-1z" />
|
||||
android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-12.5c-2.49 0-4.5 2.01-4.5 4.5s2.01 4.5 4.5 4.5 4.5-2.01 4.5-4.5-2.01-4.5-4.5-4.5zm0 5.5c-0.55 0-1-0.45-1-1s0.45-1 1-1 1 0.45 1 1-0.45 1-1 1z" />
|
||||
</vector>
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M 2,5 C 1.45,5 1,5.45 1,6 l 0,12 c 0,0.55 0.45,1 1,1 l 12,0 c 0.55,0 1,-0.45 1,-1 L 15,6 C 15,5.45 14.55,5 14,5 L 2,5 Z m 7.390625,8.289062 c 0.2,-0.259999 0.589063,-0.26 0.789063,0 l 2.210937,2.900391 c 0.25,0.33 0.01961,0.800781 -0.400391,0.800781 l -7.960937,0 c -0.41,0.01 -0.648672,-0.470781 -0.388672,-0.800781 l 1.46875,-1.859375 c 0.2,-0.25 0.57125,-0.249766 0.78125,-0.0098 L 7.289062,16 9.390625,13.289062 Z" />
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M 22,5 c -0.55,0 -1,0.45 -1,1 l 0,12 c 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 L 23,6 C 23,5.45 22.55,5 22,5 Z" />
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M 18,5 c -0.55,0 -1,0.45 -1,1 l 0,12 c 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 L 19,6 C 19,5.45 18.55,5 18,5 Z" />
|
||||
</vector>
|
20
app/src/main/res/drawable/ic_app_shortcut_search.xml
Normal file
20
app/src/main/res/drawable/ic_app_shortcut_search.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="176dp"
|
||||
android:height="176dp"
|
||||
android:viewportWidth="176"
|
||||
android:viewportHeight="176">
|
||||
|
||||
<group
|
||||
android:pivotX="88"
|
||||
android:pivotY="88"
|
||||
android:scaleX="0.916"
|
||||
android:scaleY="0.916"
|
||||
android:translateX="-8"
|
||||
android:translateY="-8">
|
||||
<path
|
||||
android:name="ic_app_shortcut_search_ic"
|
||||
android:fillColor="#000"
|
||||
android:pathData="M104.333 97.3333H100.647L99.34 96.0733C103.913 90.7533 106.667 83.8467 106.667 76.3333C106.667 59.58 93.0867 46 76.3333 46C59.58 46 46 59.58 46 76.3333C46 93.0867 59.58 106.667 76.3333 106.667C83.8467 106.667 90.7533 103.913 96.0733 99.34L97.3333 100.647V104.333L120.667 127.62L127.62 120.667L104.333 97.3333V97.3333ZM76.3333 97.3333C64.7133 97.3333 55.3333 87.9533 55.3333 76.3333C55.3333 64.7133 64.7133 55.3333 76.3333 55.3333C87.9533 55.3333 97.3333 64.7133 97.3333 76.3333C97.3333 87.9533 87.9533 97.3333 76.3333 97.3333Z" />
|
||||
</group>
|
||||
</vector>
|
14
app/src/main/res/drawable/ic_artist_selected_white_24dp.xml
Normal file
14
app/src/main/res/drawable/ic_artist_selected_white_24dp.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M 10 4 C 7.79 4 6 5.79 6 8 C 6 10.21 7.79 12 10 12 C 12.21 12 14 10.21 14 8 C 14 5.79 12.21 4 10 4 z M 10 14 C 7.33 14 2 15.34 2 18 L 2 19 C 2 19.55 2.45 20 3 20 L 12.007812 20 A 5 5 0 0 1 11 17 A 5 5 0 0 1 11.867188 14.1875 C 11.186145 14.077427 10.532166 14 10 14 z" />
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M 19 8 A 2 2 0 0 0 17 10 L 17 14.173828 C 16.678959 14.059508 16.340787 14.000724 16 14 C 14.343146 14 13 15.343146 13 17 C 13 18.656854 14.343146 20 16 20 C 17.656854 20 19 18.656854 19 17 L 19 10 L 21 10 C 21.554 10 22 9.554 22 9 C 22 8.446 21.554 8 21 8 L 19 8 z" />
|
||||
</vector>
|
|
@ -4,11 +4,10 @@
|
|||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M 10 4 C 7.79 4 6 5.79 6 8 C 6 10.21 7.79 12 10 12 C 12.21 12 14 10.21 14 8 C 14 5.79 12.21 4 10 4 z M 10 14 C 7.33 14 2 15.34 2 18 L 2 19 C 2 19.55 2.45 20 3 20 L 12.007812 20 A 5 5 0 0 1 11 17 A 5 5 0 0 1 11.867188 14.1875 C 11.186145 14.077427 10.532166 14 10 14 z" />
|
||||
android:pathData="M 10 4 C 7.789999 4 6 5.79 6 8 C 6 10.21 7.789999 12 10 12 C 12.21 12 14 10.21 14 8 C 14 5.79 12.21 4 10 4 z M 10 6 C 11.1 6 12 6.9 12 8 C 12 9.1 11.1 10 10 10 C 8.899999 10 8 9.1 8 8 C 8 6.9 8.899999 6 10 6 z M 10 14 C 7.329999 14 2 15.34 2 18 L 2 20 L 13.007812 20 A 5 5 0 0 1 12.105469 18 L 4 18 C 4.23 17.28 7.309999 16 10 16 C 10.681642 16 11.388828 16.082448 12.068359 16.216797 A 5 5 0 0 1 12.771484 14.34375 C 11.755351 14.12326 10.766662 14 10 14 z" />
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M 19 8 A 2 2 0 0 0 17 10 L 17 14.173828 C 16.678959 14.059508 16.340787 14.000724 16 14 C 14.343146 14 13 15.343146 13 17 C 13 18.656854 14.343146 20 16 20 C 17.656854 20 19 18.656854 19 17 L 19 10 L 21 10 C 21.554 10 22 9.554 22 9 C 22 8.446 21.554 8 21 8 L 19 8 z" />
|
||||
android:pathData="M 18 8 L 18 10 L 18 14.173828 A 3 3 0 0 0 17 14 A 3 3 0 0 0 14 17 A 3 3 0 0 0 17 20 A 3 3 0 0 0 20 17 L 20 10 L 22 10 L 22 8 L 20 8 L 18 8 z M 17 16 A 1 1 0 0 1 18 17 A 1 1 0 0 1 17 18 A 1 1 0 0 1 16 17 A 1 1 0 0 1 17 16 z" />
|
||||
</vector>
|
|
@ -6,5 +6,5 @@
|
|||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M12 5v8.55c-0.94-0.54-2.1-0.75-3.33-0.32-1.34 0.48 -2.37 1.67-2.61 3.07-0.46 2.74 1.86 5.08 4.59 4.65 1.96-0.31 3.35-2.11 3.35-4.1V7h2c1.1 0 2-0.9 2-2s-0.9-2-2-2h-2c-1.1 0-2 0.9-2 2z" />
|
||||
android:pathData="M12 3v10.55c-0.59-0.34-1.27-0.55-2-0.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6zm-2 16c-1.1 0-2-0.9-2-2s0.9-2 2-2 2 0.9 2 2-0.9 2-2 2z" />
|
||||
</vector>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M12 3v9.28c-0.47-0.17-0.97-0.28-1.5-0.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7z" />
|
||||
</vector>
|
|
@ -5,7 +5,8 @@
|
|||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M19 8h-1.81c-0.45-0.78-1.07-1.45-1.82-1.96l0.93-0.93c0.39-0.39 0.39 -1.02 0-1.41-0.39-0.39-1.02-0.39-1.41 0l-1.47 1.47C12.96 5.06 12.49 5 12 5s-0.96 0.06 -1.41 0.17 L9.11 3.7c-0.39-0.39-1.02-0.39-1.41 0-0.39 0.39 -0.39 1.02 0 1.41l0.92 0.93 C7.88 6.55 7.26 7.22 6.81 8H5c-0.55 0-1 0.45-1 1s0.45 1 1 1h1.09c-0.05 0.33 -0.09 0.66 -0.09 1v1H5c-0.55 0-1 0.45-1 1s0.45 1 1 1h1v1c0 0.34 0.04 0.67 0.09 1H5c-0.55 0-1 0.45-1 1s0.45 1 1 1h1.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H19c0.55 0 1-0.45 1-1s-0.45-1-1-1h-1.09c0.05-0.33 0.09 -0.66 0.09 -1v-1h1c0.55 0 1-0.45 1-1s-0.45-1-1-1h-1v-1c0-0.34-0.04-0.67-0.09-1H19c0.55 0 1-0.45 1-1s-0.45-1-1-1zm-6 8h-2c-0.55 0-1-0.45-1-1s0.45-1 1-1h2c0.55 0 1 0.45 1 1s-0.45 1-1 1zm0-4h-2c-0.55 0-1-0.45-1-1s0.45-1 1-1h2c0.55 0 1 0.45 1 1s-0.45 1-1 1z" />
|
||||
android:pathData="M20 8h-2.81c-0.45-0.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5s-0.96 0.06 -1.41 0.17 L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-0.05 0.33 -0.09 0.66 -0.09 1v1H4v2h2v1c0 0.34 0.04 0.67 0.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c0.05-0.33 0.09 -0.66 0.09 -1v-1h2v-2h-2v-1c0-0.34-0.04-0.67-0.09-1H20V8zm-4 4v3c0 0.22-0.03 0.47 -0.07 0.7 l-0.1 0.65 -0.37 0.65 c-0.72 1.24-2.04 2-3.46 2s-2.74-0.77-3.46-2l-0.37-0.64-0.1-0.65C8.03 15.48 8 15.23 8 15v-4c0-0.23 0.03 -0.48 0.07 -0.7l0.1-0.65 0.37 -0.65c0.3-0.52 0.72 -0.97 1.21-1.31l0.57-0.39 0.74 -0.18c0.31-0.08 0.63 -0.12 0.94 -0.12 0.32 0 0.63 0.04 0.95 0.12 l0.68 0.16 0.61 0.42 c0.5 0.34 0.91 0.78 1.21 1.31l0.38 0.65 0.1 0.65 c0.04 0.22 0.07 0.47 0.07 0.69 v1zm-6 2h4v2h-4zm0-4h4v2h-4z" />
|
||||
</vector>
|
|
@ -7,5 +7,5 @@
|
|||
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M20 6h-2.18c0.11-0.31 0.18 -0.65 0.18 -1 0-1.66-1.34-3-3-3-1.05 0-1.96 0.54 -2.5 1.35l-0.5 0.67 -0.5-0.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 0.35 0.07 0.69 0.18 1H4c-1.11 0-1.99 0.89 -1.99 2L2 19c0 1.11 0.89 2 2 2h16c1.11 0 2-0.89 2-2V8c0-1.11-0.89-2-2-2zm-5-2c0.55 0 1 0.45 1 1s-0.45 1-1 1-1-0.45-1-1 0.45-1 1-1zM9 4c0.55 0 1 0.45 1 1s-0.45 1-1 1-1-0.45-1-1 0.45-1 1-1zm11 15H4v-2h16v2zm0-5H4V9c0-0.55 0.45 -1 1-1h4.08L7.6 10.02c-0.33 0.45 -0.23 1.08 0.22 1.4 0.44 0.32 1.07 0.22 1.39-0.22L12 7.4l2.79 3.8c0.32 0.44 0.95 0.54 1.39 0.22 0.45-0.32 0.55 -0.95 0.22 -1.4L14.92 8H19c0.55 0 1 0.45 1 1v5z" />
|
||||
android:pathData="M20 6h-2.18c0.11-0.31 0.18 -0.65 0.18 -1 0-1.66-1.34-3-3-3-1.05 0-1.96 0.54 -2.5 1.35l-0.5 0.67 -0.5-0.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 0.35 0.07 0.69 0.18 1H4c-1.11 0-1.99 0.89 -1.99 2L2 19c0 1.11 0.89 2 2 2h16c1.11 0 2-0.89 2-2V8c0-1.11-0.89-2-2-2zm-5-2c0.55 0 1 0.45 1 1s-0.45 1-1 1-1-0.45-1-1 0.45-1 1-1zM9 4c0.55 0 1 0.45 1 1s-0.45 1-1 1-1-0.45-1-1 0.45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 12 7.4l3.38 4.6L17 10.83 14.92 8H20v6z" />
|
||||
</vector>
|
|
@ -1,9 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M5,13h14v-2L5,11v2zM3,17h14v-2L3,15v2zM7,7v2h14L21,7L7,7z"/>
|
||||
</vector>
|
||||
android:pathData="M5 13h14v-2H5v2zm-2 4h14v-2H3v2zM7 7v2h14V7H7z" />
|
||||
</vector>
|
|
@ -1,9 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:width="24dp">
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M18.3,5.71L18.3,5.71c-0.39,-0.39 -1.02,-0.39 -1.41,0L12,10.59L7.11,5.7c-0.39,-0.39 -1.02,-0.39 -1.41,0l0,0c-0.39,0.39 -0.39,1.02 0,1.41L10.59,12L5.7,16.89c-0.39,0.39 -0.39,1.02 0,1.41h0c0.39,0.39 1.02,0.39 1.41,0L12,13.41l4.89,4.89c0.39,0.39 1.02,0.39 1.41,0l0,0c0.39,-0.39 0.39,-1.02 0,-1.41L13.41,12l4.89,-4.89C18.68,6.73 18.68,6.09 18.3,5.71z"/>
|
||||
</vector>
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
|
||||
</vector>
|
|
@ -5,7 +5,8 @@
|
|||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M6 19c0 1.1 0.9 2 2 2h8c1.1 0 2-0.9 2-2V9c0-1.1-0.9-2-2-2H8c-1.1 0-2 0.9-2 2v10zM18 4h-2.5l-0.71-0.71c-0.18-0.18-0.44-0.29-0.7-0.29H9.91c-0.26 0-0.52 0.11 -0.7 0.29 L8.5 4H6c-0.55 0-1 0.45-1 1s0.45 1 1 1h12c0.55 0 1-0.45 1-1s-0.45-1-1-1z" />
|
||||
android:pathData="M16 9v10H8V9h8m-1.5-6h-5l-1 1H5v2h14V4h-3.5l-1-1zM18 7H6v12c0 1.1 0.9 2 2 2h8c1.1 0 2-0.9 2-2V7z" />
|
||||
</vector>
|
9
app/src/main/res/drawable/ic_disc_full_black_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_disc_full_black_24dp.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M20,16h2v-2h-2v2zM20,7v5h2L22,7h-2zM10,4c-4.42,0 -8,3.58 -8,8s3.58,8 8,8 8,-3.58 8,-8 -3.58,-8 -8,-8zM10,14c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z"/>
|
||||
</vector>
|
|
@ -1,9 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M3,17.46v3.04c0,0.28 0.22,0.5 0.5,0.5h3.04c0.13,0 0.26,-0.05 0.35,-0.15L17.81,9.94l-3.75,-3.75L3.15,17.1c-0.1,0.1 -0.15,0.22 -0.15,0.36zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z" />
|
||||
</vector>
|
||||
android:pathData="M14.06 9.02l0.92 0.92 L5.92 19H5v-0.92l9.06-9.06M17.66 3c-0.25 0-0.51 0.1 -0.7 0.29 l-1.83 1.83 3.75 3.75 1.83-1.83c0.39-0.39 0.39 -1.02 0-1.41l-2.34-2.34c-0.2-0.2-0.45-0.29-0.71-0.29zm-3.6 3.19L3 17.25V21h3.75L17.81 9.94l-3.75-3.75z" />
|
||||
</vector>
|
|
@ -1,9 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M10,20h4L14,4h-4v16zM4,20h4v-8L4,12v8zM16,9v11h4L20,9h-4z"/>
|
||||
</vector>
|
||||
android:pathData="M10 20h4V4h-4v16zm-6 0h4v-8H4v8zM16 9v11h4V9h-4z" />
|
||||
</vector>
|
|
@ -1,9 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M19.66,3.99c-2.64,-1.8 -5.9,-0.96 -7.66,1.1c-1.76,-2.06 -5.02,-2.91 -7.66,-1.1C2.94,4.95 2.06,6.57 2,8.28c-0.14,3.88 3.3,6.99 8.55,11.76l0.1,0.09c0.76,0.69 1.93,0.69 2.69,-0.01l0.11,-0.1c5.25,-4.76 8.68,-7.87 8.55,-11.75C21.94,6.57 21.06,4.95 19.66,3.99zM12.1,18.55l-0.1,0.1l-0.1,-0.1C7.14,14.24 4,11.39 4,8.5C4,6.5 5.5,5 7.5,5c1.54,0 3.04,0.99 3.57,2.36h1.87C13.46,5.99 14.96,5 16.5,5c2,0 3.5,1.5 3.5,3.5C20,11.39 16.86,14.24 12.1,18.55z"/>
|
||||
</vector>
|
||||
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M16.5 3c-1.74 0-3.41 0.81 -4.5 2.09C10.91 3.81 9.24 3 7.5 3 4.42 3 2 5.42 2 8.5c0 3.78 3.4 6.86 8.55 11.54L12 21.35l1.45-1.32C18.6 15.36 22 12.28 22 8.5 22 5.42 19.58 3 16.5 3zm-4.4 15.55l-0.1 0.1 -0.1-0.1C7.14 14.24 4 11.39 4 8.5 4 6.5 5.5 5 7.5 5c1.54 0 3.04 0.99 3.57 2.36h1.87C13.46 5.99 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5 0 2.89-3.14 5.74-7.9 10.05z" />
|
||||
</vector>
|
|
@ -1,9 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M13.35,20.13c-0.76,0.69 -1.93,0.69 -2.69,-0.01l-0.11,-0.1C5.3,15.27 1.87,12.16 2,8.28c0.06,-1.7 0.93,-3.33 2.34,-4.29c2.64,-1.8 5.9,-0.96 7.66,1.1c1.76,-2.06 5.02,-2.91 7.66,-1.1c1.41,0.96 2.28,2.59 2.34,4.29c0.14,3.88 -3.3,6.99 -8.55,11.76L13.35,20.13z"/>
|
||||
</vector>
|
||||
|
||||
<path
|
||||
android:fillColor="@color/md_white_1000"
|
||||
android:pathData="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41 0.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
|
||||
</vector>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue