Merge pull request #73 from h4h13/kotlin

Kotlin
This commit is contained in:
Hemanth S 2018-12-10 13:07:24 +05:30 committed by GitHub
commit 903f563c66
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
109 changed files with 3592 additions and 1545 deletions

File diff suppressed because one or more lines are too long

View file

@ -13,12 +13,12 @@ android {
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
applicationId "code.name.monkey.retromusic" applicationId "code.name.monkey.retromusic"
versionCode 255 versionCode 260
versionName '2.2.100' versionName '3.0.010'
multiDexEnabled true multiDexEnabled true
buildConfigField("String", "GOOGLE_PLAY_LICENSE_KEY", "\"${getProperty(getProperties('../public.properties'), 'GOOGLE_PLAY_LICENSE_KEY')}\"") buildConfigField("String", "GOOGLE_PLAY_LICENSING_KEY", "\"${getProperty(getProperties('../public.properties'), 'GOOGLE_PLAY_LICENSE_KEY')}\"")
} }
signingConfigs { signingConfigs {
release { release {
@ -149,7 +149,8 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:2.1.5' implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:2.1.5'
implementation 'com.github.jetradarmobile:android-snowfall:1.2.0'
implementation 'com.github.javiersantos:PiracyChecker:1.2.4'
} }
repositories { repositories {
mavenCentral() mavenCentral()

View file

@ -112,7 +112,7 @@
<activity android:name=".ui.activities.SupportDevelopmentActivity" /> <activity android:name=".ui.activities.SupportDevelopmentActivity" />
<activity android:name=".ui.activities.GenreDetailsActivity" /> <activity android:name=".ui.activities.GenreDetailsActivity" />
<activity android:name=".ui.activities.LicenseActivity" /> <activity android:name=".ui.activities.LicenseActivity" />
<activity android:name=".ui.activities.ProVersionActivity" /> <activity android:name=".ui.activities.PurchaseActivity" />
<activity android:name=".ui.activities.EqualizerActivity" /> <activity android:name=".ui.activities.EqualizerActivity" />
<activity android:name=".ui.activities.ErrorHandlerActivity" /> <activity android:name=".ui.activities.ErrorHandlerActivity" />
<activity android:name=".ui.activities.WhatsNewActivity" /> <activity android:name=".ui.activities.WhatsNewActivity" />
@ -122,10 +122,13 @@
android:launchMode="singleInstance" android:launchMode="singleInstance"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/AppTheme.ExpandedCastController" /> android:theme="@style/AppTheme.ExpandedCastController" />
<activity android:name=".ui.activities.bugreport.BugReportActivity" />
<activity android:name=".ui.activities.LockScreenActivity" />
<service <service
android:name=".service.MusicService" android:name=".service.MusicService"
android:enabled="true" /> android:enabled="true" />
<service <service
android:name=".service.WearBrowserService" android:name=".service.WearBrowserService"
android:exported="true"> android:exported="true">
@ -134,27 +137,11 @@
</intent-filter> </intent-filter>
</service> </service>
<!-- <service --> <receiver android:name=".service.MediaButtonIntentReceiver">
<!-- android:name=".service.daydream.RetroMusicAlbums" -->
<!-- android:exported="true" -->
<!-- android:label="Retro Music Albums" -->
<!-- android:permission="android.permission.BIND_DREAM_SERVICE"> -->
<!-- <intent-filter> -->
<!-- <action android:name="android.service.dreams.DreamService" /> -->
<!-- <category android:name="android.intent.category.DEFAULT" /> -->
<!-- </intent-filter> -->
<!-- </service> -->
<!-- Widgets -->
<!--
<receiver
android:name=".headset.HeadsetReceiver"
android:enabled="true"
android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.HEADSET_PLUG" /> <action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter> </intent-filter>
</receiver> </receiver>
-->
<meta-data <meta-data
@ -173,12 +160,6 @@
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME" android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="code.name.monkey.retromusic.cast.CastOptionsProvider" /> android:value="code.name.monkey.retromusic.cast.CastOptionsProvider" />
<!--
<meta-data
android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc" />
-->
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}" android:authorities="${applicationId}"
@ -189,6 +170,73 @@
android:resource="@xml/provider_paths" /> android:resource="@xml/provider_paths" />
</provider> </provider>
</application> <receiver android:name=".appwidgets.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
<receiver
android:name=".appwidgets.AppWidgetBig"
android:exported="false"
android:label="@string/app_widget_big_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/app_widget_big_info" />
</receiver>
<receiver
android:name=".appwidgets.AppWidgetClassic"
android:exported="false"
android:label="@string/app_widget_classic_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/app_widget_classic_info" />
</receiver>
<receiver
android:name=".appwidgets.AppWidgetSmall"
android:exported="false"
android:label="@string/app_widget_small_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/app_widget_small_info" />
</receiver>
<receiver
android:name=".appwidgets.AppWidgetText"
android:exported="false"
android:label="@string/app_widget_text_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/app_widget_text" />
</receiver>
<receiver
android:name=".appwidgets.AppWidgetCard"
android:exported="false"
android:label="@string/app_widget_card_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/app_widget_card_info" />
</receiver>
</application>
</manifest> </manifest>

View file

@ -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 2.2.100</h3> <ul style="line-height:150%"> <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>Click toolbar (Library) to open options</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> <h3>Version 3.0.00</h3> <ul style="line-height:150%"> <li>Converted app to kotlin</li> <li>Good old side navigation bar for options</li> <h3>Version 2.2.100</h3> <ul style="line-height:150%"> <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>

View file

@ -1,8 +1,11 @@
package code.name.monkey.retromusic package code.name.monkey.retromusic
import android.content.Context import android.content.Context
import android.widget.Toast
import androidx.multidex.MultiDexApplication import androidx.multidex.MultiDexApplication
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
import com.anjlab.android.iab.v3.BillingProcessor import com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.TransactionDetails import com.anjlab.android.iab.v3.TransactionDetails
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
@ -25,13 +28,17 @@ class App : MultiDexApplication() {
.commit() .commit()
} }
if (VersionUtils.hasNougatMR())
DynamicShortcutManager(this).initDynamicShortcuts()
// automatically restores purchases // automatically restores purchases
billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSE_KEY, billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSING_KEY,
object : BillingProcessor.IBillingHandler { object : BillingProcessor.IBillingHandler {
override fun onProductPurchased(productId: String, details: TransactionDetails?) {} override fun onProductPurchased(productId: String, details: TransactionDetails?) {}
override fun onPurchaseHistoryRestored() { override fun onPurchaseHistoryRestored() {
//Toast.makeText(App.this, R.string.restored_previous_purchase_please_restart, Toast.LENGTH_LONG).show(); Toast.makeText(this@App, R.string.restored_previous_purchase_please_restart, Toast.LENGTH_LONG).show();
} }
override fun onBillingError(errorCode: Int, error: Throwable?) {} override fun onBillingError(errorCode: Int, error: Throwable?) {}

View file

@ -10,7 +10,7 @@ import code.name.monkey.retromusic.util.schedulers.SchedulerProvider
object Injection { object Injection {
fun provideRepository(): Repository { fun provideRepository(): Repository {
return RepositoryImpl.getInstance() return RepositoryImpl.instance
} }
fun provideSchedulerProvider(): BaseSchedulerProvider { fun provideSchedulerProvider(): BaseSchedulerProvider {

View file

@ -0,0 +1,70 @@
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;
}
}

View file

@ -0,0 +1,77 @@
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);
}
}

View file

@ -0,0 +1,63 @@
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()
));
}
}

View file

@ -0,0 +1,50 @@
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;
}
}

View file

@ -0,0 +1,34 @@
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();
}
}

View file

@ -0,0 +1,35 @@
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();
}
}

View file

@ -0,0 +1,35 @@
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();
}
}

View file

@ -0,0 +1,167 @@
package code.name.monkey.retromusic.appwidgets
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.text.TextUtils
import android.view.View
import android.widget.RemoteViews
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target
class AppWidgetBig : BaseAppWidget() {
private var target: Target<Bitmap>? = null // for cancellation
/**
* Initialize given widgets to default state, where we launch Music on default click and hide
* actions if service not running.
*/
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName,
R.layout.app_widget_big)
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.createBitmap(
RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp,
MaterialValueHelper.getPrimaryTextColor(context, false))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp,
MaterialValueHelper.getPrimaryTextColor(context, false))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_24dp,
MaterialValueHelper.getPrimaryTextColor(context, false))!!, 1f))
linkButtons(context, appWidgetView)
pushUpdate(context, appWidgetIds, appWidgetView)
}
/**
* Update all active widget instances by pushing changes
*/
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName,
R.layout.app_widget_big)
val isPlaying = service.isPlaying
val song = service.currentSong
// Set the titles and artwork
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
} else {
appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
appWidgetView.setTextViewText(R.id.title, song.title)
appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song))
}
// Set correct drawable for pause state
val playPauseRes = if (isPlaying) R.drawable.ic_pause_white_24dp else R.drawable.ic_play_arrow_white_24dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.createBitmap(
RetroUtil.getTintedVectorDrawable(service, playPauseRes,
MaterialValueHelper.getPrimaryTextColor(service, false))!!, 1f))
// Set prev/next button drawables
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp,
MaterialValueHelper.getPrimaryTextColor(service, false))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp,
MaterialValueHelper.getPrimaryTextColor(service, false))!!, 1f))
// Link actions buttons to intents
linkButtons(service, appWidgetView)
// Load the album cover async and push the update on completion
val p = RetroUtil.getScreenSize(service)
val widgetImageSize = Math.min(p.x, p.y)
val appContext = service.applicationContext
service.runOnUiThread {
if (target != null) {
Glide.clear(target!!)
}
target = SongGlideRequest.Builder.from(Glide.with(appContext), song)
.checkIgnoreMediaStore(appContext)
.asBitmap().build()
.into(object : SimpleTarget<Bitmap>(widgetImageSize, widgetImageSize) {
override fun onResourceReady(resource: Bitmap,
glideAnimation: GlideAnimation<in Bitmap>) {
update(resource)
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
update(null)
}
private fun update(bitmap: Bitmap?) {
if (bitmap == null) {
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
} else {
appWidgetView.setImageViewBitmap(R.id.image, bitmap)
}
pushUpdate(appContext, appWidgetIds, appWidgetView)
}
})
}
}
/**
* Link up various button actions using [PendingIntent].
*/
private fun linkButtons(context: Context, views: RemoteViews) {
val action = Intent(context, MainActivity::class.java).putExtra("expand", true)
var pendingIntent: PendingIntent
val serviceName = ComponentName(context, MusicService::class.java)
// Home
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
pendingIntent = PendingIntent.getActivity(context, 0, action, 0)
views.setOnClickPendingIntent(R.id.clickable_area, pendingIntent)
// Previous track
pendingIntent = buildPendingIntent(context, Constants.ACTION_REWIND, serviceName)
views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
// Play and pause
pendingIntent = buildPendingIntent(context, Constants.ACTION_TOGGLE_PAUSE, serviceName)
views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
// Next track
pendingIntent = buildPendingIntent(context, Constants.ACTION_SKIP, serviceName)
views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
}
companion object {
const val NAME: String = "app_widget_big"
private var mInstance: AppWidgetBig? = null
val instance: AppWidgetBig
@Synchronized get() {
if (mInstance == null) {
mInstance = AppWidgetBig()
}
return mInstance!!
}
}
}

View file

@ -0,0 +1,182 @@
package code.name.monkey.retromusic.appwidgets
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.text.TextUtils
import android.view.View
import android.widget.RemoteViews
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target
class AppWidgetCard : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
/**
* Initialize given widgets to default state, where we launch Music on default click and hide
* actions if service not running.
*/
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName,
R.layout.app_widget_card)
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp,
MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp,
MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_24dp,
MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
linkButtons(context, appWidgetView)
pushUpdate(context, appWidgetIds, appWidgetView)
}
/**
* Update all active widget instances by pushing changes
*/
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName,
R.layout.app_widget_card)
val isPlaying = service.isPlaying
val song = service.currentSong
// Set the titles and artwork
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
} else {
appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
appWidgetView.setTextViewText(R.id.title, song.title)
appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song))
}
// Set correct drawable for pause state
val playPauseRes = if (isPlaying) R.drawable.ic_pause_white_24dp else R.drawable.ic_play_arrow_white_24dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(service, playPauseRes,
MaterialValueHelper.getSecondaryTextColor(service, true))!!, 1f))
// Set prev/next button drawables
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp,
MaterialValueHelper.getSecondaryTextColor(service, true))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp,
MaterialValueHelper.getSecondaryTextColor(service, true))!!, 1f))
// Link actions buttons to intents
linkButtons(service, appWidgetView)
if (imageSize == 0) {
imageSize = service.resources.getDimensionPixelSize(R.dimen.app_widget_card_image_size)
}
if (cardRadius == 0f) {
cardRadius = service.resources.getDimension(R.dimen.app_widget_card_radius)
}
// Load the album cover async and push the update on completion
service.runOnUiThread {
if (target != null) {
Glide.clear(target!!)
}
target = SongGlideRequest.Builder.from(Glide.with(service), song)
.checkIgnoreMediaStore(service)
.generatePalette(service).build()
.centerCrop()
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
val palette = resource.palette
update(resource.bitmap, palette.getVibrantColor(palette
.getMutedColor(MaterialValueHelper.getSecondaryTextColor(service, true))))
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
}
private fun update(bitmap: Bitmap?, color: Int) {
// Set correct drawable for pause state
val playPauseRest = if (isPlaying) R.drawable.ic_pause_white_24dp
else
R.drawable.ic_play_arrow_white_24dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.createBitmap(RetroUtil.getTintedVectorDrawable(service, playPauseRest, color)!!, 1f))
// Set prev/next button drawables
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, color)!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color)!!, 1f))
val image = getAlbumArtDrawable(service.resources, bitmap)
val roundedBitmap = BaseAppWidget.Companion.createRoundedBitmap(image, imageSize, imageSize, cardRadius, 0f, cardRadius, 0f)
appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
pushUpdate(service, appWidgetIds, appWidgetView)
}
})
}
}
/**
* Link up various button actions using [PendingIntent].
*/
private fun linkButtons(context: Context, views: RemoteViews) {
val action: Intent = Intent(context, MainActivity::class.java).putExtra("expand", true)
var pendingIntent: PendingIntent
val serviceName = ComponentName(context, MusicService::class.java)
// Home
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
pendingIntent = PendingIntent.getActivity(context, 0, action, 0)
views.setOnClickPendingIntent(R.id.image, pendingIntent)
views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
// Previous track
pendingIntent = buildPendingIntent(context, Constants.ACTION_REWIND, serviceName)
views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
// Play and pause
pendingIntent = buildPendingIntent(context, Constants.ACTION_TOGGLE_PAUSE, serviceName)
views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
// Next track
pendingIntent = buildPendingIntent(context, Constants.ACTION_SKIP, serviceName)
views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
}
companion object {
const val NAME = "app_widget_card"
private var mInstance: AppWidgetCard? = null
private var imageSize = 0
private var cardRadius = 0f
val instance: AppWidgetCard
@Synchronized get() {
if (mInstance == null) {
mInstance = AppWidgetCard()
}
return mInstance!!
}
}
}

View file

@ -0,0 +1,166 @@
package code.name.monkey.retromusic.appwidgets
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.text.TextUtils
import android.view.View
import android.widget.RemoteViews
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target
class AppWidgetClassic : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
/**
* Initialize given widgets to default state, where we launch Music on default click and hide
* actions if service not running.
*/
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_classic)
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.Companion.createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.Companion.createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
linkButtons(context, appWidgetView)
pushUpdate(context, appWidgetIds, appWidgetView)
}
/**
* Update all active widget instances by pushing changes
*/
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName,
R.layout.app_widget_classic)
val isPlaying = service.isPlaying
val song = service.currentSong
// Set the titles and artwork
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
} else {
appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
appWidgetView.setTextViewText(R.id.title, song.title)
appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song))
}
// Link actions buttons to intents
linkButtons(service, appWidgetView)
if (imageSize == 0) {
imageSize = service.resources
.getDimensionPixelSize(R.dimen.app_widget_classic_image_size)
}
if (cardRadius == 0f) {
cardRadius = service.resources.getDimension(R.dimen.app_widget_card_radius)
}
// Load the album cover async and push the update on completion
val appContext = service.applicationContext
service.runOnUiThread {
if (target != null) {
Glide.clear(target!!)
}
target = SongGlideRequest.Builder.from(Glide.with(appContext), song)
.checkIgnoreMediaStore(appContext)
.generatePalette(service).build()
.centerCrop()
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
val palette = resource.palette
update(resource.bitmap, palette.getVibrantColor(palette.getMutedColor(MaterialValueHelper.getSecondaryTextColor(appContext, true))))
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(appContext, true))
}
private fun update(bitmap: Bitmap?, color: Int) {
// Set correct drawable for pause state
val playPauseRes = if (isPlaying)
R.drawable.ic_pause_white_24dp
else
R.drawable.ic_play_arrow_white_24dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause,
BaseAppWidget.createBitmap(RetroUtil.getTintedVectorDrawable(service, playPauseRes, color)!!, 1f))
// Set prev/next button drawables
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, color)!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color)!!, 1f))
val image = getAlbumArtDrawable(service.resources, bitmap)
val roundedBitmap = BaseAppWidget.createRoundedBitmap(image, imageSize, imageSize,
cardRadius, 0f, cardRadius, 0f)
appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
pushUpdate(appContext, appWidgetIds, appWidgetView)
}
})
}
}
/**
* Link up various button actions using [PendingIntent].
*/
private fun linkButtons(context: Context, views: RemoteViews) {
val action = Intent(context, MainActivity::class.java).putExtra("expand", true)
var pendingIntent: PendingIntent
val serviceName = ComponentName(context, MusicService::class.java)
// Home
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
pendingIntent = PendingIntent.getActivity(context, 0, action, 0)
views.setOnClickPendingIntent(R.id.image, pendingIntent)
views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
// Previous track
pendingIntent = buildPendingIntent(context, Constants.ACTION_REWIND, serviceName)
views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
// Play and pause
pendingIntent = buildPendingIntent(context, Constants.ACTION_TOGGLE_PAUSE, serviceName)
views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
// Next track
pendingIntent = buildPendingIntent(context, Constants.ACTION_SKIP, serviceName)
views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
}
companion object {
const val NAME = "app_widget_classic"
private var mInstance: AppWidgetClassic? = null
private var imageSize = 0
private var cardRadius = 0f
val instance: AppWidgetClassic
@Synchronized get() {
if (mInstance == null) {
mInstance = AppWidgetClassic()
}
return mInstance!!
}
}
}

View file

@ -0,0 +1,170 @@
package code.name.monkey.retromusic.appwidgets
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.text.TextUtils
import android.view.View
import android.widget.RemoteViews
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target
class AppWidgetSmall : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
/**
* Initialize given widgets to default state, where we launch Music on default click and hide
* actions if service not running.
*/
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_small)
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_24dp, MaterialValueHelper.getSecondaryTextColor(context, true))!!, 1f))
linkButtons(context, appWidgetView)
pushUpdate(context, appWidgetIds, appWidgetView)
}
/**
* Update all active widget instances by pushing changes
*/
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName,
R.layout.app_widget_small)
val isPlaying = service.isPlaying
val song = service.currentSong
// Set the titles and artwork
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
} else {
if (TextUtils.isEmpty(song.title) || TextUtils.isEmpty(song.artistName)) {
appWidgetView.setTextViewText(R.id.text_separator, "")
} else {
appWidgetView.setTextViewText(R.id.text_separator, "")
}
appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
appWidgetView.setTextViewText(R.id.title, song.title)
appWidgetView.setTextViewText(R.id.text, song.artistName)
}
// Link actions buttons to intents
linkButtons(service, appWidgetView)
if (imageSize == 0) {
imageSize = service.resources.getDimensionPixelSize(R.dimen.app_widget_small_image_size)
}
if (cardRadius == 0f) {
cardRadius = service.resources.getDimension(R.dimen.app_widget_card_radius)
}
// Load the album cover async and push the update on completion
val appContext = service.applicationContext
service.runOnUiThread {
if (target != null) {
Glide.clear(target!!)
}
target = SongGlideRequest.Builder.from(Glide.with(appContext), song)
.checkIgnoreMediaStore(appContext)
.generatePalette(service).build()
.centerCrop()
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
val palette = resource.palette
update(resource.bitmap, palette.getVibrantColor(palette
.getMutedColor(MaterialValueHelper.getSecondaryTextColor(appContext, true))))
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(appContext, true))
}
private fun update(bitmap: Bitmap?, color: Int) {
// Set correct drawable for pause state
val playPauseRes = if (isPlaying)
R.drawable.ic_pause_white_24dp
else
R.drawable.ic_play_arrow_white_24dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.Companion.createBitmap(RetroUtil.getTintedVectorDrawable(service, playPauseRes, color)!!, 1f))
// Set prev/next button drawables
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.Companion.createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, color)!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color)!!, 1f))
val image = getAlbumArtDrawable(service.resources, bitmap)
val roundedBitmap = BaseAppWidget.createRoundedBitmap(image, imageSize, imageSize, cardRadius, 0f, 0f, 0f)
appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
pushUpdate(appContext, appWidgetIds, appWidgetView)
}
})
}
}
/**
* Link up various button actions using [PendingIntent].
*/
private fun linkButtons(context: Context, views: RemoteViews) {
val action = Intent(context, MainActivity::class.java).putExtra("expand", true)
var pendingIntent: PendingIntent
val serviceName = ComponentName(context, MusicService::class.java)
// Home
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
pendingIntent = PendingIntent.getActivity(context, 0, action, 0)
views.setOnClickPendingIntent(R.id.image, pendingIntent)
views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
// Previous track
pendingIntent = buildPendingIntent(context, Constants.ACTION_REWIND, serviceName)
views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
// Play and pause
pendingIntent = buildPendingIntent(context, Constants.ACTION_TOGGLE_PAUSE, serviceName)
views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
// Next track
pendingIntent = buildPendingIntent(context, Constants.ACTION_SKIP, serviceName)
views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
}
companion object {
const val NAME:String = "app_widget_small"
private var mInstance: AppWidgetSmall? = null
private var imageSize = 0
private var cardRadius = 0f
val instance: AppWidgetSmall
@Synchronized get() {
if (mInstance == null) {
mInstance = AppWidgetSmall()
}
return mInstance!!
}
}
}

View file

@ -0,0 +1,106 @@
package code.name.monkey.retromusic.appwidgets
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.text.TextUtils
import android.view.View
import android.widget.RemoteViews
import androidx.core.content.ContextCompat
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.App.Companion.context
import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.MainActivity
import code.name.monkey.retromusic.util.RetroUtil
class AppWidgetText : BaseAppWidget() {
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_text)
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp, ContextCompat.getColor(context, R.color.md_white_1000)), 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp, ContextCompat.getColor(context, R.color.md_white_1000)), 1f))
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.createBitmap(RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_24dp, ContextCompat.getColor(context, R.color.md_white_1000)), 1f))
appWidgetView.setTextColor(R.id.title, ContextCompat.getColor(context, R.color.md_white_1000))
appWidgetView.setTextColor(R.id.text, ContextCompat.getColor(context, R.color.md_white_1000))
linkButtons(context, appWidgetView)
pushUpdate(context, appWidgetIds, appWidgetView)
}
/**
* Link up various button actions using [PendingIntent].
*/
private fun linkButtons(context: Context, views: RemoteViews) {
val action = Intent(context, MainActivity::class.java).putExtra("expand", true)
var pendingIntent: PendingIntent
val serviceName = ComponentName(context, MusicService::class.java)
// Home
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
pendingIntent = PendingIntent.getActivity(context, 0, action, 0)
views.setOnClickPendingIntent(R.id.image, pendingIntent)
views.setOnClickPendingIntent(R.id.media_titles, pendingIntent)
// Previous track
pendingIntent = buildPendingIntent(context, Constants.ACTION_REWIND, serviceName)
views.setOnClickPendingIntent(R.id.button_prev, pendingIntent)
// Play and pause
pendingIntent = buildPendingIntent(context, Constants.ACTION_TOGGLE_PAUSE, serviceName)
views.setOnClickPendingIntent(R.id.button_toggle_play_pause, pendingIntent)
// Next track
pendingIntent = buildPendingIntent(context, Constants.ACTION_SKIP, serviceName)
views.setOnClickPendingIntent(R.id.button_next, pendingIntent)
}
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName, R.layout.app_widget_text)
val isPlaying = service.isPlaying
val song = service.currentSong
// Set the titles and artwork
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE)
} else {
appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE)
appWidgetView.setTextViewText(R.id.title, song.title)
appWidgetView.setTextViewText(R.id.text, song.artistName)
}
// Link actions buttons to intents
linkButtons(service, appWidgetView)
// Set correct drawable for pause state
val playPauseRes = if (isPlaying)
R.drawable.ic_pause_white_24dp
else
R.drawable.ic_play_arrow_white_24dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.createBitmap(RetroUtil.getTintedVectorDrawable(context, playPauseRes, ContextCompat.getColor(context, R.color.md_white_1000)), 1f))
pushUpdate(service.applicationContext, appWidgetIds, appWidgetView)
}
companion object {
const val NAME: String = "app_widget_text"
private var mInstance: AppWidgetText? = null
val instance: AppWidgetText
@Synchronized get() {
if (mInstance == null) {
mInstance = AppWidgetText()
}
return mInstance!!
}
}
}

View file

@ -0,0 +1,31 @@
package code.name.monkey.retromusic.appwidgets
import android.appwidget.AppWidgetManager
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Build
import code.name.monkey.retromusic.service.MusicService
/**
* @author Eugene Cheung (arkon)
*/
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val widgetManager = AppWidgetManager.getInstance(context)
// Start music service if there are any existing widgets
if (widgetManager.getAppWidgetIds(ComponentName(context, AppWidgetBig::class.java)).isNotEmpty() ||
widgetManager.getAppWidgetIds(ComponentName(context, AppWidgetClassic::class.java)).isNotEmpty() ||
widgetManager.getAppWidgetIds(ComponentName(context, AppWidgetSmall::class.java)).isNotEmpty() ||
widgetManager.getAppWidgetIds(ComponentName(context, AppWidgetCard::class.java)).isNotEmpty()) {
val serviceIntent = Intent(context, MusicService::class.java)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { // not allowed on Oreo
context.startService(serviceIntent)
}
}
}
}

View file

@ -0,0 +1,163 @@
package code.name.monkey.retromusic.appwidgets.base
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.res.Resources
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Build
import android.text.TextUtils
import android.widget.RemoteViews
import androidx.core.content.ContextCompat
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.MusicService
abstract class BaseAppWidget : AppWidgetProvider() {
/**
* {@inheritDoc}
*/
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray) {
defaultAppWidget(context, appWidgetIds)
val updateIntent = Intent(Constants.APP_WIDGET_UPDATE)
updateIntent.putExtra(Constants.EXTRA_APP_WIDGET_NAME, NAME)
updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds)
updateIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
context.sendBroadcast(updateIntent)
}
/**
* Handle a change notification coming over from [MusicService]
*/
fun notifyChange(service: MusicService, what: String) {
if (hasInstances(service)) {
if (Constants.META_CHANGED == what || Constants.PLAY_STATE_CHANGED == what) {
performUpdate(service, null)
}
}
}
protected fun pushUpdate(context: Context, appWidgetIds: IntArray?,
views: RemoteViews) {
val appWidgetManager = AppWidgetManager.getInstance(context)
if (appWidgetIds != null) {
appWidgetManager.updateAppWidget(appWidgetIds, views)
} else {
appWidgetManager.updateAppWidget(ComponentName(context, javaClass), views)
}
}
/**
* Check against [AppWidgetManager] if there are any instances of this widget.
*/
protected fun hasInstances(context: Context): Boolean {
val appWidgetManager = AppWidgetManager.getInstance(context)
val mAppWidgetIds = appWidgetManager.getAppWidgetIds(ComponentName(context,
javaClass))
return mAppWidgetIds.size > 0
}
protected fun buildPendingIntent(context: Context, action: String,
serviceName: ComponentName): PendingIntent {
val intent = Intent(action)
intent.component = serviceName
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
PendingIntent.getForegroundService(context, 0, intent, 0)
} else {
PendingIntent.getService(context, 0, intent, 0)
}
}
protected abstract fun defaultAppWidget(context: Context, appWidgetIds: IntArray)
abstract fun performUpdate(service: MusicService, appWidgetIds: IntArray?)
protected fun getAlbumArtDrawable(resources: Resources, bitmap: Bitmap?): Drawable {
return if (bitmap == null) {
ContextCompat.getDrawable(App.context, R.drawable.default_album_art)!!
} else {
BitmapDrawable(resources, bitmap)
}
}
protected fun getSongArtistAndAlbum(song: Song): String {
val builder = StringBuilder()
builder.append(song.artistName)
if (!TextUtils.isEmpty(song.artistName) && !TextUtils.isEmpty(song.albumName)) {
builder.append("")
}
builder.append(song.albumName)
return builder.toString()
}
companion object {
const val NAME: String = "app_widget"
fun createRoundedBitmap(drawable: Drawable?, width: Int, height: Int, tl: Float,
tr: Float, bl: Float, br: Float): Bitmap? {
if (drawable == null) {
return null
}
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val c = Canvas(bitmap)
drawable.setBounds(0, 0, width, height)
drawable.draw(c)
val rounded = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(rounded)
val paint = Paint()
paint.shader = BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
paint.isAntiAlias = true
canvas.drawPath(composeRoundedRectPath(RectF(0f, 0f, width.toFloat(), height.toFloat()), tl, tr, bl, br), paint)
return rounded
}
fun createBitmap(drawable: Drawable, sizeMultiplier: Float): Bitmap {
val bitmap = Bitmap.createBitmap((drawable.intrinsicWidth * sizeMultiplier).toInt(),
(drawable.intrinsicHeight * sizeMultiplier).toInt(), Bitmap.Config.ARGB_8888)
val c = Canvas(bitmap)
drawable.setBounds(0, 0, c.width, c.height)
drawable.draw(c)
return bitmap
}
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)
path.lineTo(rect.right, rect.bottom - br)
path.quadTo(rect.right, rect.bottom, rect.right - br, rect.bottom)
path.lineTo(rect.left + bl, rect.bottom)
path.quadTo(rect.left, rect.bottom, rect.left, rect.bottom - bl)
path.lineTo(rect.left, rect.top + tl)
path.quadTo(rect.left, rect.top, rect.left + tl, rect.top)
path.close()
return path
}
}
}

View file

@ -24,7 +24,7 @@ class DeletePlaylistDialog : RoundedBottomSheetDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
val playlists = arguments!!.getParcelableArrayList<Playlist>("playlists") val playlists = arguments!!.getParcelableArrayList<Playlist>("playlist")
val content: CharSequence val content: CharSequence
content = if (playlists!!.size > 1) { content = if (playlists!!.size > 1) {

View file

@ -29,16 +29,16 @@ class SortOrder {
companion object { companion object {
/* Artist sort order A-Z */ /* Artist sort order A-Z */
val ARTIST_A_Z = MediaStore.Audio.Artists.DEFAULT_SORT_ORDER const val ARTIST_A_Z = MediaStore.Audio.Artists.DEFAULT_SORT_ORDER
/* Artist sort order Z-A */ /* Artist sort order Z-A */
val ARTIST_Z_A = "$ARTIST_A_Z DESC" const val ARTIST_Z_A = "$ARTIST_A_Z DESC"
/* Artist sort order number of songs */ /* Artist sort order number of songs */
val ARTIST_NUMBER_OF_SONGS = MediaStore.Audio.Artists.NUMBER_OF_TRACKS + " DESC" const val ARTIST_NUMBER_OF_SONGS = MediaStore.Audio.Artists.NUMBER_OF_TRACKS + " DESC"
/* Artist sort order number of albums */ /* Artist sort order number of albums */
val ARTIST_NUMBER_OF_ALBUMS = MediaStore.Audio.Artists.NUMBER_OF_ALBUMS + " DESC" const val ARTIST_NUMBER_OF_ALBUMS = MediaStore.Audio.Artists.NUMBER_OF_ALBUMS + " DESC"
} }
} }
@ -49,20 +49,20 @@ class SortOrder {
companion object { companion object {
/* Album sort order A-Z */ /* Album sort order A-Z */
val ALBUM_A_Z = MediaStore.Audio.Albums.DEFAULT_SORT_ORDER const val ALBUM_A_Z = MediaStore.Audio.Albums.DEFAULT_SORT_ORDER
/* Album sort order Z-A */ /* Album sort order Z-A */
val ALBUM_Z_A = "$ALBUM_A_Z DESC" const val ALBUM_Z_A = "$ALBUM_A_Z DESC"
/* Album sort order songs */ /* Album sort order songs */
val ALBUM_NUMBER_OF_SONGS = MediaStore.Audio.Albums.NUMBER_OF_SONGS + " DESC" const val ALBUM_NUMBER_OF_SONGS = MediaStore.Audio.Albums.NUMBER_OF_SONGS + " DESC"
/* Album sort order artist */ /* Album sort order artist */
val ALBUM_ARTIST = (MediaStore.Audio.Artists.DEFAULT_SORT_ORDER const val ALBUM_ARTIST = (MediaStore.Audio.Artists.DEFAULT_SORT_ORDER
+ ", " + MediaStore.Audio.Albums.DEFAULT_SORT_ORDER) + ", " + MediaStore.Audio.Albums.DEFAULT_SORT_ORDER)
/* Album sort order year */ /* Album sort order year */
val ALBUM_YEAR = MediaStore.Audio.Media.YEAR + " DESC" const val ALBUM_YEAR = MediaStore.Audio.Media.YEAR + " DESC"
} }
} }
@ -73,25 +73,25 @@ class SortOrder {
companion object { companion object {
/* Song sort order A-Z */ /* Song sort order A-Z */
val SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER const val SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER
/* Song sort order Z-A */ /* Song sort order Z-A */
val SONG_Z_A = "$SONG_A_Z DESC" const val SONG_Z_A = "$SONG_A_Z DESC"
/* Song sort order artist */ /* Song sort order artist */
val SONG_ARTIST = MediaStore.Audio.Artists.DEFAULT_SORT_ORDER const val SONG_ARTIST = MediaStore.Audio.Artists.DEFAULT_SORT_ORDER
/* Song sort order album */ /* Song sort order album */
val SONG_ALBUM = MediaStore.Audio.Albums.DEFAULT_SORT_ORDER const val SONG_ALBUM = MediaStore.Audio.Albums.DEFAULT_SORT_ORDER
/* Song sort order year */ /* Song sort order year */
val SONG_YEAR = MediaStore.Audio.Media.YEAR + " DESC" const val SONG_YEAR = MediaStore.Audio.Media.YEAR + " DESC"
/* Song sort order duration */ /* Song sort order duration */
val SONG_DURATION = MediaStore.Audio.Media.DURATION + " DESC" const val SONG_DURATION = MediaStore.Audio.Media.DURATION + " DESC"
/* Song sort order date */ /* Song sort order date */
val SONG_DATE = MediaStore.Audio.Media.DATE_ADDED + " DESC" const val SONG_DATE = MediaStore.Audio.Media.DATE_ADDED + " DESC"
} }
} }
@ -102,17 +102,17 @@ class SortOrder {
companion object { companion object {
/* Album song sort order A-Z */ /* Album song sort order A-Z */
val SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER const val SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER
/* Album song sort order Z-A */ /* Album song sort order Z-A */
val SONG_Z_A = "$SONG_A_Z DESC" const val SONG_Z_A = "$SONG_A_Z DESC"
/* Album song sort order track list */ /* Album song sort order track list */
val SONG_TRACK_LIST = (MediaStore.Audio.Media.TRACK + ", " const val SONG_TRACK_LIST = (MediaStore.Audio.Media.TRACK + ", "
+ MediaStore.Audio.Media.DEFAULT_SORT_ORDER) + MediaStore.Audio.Media.DEFAULT_SORT_ORDER)
/* Album song sort order duration */ /* Album song sort order duration */
val SONG_DURATION = SongSortOrder.SONG_DURATION const val SONG_DURATION = SongSortOrder.SONG_DURATION
} }
} }
@ -123,22 +123,22 @@ class SortOrder {
companion object { companion object {
/* Artist song sort order A-Z */ /* Artist song sort order A-Z */
val SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER const val SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER
/* Artist song sort order Z-A */ /* Artist song sort order Z-A */
val SONG_Z_A = "$SONG_A_Z DESC" const val SONG_Z_A = "$SONG_A_Z DESC"
/* Artist song sort order album */ /* Artist song sort order album */
val SONG_ALBUM = MediaStore.Audio.Media.ALBUM const val SONG_ALBUM = MediaStore.Audio.Media.ALBUM
/* Artist song sort order year */ /* Artist song sort order year */
val SONG_YEAR = MediaStore.Audio.Media.YEAR + " DESC" const val SONG_YEAR = MediaStore.Audio.Media.YEAR + " DESC"
/* Artist song sort order duration */ /* Artist song sort order duration */
val SONG_DURATION = MediaStore.Audio.Media.DURATION + " DESC" const val SONG_DURATION = MediaStore.Audio.Media.DURATION + " DESC"
/* Artist song sort order date */ /* Artist song sort order date */
val SONG_DATE = MediaStore.Audio.Media.DATE_ADDED + " DESC" const val SONG_DATE = MediaStore.Audio.Media.DATE_ADDED + " DESC"
} }
} }
@ -149,16 +149,16 @@ class SortOrder {
companion object { companion object {
/* Artist album sort order A-Z */ /* Artist album sort order A-Z */
val ALBUM_A_Z = MediaStore.Audio.Albums.DEFAULT_SORT_ORDER const val ALBUM_A_Z = MediaStore.Audio.Albums.DEFAULT_SORT_ORDER
/* Artist album sort order Z-A */ /* Artist album sort order Z-A */
val ALBUM_Z_A = "$ALBUM_A_Z DESC" const val ALBUM_Z_A = "$ALBUM_A_Z DESC"
/* Artist album sort order year */ /* Artist album sort order year */
val ALBUM_YEAR = MediaStore.Audio.Media.YEAR + " DESC" const val ALBUM_YEAR = MediaStore.Audio.Media.YEAR + " DESC"
/* Artist album sort order year */ /* Artist album sort order year */
val ALBUM_YEAR_ASC = MediaStore.Audio.Media.YEAR + " ASC" const val ALBUM_YEAR_ASC = MediaStore.Audio.Media.YEAR + " ASC"
} }
} }
@ -169,10 +169,10 @@ class SortOrder {
companion object { companion object {
/* Genre sort order A-Z */ /* Genre sort order A-Z */
val GENRE_A_Z = MediaStore.Audio.Genres.DEFAULT_SORT_ORDER const val GENRE_A_Z = MediaStore.Audio.Genres.DEFAULT_SORT_ORDER
/* Genre sort order Z-A */ /* Genre sort order Z-A */
val ALBUM_Z_A = "$GENRE_A_Z DESC" const val ALBUM_Z_A = "$GENRE_A_Z DESC"
} }
} }

View file

@ -2,18 +2,17 @@ package code.name.monkey.retromusic.loaders
import android.content.Context import android.content.Context
import android.text.TextUtils import android.text.TextUtils
import java.util.ArrayList
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import io.reactivex.Observable import io.reactivex.Observable
import java.util.*
object SearchLoader { object SearchLoader {
fun searchAll(context: Context, query: String): Observable<ArrayList<Any>> { fun searchAll(context: Context, query: String?): Observable<ArrayList<Any>> {
val results = ArrayList<Any>() val results = ArrayList<Any>()
return Observable.create { e -> return Observable.create { e ->
if (!TextUtils.isEmpty(query)) { if (!TextUtils.isEmpty(query)) {
SongLoader.getSongs(context, query) SongLoader.getSongs(context, query!!)
.subscribe { songs -> .subscribe { songs ->
if (!songs.isEmpty()) { if (!songs.isEmpty()) {
results.add(context.resources.getString(R.string.songs)) results.add(context.resources.getString(R.string.songs))

View file

@ -114,7 +114,7 @@ object SongLoader {
return newSelectionValues return newSelectionValues
} }
fun getSong(cursor: Cursor?): Observable<Song> { private fun getSong(cursor: Cursor?): Observable<Song> {
return Observable.create { e -> return Observable.create { e ->
val song: Song = if (cursor != null && cursor.moveToFirst()) { val song: Song = if (cursor != null && cursor.moveToFirst()) {
getSongFromCursorImpl(cursor) getSongFromCursorImpl(cursor)

View file

@ -2,8 +2,7 @@ package code.name.monkey.retromusic.mvp.contract
import code.name.monkey.retromusic.mvp.BasePresenter import code.name.monkey.retromusic.mvp.BasePresenter
import code.name.monkey.retromusic.mvp.BaseView import code.name.monkey.retromusic.mvp.BaseView
import java.util.*
import java.util.ArrayList
/** /**
@ -14,6 +13,6 @@ interface SearchContract {
interface SearchView : BaseView<ArrayList<Any>> interface SearchView : BaseView<ArrayList<Any>>
interface SearchPresenter : BasePresenter<SearchView> { interface SearchPresenter : BasePresenter<SearchView> {
fun search(query: String) fun search(query: String?)
} }
} }

View file

@ -27,7 +27,7 @@ class SearchPresenter(private val view: SearchContract.SearchView) : Presenter()
} }
} }
override fun search(query: String) { override fun search(query: String?) {
disposable.add(repository.search(query) disposable.add(repository.search(query)
.debounce(500, TimeUnit.MILLISECONDS) .debounce(500, TimeUnit.MILLISECONDS)
.subscribeOn(schedulerProvider.computation()) .subscribeOn(schedulerProvider.computation())

View file

@ -1,169 +0,0 @@
package code.name.monkey.retromusic.providers;
import android.content.Context;
import java.io.File;
import java.util.ArrayList;
import code.name.monkey.retromusic.Injection;
import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.loaders.AlbumLoader;
import code.name.monkey.retromusic.loaders.ArtistLoader;
import code.name.monkey.retromusic.loaders.GenreLoader;
import code.name.monkey.retromusic.loaders.HomeLoader;
import code.name.monkey.retromusic.loaders.LastAddedSongsLoader;
import code.name.monkey.retromusic.loaders.PlaylistLoader;
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader;
import code.name.monkey.retromusic.loaders.SearchLoader;
import code.name.monkey.retromusic.loaders.SongLoader;
import code.name.monkey.retromusic.loaders.TopAndRecentlyPlayedTracksLoader;
import code.name.monkey.retromusic.model.Album;
import code.name.monkey.retromusic.model.Artist;
import code.name.monkey.retromusic.model.Genre;
import code.name.monkey.retromusic.model.Playlist;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist;
import code.name.monkey.retromusic.providers.interfaces.Repository;
import code.name.monkey.retromusic.rest.model.KuGouRawLyric;
import code.name.monkey.retromusic.rest.model.KuGouSearchLyricResult;
import code.name.monkey.retromusic.rest.service.KuGouApiService;
import code.name.monkey.retromusic.util.LyricUtil;
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;
public class RepositoryImpl implements Repository {
private static RepositoryImpl INSTANCE;
private Context context;
public RepositoryImpl(Context context) {
this.context = context;
}
public static synchronized RepositoryImpl getInstance() {
if (INSTANCE == null) {
INSTANCE = new RepositoryImpl(App.Companion.getInstance());
}
return INSTANCE;
}
@Override
public Observable<ArrayList<Song>> getAllSongs() {
return SongLoader.INSTANCE.getAllSongs(context);
}
@Override
public Observable<ArrayList<Song>> getSuggestionSongs() {
return SongLoader.INSTANCE.suggestSongs(context);
}
@Override
public Observable<Song> getSong(int id) {
return SongLoader.INSTANCE.getSong(context, id);
}
@Override
public Observable<ArrayList<Album>> getAllAlbums() {
return AlbumLoader.Companion.getAllAlbums(context);
}
@Override
public Observable<ArrayList<Album>> getRecentAlbums() {
return LastAddedSongsLoader.INSTANCE.getLastAddedAlbums(context);
}
@Override
public Observable<ArrayList<Album>> getTopAlbums() {
return TopAndRecentlyPlayedTracksLoader.INSTANCE.getTopAlbums(context);
}
@Override
public Observable<Album> getAlbum(int albumId) {
return AlbumLoader.Companion.getAlbum(context, albumId);
}
@Override
public Observable<ArrayList<Artist>> getAllArtists() {
return ArtistLoader.INSTANCE.getAllArtists(context);
}
@Override
public Observable<ArrayList<Artist>> getRecentArtists() {
return LastAddedSongsLoader.INSTANCE.getLastAddedArtists(context);
}
@Override
public Observable<ArrayList<Artist>> getTopArtists() {
return TopAndRecentlyPlayedTracksLoader.INSTANCE.getTopArtists(context);
}
@Override
public Observable<Artist> getArtistById(long artistId) {
return ArtistLoader.INSTANCE.getArtist(context, (int) artistId);
}
@Override
public Observable<ArrayList<Playlist>> getAllPlaylists() {
return PlaylistLoader.INSTANCE.getAllPlaylists(context);
}
@Override
public Observable<ArrayList<Song>> getFavoriteSongs() {
return null;
}
@Override
public Observable<ArrayList<Object>> search(String query) {
return SearchLoader.INSTANCE.searchAll(context, query);
}
@Override
public Observable<ArrayList<Song>> getPlaylistSongs(Playlist playlist) {
return PlaylistSongsLoader.INSTANCE.getPlaylistSongList(context, playlist);
}
@Override
public Observable<ArrayList<Playlist>> getHomeList() {
return HomeLoader.INSTANCE.getHomeLoader(context);
}
@Override
public Observable<ArrayList<AbsSmartPlaylist>> getAllThings() {
return HomeLoader.INSTANCE.getRecentAndTopThings(context);
}
@Override
public Observable<ArrayList<Genre>> getAllGenres() {
return GenreLoader.INSTANCE.getAllGenres(context);
}
@Override
public Observable<ArrayList<Song>> getGenre(int genreId) {
return GenreLoader.INSTANCE.getSongs(context, genreId);
}
@Override
public Observable<File> downloadLrcFile(String title, String artist, long duration) {
KuGouApiService service = Injection.INSTANCE.provideKuGouApiService();
return service.searchLyric(title, String.valueOf(duration))
.subscribeOn(Schedulers.io())
.flatMap(kuGouSearchLyricResult -> {
if (kuGouSearchLyricResult.status == 200
&& kuGouSearchLyricResult.candidates != null
&& kuGouSearchLyricResult.candidates.size() != 0) {
KuGouSearchLyricResult.Candidates candidates = kuGouSearchLyricResult.candidates.get(0);
return service.getRawLyric(candidates.id, candidates.accesskey);
} else {
return Observable.just(new KuGouRawLyric());
}
}).map(kuGouRawLyric -> {
if (kuGouRawLyric == null) {
return null;
}
String rawLyric = LyricUtil.decryptBASE64(kuGouRawLyric.content);
if (rawLyric != null && rawLyric.isEmpty()) {
return null;
}
return LyricUtil.writeLrcToLoc(title, artist, rawLyric);
});
}
}

View file

@ -0,0 +1,86 @@
package code.name.monkey.retromusic.providers
import android.content.Context
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.loaders.*
import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist
import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.Observable
import java.util.*
class RepositoryImpl(private val context: Context) : Repository {
override val allSongs: Observable<ArrayList<Song>>
get() = SongLoader.getAllSongs(context)
override val suggestionSongs: Observable<ArrayList<Song>>
get() = SongLoader.suggestSongs(context)
override val allAlbums: Observable<ArrayList<Album>>
get() = AlbumLoader.getAllAlbums(context)
override val recentAlbums: Observable<ArrayList<Album>>
get() = LastAddedSongsLoader.getLastAddedAlbums(context)
override val topAlbums: Observable<ArrayList<Album>>
get() = TopAndRecentlyPlayedTracksLoader.getTopAlbums(context)
override val allArtists: Observable<ArrayList<Artist>>
get() = ArtistLoader.getAllArtists(context)
override val recentArtists: Observable<ArrayList<Artist>>
get() = LastAddedSongsLoader.getLastAddedArtists(context)
override val topArtists: Observable<ArrayList<Artist>>
get() = TopAndRecentlyPlayedTracksLoader.getTopArtists(context)
override val allPlaylists: Observable<ArrayList<Playlist>>
get() = PlaylistLoader.getAllPlaylists(context)
override val homeList: Observable<ArrayList<Playlist>>
get() = HomeLoader.getHomeLoader(context)
override val allThings: Observable<ArrayList<AbsSmartPlaylist>>
get() = HomeLoader.getRecentAndTopThings(context)
override val allGenres: Observable<ArrayList<Genre>>
get() = GenreLoader.getAllGenres(context)
override fun getSong(id: Int): Observable<Song> {
return SongLoader.getSong(context, id)
}
override fun getAlbum(albumId: Int): Observable<Album> {
return AlbumLoader.getAlbum(context, albumId)
}
override fun getArtistById(artistId: Long): Observable<Artist> {
return ArtistLoader.getArtist(context, artistId.toInt())
}
override fun search(query: String?): Observable<ArrayList<Any>> {
return SearchLoader.searchAll(context, query)
}
override fun getPlaylistSongs(playlist: Playlist): Observable<ArrayList<Song>> {
return PlaylistSongsLoader.getPlaylistSongList(context, playlist)
}
override fun getGenre(genreId: Int): Observable<ArrayList<Song>> {
return GenreLoader.getSongs(context, genreId)
}
companion object {
private var INSTANCE: RepositoryImpl? = null
val instance: RepositoryImpl
@Synchronized get() {
if (INSTANCE == null) {
INSTANCE = RepositoryImpl(App.instance)
}
return INSTANCE!!
}
}
}

View file

@ -1,14 +1,9 @@
package code.name.monkey.retromusic.providers.interfaces package code.name.monkey.retromusic.providers.interfaces
import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist
import io.reactivex.Observable import io.reactivex.Observable
import java.io.File import java.util.*
import java.util.ArrayList
/** /**
* Created by hemanths on 11/08/17. * Created by hemanths on 11/08/17.
@ -34,8 +29,6 @@ interface Repository {
val allPlaylists: Observable<ArrayList<Playlist>> val allPlaylists: Observable<ArrayList<Playlist>>
val favoriteSongs: Observable<ArrayList<Song>>
val homeList: Observable<ArrayList<Playlist>> val homeList: Observable<ArrayList<Playlist>>
val allThings: Observable<ArrayList<AbsSmartPlaylist>> val allThings: Observable<ArrayList<AbsSmartPlaylist>>
@ -46,15 +39,13 @@ interface Repository {
fun getAlbum(albumId: Int): Observable<Album> fun getAlbum(albumId: Int): Observable<Album>
fun getArtistById(artistId: Long): Observable<Artist> fun getArtistById(artistId: Long): Observable<Artist>
fun search(query: String): Observable<ArrayList<Any>> fun search(query: String?): Observable<ArrayList<Any>>
fun getPlaylistSongs(playlist: Playlist): Observable<ArrayList<Song>> fun getPlaylistSongs(playlist: Playlist): Observable<ArrayList<Song>>
fun getGenre(genreId: Int): Observable<ArrayList<Song>> fun getGenre(genreId: Int): Observable<ArrayList<Song>>
fun downloadLrcFile(title: String, artist: String, duration: Long): Observable<File>
} }

View file

@ -2,6 +2,7 @@ package code.name.monkey.retromusic.service;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
@ -47,6 +48,11 @@ import java.util.Random;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.appwidgets.AppWidgetBig;
import code.name.monkey.retromusic.appwidgets.AppWidgetCard;
import code.name.monkey.retromusic.appwidgets.AppWidgetClassic;
import code.name.monkey.retromusic.appwidgets.AppWidgetSmall;
import code.name.monkey.retromusic.appwidgets.AppWidgetText;
import code.name.monkey.retromusic.glide.BlurTransformation; import code.name.monkey.retromusic.glide.BlurTransformation;
import code.name.monkey.retromusic.glide.SongGlideRequest; import code.name.monkey.retromusic.glide.SongGlideRequest;
import code.name.monkey.retromusic.helper.ShuffleHelper; import code.name.monkey.retromusic.helper.ShuffleHelper;
@ -92,12 +98,10 @@ import static code.name.monkey.retromusic.Constants.SHUFFLE_MODE_CHANGED;
*/ */
public class MusicService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener, Playback.PlaybackCallbacks { public class MusicService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener, Playback.PlaybackCallbacks {
public static final String TAG = MusicService.class.getSimpleName(); public static final String TAG = MusicService.class.getSimpleName();
public static final String SAVED_POSITION = "POSITION"; public static final String SAVED_POSITION = "POSITION";
public static final String SAVED_POSITION_IN_TRACK = "POSITION_IN_TRACK"; public static final String SAVED_POSITION_IN_TRACK = "POSITION_IN_TRACK";
public static final String SAVED_SHUFFLE_MODE = "SHUFFLE_MODE"; public static final String SAVED_SHUFFLE_MODE = "SHUFFLE_MODE";
public static final String SAVED_REPEAT_MODE = "REPEAT_MODE"; public static final String SAVED_REPEAT_MODE = "REPEAT_MODE";
public static final int RELEASE_WAKELOCK = 0; public static final int RELEASE_WAKELOCK = 0;
public static final int TRACK_ENDED = 1; public static final int TRACK_ENDED = 1;
public static final int TRACK_WENT_TO_NEXT = 2; public static final int TRACK_WENT_TO_NEXT = 2;
@ -122,11 +126,40 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
| PlaybackStateCompat.ACTION_STOP | PlaybackStateCompat.ACTION_STOP
| PlaybackStateCompat.ACTION_SEEK_TO; | PlaybackStateCompat.ACTION_SEEK_TO;
private final IBinder musicBind = new MusicBinder(); private final IBinder musicBind = new MusicBinder();
private AppWidgetBig appWidgetBig = AppWidgetBig.Companion.getInstance();
private AppWidgetClassic appWidgetClassic = AppWidgetClassic.Companion.getInstance();
private AppWidgetSmall appWidgetSmall = AppWidgetSmall.Companion.getInstance();
private AppWidgetCard appWidgetCard = AppWidgetCard.Companion.getInstance();
private AppWidgetText appWidgetText = AppWidgetText.Companion.getInstance();
private final BroadcastReceiver widgetIntentReceiver = new BroadcastReceiver() { private final BroadcastReceiver widgetIntentReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(final Context context, final Intent intent) { public void onReceive(final Context context, final Intent intent) {
final String command = intent.getStringExtra(EXTRA_APP_WIDGET_NAME); final String command = intent.getStringExtra(EXTRA_APP_WIDGET_NAME);
final int[] ids = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
switch (command) {
case AppWidgetClassic.NAME: {
appWidgetClassic.performUpdate(MusicService.this, ids);
break;
}
case AppWidgetSmall.NAME: {
appWidgetSmall.performUpdate(MusicService.this, ids);
break;
}
case AppWidgetBig.NAME: {
appWidgetBig.performUpdate(MusicService.this, ids);
break;
}
case AppWidgetCard.NAME: {
appWidgetCard.performUpdate(MusicService.this, ids);
break;
}
case AppWidgetText.NAME: {
appWidgetText.performUpdate(MusicService.this, ids);
break;
}
}
} }
}; };
private Playback playback; private Playback playback;
@ -1083,7 +1116,11 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
private void sendChangeInternal(final String what) { private void sendChangeInternal(final String what) {
sendBroadcast(new Intent(what)); sendBroadcast(new Intent(what));
appWidgetBig.notifyChange(this, what);
appWidgetClassic.notifyChange(this, what);
appWidgetSmall.notifyChange(this, what);
appWidgetCard.notifyChange(this, what);
appWidgetText.notifyChange(this, what);
} }
private void handleChangeInternal(@NonNull final String what) { private void handleChangeInternal(@NonNull final String what) {

View file

@ -45,10 +45,8 @@ class PlayingNotificationImpl : PlayingNotification() {
val isPlaying = service.isPlaying val isPlaying = service.isPlaying
val notificationLayout = RemoteViews(service.packageName, val notificationLayout = RemoteViews(service.packageName, R.layout.notification)
R.layout.notification) val notificationLayoutBig = RemoteViews(service.packageName, R.layout.notification_big)
val notificationLayoutBig = RemoteViews(service.packageName,
R.layout.notification_big)
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) { if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
notificationLayout.setViewVisibility(R.id.media_titles, View.INVISIBLE) notificationLayout.setViewVisibility(R.id.media_titles, View.INVISIBLE)
@ -58,8 +56,7 @@ class PlayingNotificationImpl : PlayingNotification() {
notificationLayout.setTextViewText(R.id.text, song.artistName) notificationLayout.setTextViewText(R.id.text, song.artistName)
} }
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName) && TextUtils if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName) && TextUtils.isEmpty(song.albumName)) {
.isEmpty(song.albumName)) {
notificationLayoutBig.setViewVisibility(R.id.media_titles, View.INVISIBLE) notificationLayoutBig.setViewVisibility(R.id.media_titles, View.INVISIBLE)
} else { } else {
notificationLayoutBig.setViewVisibility(R.id.media_titles, View.VISIBLE) notificationLayoutBig.setViewVisibility(R.id.media_titles, View.VISIBLE)

View file

@ -0,0 +1,15 @@
package code.name.monkey.retromusic.transform
import android.view.View
import androidx.viewpager.widget.ViewPager
class StackTransformer : ViewPager.PageTransformer {
override fun transformPage(page: View, position: Float) {
if (position >= 0) {
page.scaleX = (0.9f - 0.05f * position)
page.scaleY = 0.9f
page.translationX = -page.width * position
page.translationY = -30 * position
}
}
}

View file

@ -71,10 +71,11 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
setupWindowTransition() setupWindowTransition()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
toggleBottomNavigationView(true)
setLightNavigationBar(true) setLightNavigationBar(true)
setNavigationbarColorAuto() setNavigationbarColorAuto()
toggleBottomNavigationView(true)
ActivityCompat.postponeEnterTransition(this) ActivityCompat.postponeEnterTransition(this)
val albumId = intent.getIntExtra(EXTRA_ALBUM_ID, -1) val albumId = intent.getIntExtra(EXTRA_ALBUM_ID, -1)

View file

@ -0,0 +1,83 @@
package code.name.monkey.retromusic.ui.activities
import android.content.Context
import android.os.Bundle
import android.view.View
import android.view.WindowManager
import android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
import androidx.core.view.ViewCompat
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity
import code.name.monkey.retromusic.ui.fragments.player.lockscreen.LockScreenPlayerControlsFragment
import com.bumptech.glide.Glide
import com.r0adkll.slidr.Slidr
import com.r0adkll.slidr.model.SlidrConfig
import com.r0adkll.slidr.model.SlidrListener
import com.r0adkll.slidr.model.SlidrPosition
class LockScreenActivity : AbsMusicServiceActivity() {
private var mFragment: LockScreenPlayerControlsFragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
or WindowManager.LayoutParams.FLAG_FULLSCREEN
or WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
or WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
setDrawUnderStatusBar()
setContentView(R.layout.activity_lock_screen_old_style)
hideStatusBar()
setStatusbarColorAuto()
setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
setLightNavigationBar(true)
val config = SlidrConfig.Builder()
.position(SlidrPosition.BOTTOM)
.build()
Slidr.attach(this, config)
mFragment = supportFragmentManager.findFragmentById(R.id.playback_controls_fragment) as LockScreenPlayerControlsFragment?
findViewById<View>(R.id.slide).apply {
translationY = 100f
alpha = 0f
ViewCompat.animate(this)
.translationY(0f)
.alpha(1f)
.setDuration(1500)
.start()
}
findViewById<View>(R.id.root_layout).setBackgroundColor(ThemeStore.primaryColor(this))
}
override fun onPlayingMetaChanged() {
super.onPlayingMetaChanged()
updateSongs()
}
override fun onServiceConnected() {
super.onServiceConnected()
updateSongs()
}
private fun updateSongs() {
val song = MusicPlayerRemote.currentSong
SongGlideRequest.Builder.from(Glide.with(this), song)
.checkIgnoreMediaStore(this)
.generatePalette(this)
.build().into(object : RetroMusicColoredTarget(findViewById(R.id.image)) {
override fun onColorReady(color: Int) {
mFragment!!.setDark(color)
}
})
}
}

View file

@ -1,168 +1,104 @@
package code.name.monkey.retromusic.ui.activities package code.name.monkey.retromusic.ui.activities
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.PorterDuff
import android.graphics.drawable.Drawable
import android.os.AsyncTask import android.os.AsyncTask
import android.os.Bundle import android.os.Bundle
import android.text.InputType import android.text.InputType
import android.text.TextUtils import android.text.TextUtils
import android.view.MenuItem import android.view.*
import android.view.View
import android.view.WindowManager
import android.widget.RadioButton
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.model.lyrics.Lyrics import code.name.monkey.retromusic.model.lyrics.Lyrics
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity
import code.name.monkey.retromusic.ui.activities.tageditor.WriteTagsAsyncTask 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.LyricUtil
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.bumptech.glide.Glide
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.activity_lyrics.* import kotlinx.android.synthetic.main.activity_lyrics.*
import kotlinx.android.synthetic.main.fragment_lyrics.*
import kotlinx.android.synthetic.main.fragment_synced.*
import org.jaudiotagger.tag.FieldKey import org.jaudiotagger.tag.FieldKey
import java.io.File import java.io.File
import java.util.* import java.util.*
class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.Callback, View.OnClickListener { class LyricsActivity : AbsMusicServiceActivity(), View.OnClickListener {
override fun onClick(v: View?) {
when (viewPager.currentItem) {
0 -> showSyncedLyrics()
1 -> showLyricsSaveDialog()
}
}
private var updateHelper: MusicProgressViewUpdateHelper? = null private lateinit var song: Song
private var updateLyricsAsyncTask: AsyncTask<*, *, *>? = null
private var disposable: CompositeDisposable? = null
private var song: Song? = null
private var lyrics: Lyrics? = null private var lyrics: Lyrics? = null
private val googleSearchLrcUrl: String private val googleSearchLrcUrl: String
get() { get() {
var baseUrl = "http://www.google.com/search?" var baseUrl = "http://www.google.com/search?"
var query = song!!.title + "+" + song!!.artistName var query = song.title + "+" + song.artistName
query = "q=" + query.replace(" ", "+") + " .lrc" query = "q=" + query.replace(" ", "+") + " .lrc"
baseUrl += query baseUrl += query
return baseUrl return baseUrl
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
//setDrawUnderNavigationBar();
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lyrics) setContentView(R.layout.activity_lyrics)
setStatusbarColorAuto()
setTaskDescriptionColorAuto() setTaskDescriptionColorAuto()
setNavigationbarColorAuto() setNavigationbarColorAuto()
container.isFit = !PreferenceUtil.getInstance().fullScreenMode
setSupportActionBar(bottomAppBar) toolbar.setBackgroundColor(ThemeStore.primaryColor(this))
Objects.requireNonNull<Drawable>(bottomAppBar!!.navigationIcon) toolbar.navigationIcon = TintHelper.createTintedDrawable(ContextCompat.getDrawable(this@LyricsActivity, R.drawable.ic_keyboard_backspace_black_24dp), ThemeStore.textColorSecondary(this@LyricsActivity))
.setColorFilter(ThemeStore.textColorPrimary(this), PorterDuff.Mode.SRC_IN) appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this))
bottomAppBar!!.backgroundTint = ColorStateList.valueOf(ThemeStore.primaryColor(this)) setSupportActionBar(toolbar)
TintHelper.setTintAuto(fab, ThemeStore.accentColor(this), true) TintHelper.setTintAuto(fab, ThemeStore.accentColor(this), true)
updateHelper = MusicProgressViewUpdateHelper(this, 500, 1000)
setupLyricsView()
setupWakelock() setupWakelock()
loadLrcFile()
actions.setOnCheckedChangeListener { _, checkedId -> selectLyricsTye(checkedId) }
actions.check(PreferenceUtil.getInstance().lastLyricsType)
viewPager.apply {
adapter = PagerAdapter(supportFragmentManager)
}
tabs.apply {
setupWithViewPager(viewPager)
setSelectedTabIndicator(TintHelper.createTintedDrawable(ContextCompat.getDrawable(this@LyricsActivity, R.drawable.tab_indicator), ThemeStore.accentColor(this@LyricsActivity)))
setTabTextColors(ThemeStore.textColorSecondary(this@LyricsActivity), ThemeStore.accentColor(this@LyricsActivity))
setSelectedTabIndicatorColor(ThemeStore.accentColor(context))
}
fab.setOnClickListener(this) fab.setOnClickListener(this)
} }
private fun selectLyricsTye(group: Int) {
PreferenceUtil.getInstance().lastLyricsType = group
val radioButton = actions.findViewById<RadioButton>(group)
if (radioButton != null) {
radioButton.backgroundTintList = ColorStateList.valueOf(Color.WHITE)
//radioButton.setTextColor(ThemeStore.textColorPrimary(this));
}
offlineLyrics!!.visibility = View.GONE
lyricsView.visibility = View.GONE
when (group) {
R.id.syncedLyrics -> {
loadLRCLyrics()
lyricsView!!.visibility = View.VISIBLE
}
R.id.normalLyrics -> {
loadSongLyrics()
offlineLyrics!!.visibility = View.VISIBLE
}
else -> {
loadSongLyrics()
offlineLyrics!!.visibility = View.VISIBLE
}
}
}
private fun loadLRCLyrics() {
if (LyricUtil.isLrcFileExist(song!!.title, song!!.artistName)) {
showLyricsLocal(LyricUtil.getLocalLyricFile(song!!.title, song!!.artistName))
}
}
private fun setupWakelock() {
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
private fun setupLyricsView() {
disposable = CompositeDisposable()
lyricsView!!.apply {
setOnPlayerClickListener { progress, _ -> MusicPlayerRemote.seekTo(progress.toInt()) }
//lyricView.setHighLightTextColor(ThemeStore.accentColor(this));
setDefaultColor(ContextCompat.getColor(this@LyricsActivity, R.color.md_grey_400))
//lyricView.setTouchable(false);
setHintColor(Color.WHITE)
}
}
override fun onPlayingMetaChanged() { override fun onPlayingMetaChanged() {
super.onPlayingMetaChanged() super.onPlayingMetaChanged()
loadLrcFile() song = MusicPlayerRemote.currentSong
} toolbar.title = song.title
toolbar.subtitle = song.artistName
override fun onResume() {
super.onResume()
updateHelper!!.start()
}
override fun onPause() {
super.onPause()
updateHelper!!.stop()
} }
override fun onServiceConnected() { override fun onServiceConnected() {
super.onServiceConnected() super.onServiceConnected()
loadLrcFile() song = MusicPlayerRemote.currentSong
toolbar.title = song.title
toolbar.subtitle = song.artistName
} }
override fun onDestroy() { private fun setupWakelock() {
super.onDestroy() window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
disposable!!.clear()
if (updateLyricsAsyncTask != null && !updateLyricsAsyncTask!!.isCancelled) {
updateLyricsAsyncTask!!.cancel(true)
}
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
@ -172,84 +108,10 @@ class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)
} }
override fun onUpdateProgressViews(progress: Int, total: Int) {
lyricsView!!.setCurrentTimeMillis(progress.toLong())
}
private fun loadLrcFile() {
song = MusicPlayerRemote.currentSong
bottomAppBar.title = song!!.title
bottomAppBar.subtitle = song!!.artistName
SongGlideRequest.Builder.from(Glide.with(this), song!!)
.checkIgnoreMediaStore(this)
.generatePalette(this)
.build()
.into(object : RetroMusicColoredTarget(findViewById(R.id.image)) {
override fun onColorReady(color: Int) {
if (PreferenceUtil.getInstance().adaptiveColor) {
//background.setBackgroundColor(color);
}
}
})
}
private fun showLyricsLocal(file: File?) {
if (file == null) {
lyricsView!!.reset()
} else {
lyricsView!!.setLyricFile(file, "UTF-8")
}
}
override fun onClick(view: View) {
when (view.id) {
android.R.id.home -> onBackPressed()
R.id.fab -> when (actions.checkedRadioButtonId) {
R.id.syncedLyrics -> showSyncedLyrics()
R.id.normalLyrics -> showLyricsSaveDialog()
}
}
}
@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
}
offlineLyrics!!.text = l.data
}
override fun onCancelled(s: Lyrics) {
onPostExecute(null)
}
}.execute()
}
private fun showSyncedLyrics() { private fun showSyncedLyrics() {
var content = "" var content = ""
try { try {
content = LyricUtil.getStringFromFile(song!!.title, song!!.artistName) content = LyricUtil.getStringFromFile(song.title, song.artistName)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }
@ -260,14 +122,12 @@ class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.
.content("Add time frame lyrics") .content("Add time frame lyrics")
.negativeText("Delete") .negativeText("Delete")
.onNegative { _, _ -> .onNegative { _, _ ->
LyricUtil.deleteLrcFile(song!!.title, song!!.artistName) LyricUtil.deleteLrcFile(song.title, song.artistName)
loadLrcFile()
} }
.onNeutral { _, _ -> RetroUtil.openUrl(this@LyricsActivity, googleSearchLrcUrl) } .onNeutral { _, _ -> RetroUtil.openUrl(this@LyricsActivity, googleSearchLrcUrl) }
.inputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE) .inputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE)
.input("Paste lyrics here", content) { _, input -> .input("Paste lyrics here", content) { _, input ->
LyricUtil.writeLrcToLoc(song!!.title, song!!.artistName, input.toString()) LyricUtil.writeLrcToLoc(song.title, song.artistName, input.toString())
loadLrcFile()
}.show() }.show()
} }
@ -280,13 +140,12 @@ class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.
MaterialDialog.Builder(this) MaterialDialog.Builder(this)
.title("Add lyrics") .title("Add lyrics")
.neutralText("Search") .neutralText("Search")
.onNeutral { _, _ -> RetroUtil.openUrl(this@LyricsActivity, getGoogleSearchUrl(song!!.title, song!!.artistName)) } .onNeutral { _, _ -> RetroUtil.openUrl(this@LyricsActivity, getGoogleSearchUrl(song.title, song.artistName)) }
.inputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE) .inputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE)
.input("Paste lyrics here", content) { _, input -> .input("Paste lyrics here", content) { _, input ->
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java) val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
fieldKeyValueMap[FieldKey.LYRICS] = input.toString() fieldKeyValueMap[FieldKey.LYRICS] = input.toString()
WriteTagsAsyncTask(this@LyricsActivity).execute(WriteTagsAsyncTask.LoadingInfo(getSongPaths(song!!), fieldKeyValueMap, null)) WriteTagsAsyncTask(this@LyricsActivity).execute(WriteTagsAsyncTask.LoadingInfo(getSongPaths(song), fieldKeyValueMap, null))
loadLrcFile()
} }
.show() .show()
} }
@ -305,3 +164,154 @@ class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.
return baseUrl return baseUrl
} }
} }
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
}
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 onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
loadSongLyrics()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_lyrics, container, false)
}
}
class SyncedLyricsFragment : AbsMusicServiceFragment(), MusicProgressViewUpdateHelper.Callback {
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 onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
updateHelper = MusicProgressViewUpdateHelper(this, 500, 1000)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupLyricsView()
}
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 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")
}
}
}

View file

@ -11,7 +11,10 @@ import android.util.Log
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.app.ActivityCompat
import androidx.core.app.ShareCompat import androidx.core.app.ShareCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.drawerlayout.widget.DrawerLayout.*
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
@ -49,10 +52,10 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
val action = intent.action val action = intent.action
if (action != null && action == Intent.ACTION_SCREEN_OFF) { if (action != null && action == Intent.ACTION_SCREEN_OFF) {
if (PreferenceUtil.getInstance().lockScreen && MusicPlayerRemote.isPlaying) { if (PreferenceUtil.getInstance().lockScreen && MusicPlayerRemote.isPlaying) {
/*Intent activity = new Intent(context, LockScreenActivity.class); val activity = Intent(context, LockScreenActivity::class.java)
activity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); activity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
activity.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); activity.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
ActivityCompat.startActivity(context, activity, null);*/ ActivityCompat.startActivity(context, activity, null)
} }
} }
} }
@ -210,8 +213,14 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
if (!hasPermissions()) { if (!hasPermissions()) {
requestPermissions() requestPermissions()
} }
checkSetUpPro(); // good chance that pro version check was delayed on first start
} }
REQUEST_CODE_THEME, APP_USER_INFO_REQUEST -> postRecreate() REQUEST_CODE_THEME, APP_USER_INFO_REQUEST -> postRecreate()
PURCHASE_REQUEST -> {
if (resultCode == RESULT_OK) {
checkSetUpPro();
}
}
} }
} }
@ -265,7 +274,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
private fun showPromotionalOffer() { private fun showPromotionalOffer() {
MaterialDialog.Builder(this) MaterialDialog.Builder(this)
.positiveText("Buy") .positiveText("Buy")
.onPositive { _, _ -> startActivity(Intent(this@MainActivity, ProVersionActivity::class.java)) } .onPositive { _, _ -> startActivity(Intent(this@MainActivity, PurchaseActivity::class.java)) }
.negativeText(android.R.string.cancel) .negativeText(android.R.string.cancel)
.customView(R.layout.dialog_promotional_offer, false) .customView(R.layout.dialog_promotional_offer, false)
.dismissListener { .dismissListener {
@ -298,7 +307,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
R.id.nav_library -> Handler().postDelayed({ setMusicChooser(LIBRARY) }, 200) R.id.nav_library -> Handler().postDelayed({ setMusicChooser(LIBRARY) }, 200)
R.id.nav_home -> Handler().postDelayed({ setMusicChooser(HOME) }, 200) R.id.nav_home -> Handler().postDelayed({ setMusicChooser(HOME) }, 200)
R.id.nav_folders -> Handler().postDelayed({ setMusicChooser(FOLDERS) }, 200) R.id.nav_folders -> Handler().postDelayed({ setMusicChooser(FOLDERS) }, 200)
R.id.buy_pro -> Handler().postDelayed({ startActivityForResult(Intent(this@MainActivity, ProVersionActivity::class.java), PURCHASE_REQUEST) }, 200) R.id.buy_pro -> Handler().postDelayed({ startActivityForResult(Intent(this@MainActivity, PurchaseActivity::class.java), PURCHASE_REQUEST) }, 200)
R.id.nav_settings -> Handler().postDelayed({ NavigationUtil.goToSettings(this@MainActivity) }, 200) R.id.nav_settings -> Handler().postDelayed({ NavigationUtil.goToSettings(this@MainActivity) }, 200)
R.id.nav_equalizer -> Handler().postDelayed({ NavigationUtil.openEqualizer(this@MainActivity) }, 200) R.id.nav_equalizer -> Handler().postDelayed({ NavigationUtil.openEqualizer(this@MainActivity) }, 200)
R.id.nav_share_app -> Handler().postDelayed({ shareApp() }, 200) R.id.nav_share_app -> Handler().postDelayed({ shareApp() }, 200)
@ -329,7 +338,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
when (key) { when (key) {
LIBRARY -> { LIBRARY -> {
navigationView.setCheckedItem(R.id.nav_library) navigationView.setCheckedItem(R.id.nav_library)
setCurrentFragment(LibraryFragment.newInstance()) setCurrentFragment(LibraryFragment.newInstance(PreferenceUtil.getInstance().lastPage))
} }
FOLDERS -> { FOLDERS -> {
navigationView.setCheckedItem(R.id.nav_folders) navigationView.setCheckedItem(R.id.nav_folders)
@ -369,10 +378,15 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)
} }
private fun updateNavigationDrawerHeader() { override fun onPanelCollapsed() {
super.onPanelCollapsed()
drawerLayout.setDrawerLockMode(LOCK_MODE_UNLOCKED)
} }
override fun onPanelExpanded() {
super.onPanelExpanded()
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
}
companion object { companion object {
const val APP_INTRO_REQUEST = 2323 const val APP_INTRO_REQUEST = 2323
const val LIBRARY = 1 const val LIBRARY = 1

View file

@ -21,7 +21,7 @@ class PlayingQueueActivity : AbsMusicServiceActivity() {
private var wrappedAdapter: RecyclerView.Adapter<*>? = null private var wrappedAdapter: RecyclerView.Adapter<*>? = null
private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null
private var playingQueueAdapter: PlayingQueueAdapter? = null private var playingQueueAdapter: PlayingQueueAdapter? = null
private lateinit var layoutManager: LinearLayoutManager private lateinit var linearLayoutManager: LinearLayoutManager
private val upNextAndQueueTime: String private val upNextAndQueueTime: String
get() = resources.getString(R.string.up_next) + "" + MusicUtil.getReadableDurationString(MusicPlayerRemote.getQueueDurationMillis(MusicPlayerRemote.position)) get() = resources.getString(R.string.up_next) + "" + MusicUtil.getReadableDurationString(MusicPlayerRemote.getQueueDurationMillis(MusicPlayerRemote.position))
@ -54,16 +54,16 @@ class PlayingQueueActivity : AbsMusicServiceActivity() {
R.layout.item_queue) R.layout.item_queue)
wrappedAdapter = recyclerViewDragDropManager!!.createWrappedAdapter(playingQueueAdapter!!) wrappedAdapter = recyclerViewDragDropManager!!.createWrappedAdapter(playingQueueAdapter!!)
layoutManager = LinearLayoutManager(this) linearLayoutManager = LinearLayoutManager(this)
recyclerView.apply { recyclerView.apply {
layoutManager = layoutManager layoutManager = linearLayoutManager
adapter = wrappedAdapter adapter = wrappedAdapter
itemAnimator = animator itemAnimator = animator
recyclerViewDragDropManager!!.attachRecyclerView(this) recyclerViewDragDropManager!!.attachRecyclerView(this)
} }
layoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0) linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
@ -109,7 +109,7 @@ class PlayingQueueActivity : AbsMusicServiceActivity() {
private fun resetToCurrentPosition() { private fun resetToCurrentPosition() {
recyclerView.stopScroll() recyclerView.stopScroll()
layoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0) linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
} }
override fun onPause() { override fun onPause() {

View file

@ -1,6 +1,5 @@
package code.name.monkey.retromusic.ui.activities package code.name.monkey.retromusic.ui.activities
import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.AsyncTask import android.os.AsyncTask
import android.os.Bundle import android.os.Bundle
@ -21,10 +20,10 @@ import kotlinx.android.synthetic.main.activity_pro_version_content.*
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
class ProVersionActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler { class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
private var billingProcessor: BillingProcessor? = null private lateinit var billingProcessor: BillingProcessor
private var restorePurchaseAsyncTask: AsyncTask<*, *, *>? = null private var restorePurchaseAsyncTask: AsyncTask<*, *, *>? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -32,7 +31,6 @@ class ProVersionActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
setContentView(R.layout.activity_pro_version) setContentView(R.layout.activity_pro_version)
setDrawUnderStatusBar() setDrawUnderStatusBar()
setStatusbarColorAuto() setStatusbarColorAuto()
setNavigationbarColorAuto() setNavigationbarColorAuto()
setTaskDescriptionColorAuto() setTaskDescriptionColorAuto()
@ -52,7 +50,7 @@ class ProVersionActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
restoreButton.isEnabled = false restoreButton.isEnabled = false
purchaseButton.isEnabled = false purchaseButton.isEnabled = false
billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSE_KEY, this) billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSING_KEY, this)
MaterialUtil.setTint(restoreButton, false) MaterialUtil.setTint(restoreButton, false)
MaterialUtil.setTint(purchaseButton, true) MaterialUtil.setTint(purchaseButton, true)
@ -64,7 +62,7 @@ class ProVersionActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
} }
purchaseButton.setOnClickListener { purchaseButton.setOnClickListener {
billingProcessor!!.purchase(this@ProVersionActivity, App.PRO_VERSION_PRODUCT_ID) billingProcessor.purchase(this@PurchaseActivity, App.PRO_VERSION_PRODUCT_ID)
} }
} }
@ -78,14 +76,13 @@ class ProVersionActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
override fun onProductPurchased(productId: String, details: TransactionDetails?) { override fun onProductPurchased(productId: String, details: TransactionDetails?) {
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show() Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show()
setResult(Activity.RESULT_OK) setResult(RESULT_OK)
} }
override fun onPurchaseHistoryRestored() { override fun onPurchaseHistoryRestored() {
if (App.isProVersion) { if (App.isProVersion) {
Toast.makeText(this, R.string.restored_previous_purchase_please_restart, Toast.LENGTH_LONG) Toast.makeText(this, R.string.restored_previous_purchase_please_restart, Toast.LENGTH_LONG).show()
.show() setResult(RESULT_OK)
setResult(Activity.RESULT_OK)
} else { } else {
Toast.makeText(this, R.string.no_purchase_found, Toast.LENGTH_SHORT).show() Toast.makeText(this, R.string.no_purchase_found, Toast.LENGTH_SHORT).show()
} }
@ -103,7 +100,7 @@ class ProVersionActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (!billingProcessor!!.handleActivityResult(requestCode, resultCode, data)) { if (!billingProcessor.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
} }
} }
@ -116,15 +113,13 @@ class ProVersionActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
} }
override fun onDestroy() { override fun onDestroy() {
if (billingProcessor != null) { billingProcessor.release()
billingProcessor!!.release()
}
super.onDestroy() super.onDestroy()
} }
private class RestorePurchaseAsyncTask internal constructor(purchaseActivity: ProVersionActivity) : AsyncTask<Void, Void, Boolean>() { private class RestorePurchaseAsyncTask internal constructor(purchaseActivity: PurchaseActivity) : AsyncTask<Void, Void, Boolean>() {
private val buyActivityWeakReference: WeakReference<ProVersionActivity> = WeakReference(purchaseActivity) private val buyActivityWeakReference: WeakReference<PurchaseActivity> = WeakReference(purchaseActivity)
override fun onPreExecute() { override fun onPreExecute() {
super.onPreExecute() super.onPreExecute()
@ -139,7 +134,7 @@ class ProVersionActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
override fun doInBackground(vararg params: Void): Boolean? { override fun doInBackground(vararg params: Void): Boolean? {
val purchaseActivity = buyActivityWeakReference.get() val purchaseActivity = buyActivityWeakReference.get()
if (purchaseActivity != null) { if (purchaseActivity != null) {
return purchaseActivity.billingProcessor!!.loadOwnedPurchasesFromGoogle() return purchaseActivity.billingProcessor.loadOwnedPurchasesFromGoogle()
} }
cancel(false) cancel(false)
return null return null
@ -161,7 +156,6 @@ class ProVersionActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
} }
companion object { companion object {
private const val TAG: String = "PurchaseActivity"
private val TAG: String = "ProVersionActivity"
} }
} }

View file

@ -55,7 +55,7 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, SearchCon
if (intent.getBooleanExtra("mic_search", false)) { if (intent.getBooleanExtra("mic_search", false)) {
startMicSearch() startMicSearch()
} }
back.setOnClickListener { onBackPressed() }
voiceSearch.setOnClickListener { startMicSearch() } voiceSearch.setOnClickListener { startMicSearch() }
} }
@ -83,7 +83,7 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, SearchCon
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
searchPresenter!!.subscribe() searchPresenter!!.subscribe()
searchPresenter!!.search(query!!) searchPresenter!!.search(query)
} }
override fun onDestroy() { override fun onDestroy() {

View file

@ -1,7 +1,10 @@
package code.name.monkey.retromusic.ui.activities package code.name.monkey.retromusic.ui.activities
import android.app.Activity
import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.MenuItem import android.view.MenuItem
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.annotation.StringRes import androidx.annotation.StringRes
@ -9,13 +12,16 @@ import androidx.fragment.app.Fragment
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity
import code.name.monkey.retromusic.ui.fragments.settings.MainSettingsFragment import code.name.monkey.retromusic.ui.fragments.settings.MainSettingsFragment
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.color.ColorChooserDialog import com.afollestad.materialdialogs.color.ColorChooserDialog
import kotlinx.android.synthetic.main.activity_settings.* import kotlinx.android.synthetic.main.activity_settings.*
class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback, SharedPreferences.OnSharedPreferenceChangeListener { class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback, SharedPreferences.OnSharedPreferenceChangeListener {
private val fragmentManager = supportFragmentManager private val fragmentManager = supportFragmentManager
@ -32,6 +38,8 @@ class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback, Sh
} }
R.string.accent_color -> ThemeStore.editTheme(this).accentColor(selectedColor).commit() R.string.accent_color -> ThemeStore.editTheme(this).accentColor(selectedColor).commit()
} }
if (VersionUtils.hasNougatMR())
DynamicShortcutManager(this).updateDynamicShortcuts()
recreate() recreate()
} }
@ -116,6 +124,7 @@ class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback, Sh
} }
} }
companion object { companion object {
const val TAG: String = "SettingsActivity" const val TAG: String = "SettingsActivity"
} }

View file

@ -70,7 +70,7 @@ class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingH
setupToolbar() setupToolbar()
billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSE_KEY, this) billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSING_KEY, this)
TintHelper.setTint(progress, ThemeStore.accentColor(this)) TintHelper.setTint(progress, ThemeStore.accentColor(this))
donation.setTextColor(ThemeStore.accentColor(this)) donation.setTextColor(ThemeStore.accentColor(this))
donate.setOnClickListener { donate.setOnClickListener {

View file

@ -12,6 +12,7 @@ import android.text.TextUtils
import android.view.MenuItem import android.view.MenuItem
import android.widget.Toast import android.widget.Toast
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.Constants.USER_BANNER import code.name.monkey.retromusic.Constants.USER_BANNER
import code.name.monkey.retromusic.Constants.USER_PROFILE import code.name.monkey.retromusic.Constants.USER_PROFILE
@ -32,13 +33,11 @@ import java.util.*
class UserInfoActivity : AbsBaseActivity() { class UserInfoActivity : AbsBaseActivity() {
private var disposable: CompositeDisposable? = null private var disposable = CompositeDisposable()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_user_info) setContentView(R.layout.activity_user_info)
setStatusbarColorAuto() setStatusbarColorAuto()
setNavigationbarColorAuto() setNavigationbarColorAuto()
setTaskDescriptionColorAuto() setTaskDescriptionColorAuto()
@ -46,8 +45,6 @@ class UserInfoActivity : AbsBaseActivity() {
setupToolbar() setupToolbar()
disposable = CompositeDisposable()
bannerTitle.setTextColor(ThemeStore.textColorPrimary(this)) bannerTitle.setTextColor(ThemeStore.textColorPrimary(this))
nameContainer.boxStrokeColor = ThemeStore.accentColor(this) nameContainer.boxStrokeColor = ThemeStore.accentColor(this)
name!!.setText(PreferenceUtil.getInstance().userName) name!!.setText(PreferenceUtil.getInstance().userName)
@ -58,7 +55,7 @@ class UserInfoActivity : AbsBaseActivity() {
if (!PreferenceUtil.getInstance().bannerImage.isEmpty()) { if (!PreferenceUtil.getInstance().bannerImage.isEmpty()) {
loadBannerFromStorage(PreferenceUtil.getInstance().bannerImage) loadBannerFromStorage(PreferenceUtil.getInstance().bannerImage)
} }
bannerImage.setOnClickListener { userImage.setOnClickListener {
MaterialDialog.Builder(this) MaterialDialog.Builder(this)
.title("Set a profile photo") .title("Set a profile photo")
.items(Arrays.asList(getString(R.string.new_profile_photo), getString(R.string.remove_profile_photo))) .items(Arrays.asList(getString(R.string.new_profile_photo), getString(R.string.remove_profile_photo)))
@ -82,6 +79,7 @@ class UserInfoActivity : AbsBaseActivity() {
setResult(Activity.RESULT_OK) setResult(Activity.RESULT_OK)
finish() finish()
} }
TintHelper.setTintAuto(next, ThemeStore.accentColor(this), true)
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
@ -96,11 +94,11 @@ class UserInfoActivity : AbsBaseActivity() {
toolbar.apply { toolbar.apply {
setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp) setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
setBackgroundColor(primaryColor) setBackgroundColor(primaryColor)
ToolbarContentTintHelper.colorBackButton(this, ThemeStore.accentColor(this@UserInfoActivity))
setSupportActionBar(this)
} }
appBarLayout.setBackgroundColor(primaryColor) appBarLayout.setBackgroundColor(primaryColor)
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this))
title = null title = null
setSupportActionBar(toolbar)
} }
private fun showBannerOptions() { private fun showBannerOptions() {
@ -226,8 +224,8 @@ class UserInfoActivity : AbsBaseActivity() {
companion object { companion object {
private val PICK_IMAGE_REQUEST = 9002 private const val PICK_IMAGE_REQUEST = 9002
private val PICK_BANNER_REQUEST = 9003 private const val PICK_BANNER_REQUEST = 9003
private val PROFILE_ICON_SIZE = 400 private const val PROFILE_ICON_SIZE = 400
} }
} }

View file

@ -0,0 +1,94 @@
package code.name.monkey.retromusic.ui.activities;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.webkit.WebView;
import android.widget.TextView;
import com.afollestad.materialdialogs.internal.ThemeSingleton;
import com.google.android.material.appbar.AppBarLayout;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import code.name.monkey.appthemehelper.ThemeStore;
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.ui.activities.base.AbsBaseActivity;
import code.name.monkey.retromusic.util.PreferenceUtil;
public class WhatsNewActivity extends AbsBaseActivity {
WebView webView;
TextView title;
Toolbar toolbar;
AppBarLayout appBarLayout;
private static void setChangelogRead(@NonNull Context context) {
try {
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
int currentVersion = pInfo.versionCode;
PreferenceUtil.getInstance().setLastChangeLogVersion(currentVersion);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
private static String colorToHex(int color) {
return Integer.toHexString(color).substring(2);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_whats_new);
webView = findViewById(R.id.webView);
title = findViewById(R.id.bannerTitle);
toolbar = findViewById(R.id.toolbar);
appBarLayout= findViewById(R.id.appBarLayout);
setStatusbarColorAuto();
setNavigationbarColorAuto();
setTaskDescriptionColorAuto();
toolbar.setBackgroundColor(ThemeStore.primaryColor(this));
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this));
setSupportActionBar(toolbar);
setTitle(null);
toolbar.setNavigationOnClickListener(v -> onBackPressed());
title.setTextColor(ThemeStore.textColorPrimary(this));
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this));
try {
// Load from phonograph-changelog.html in the assets folder
StringBuilder buf = new StringBuilder();
InputStream json = getAssets().open("retro-changelog.html");
BufferedReader in = new BufferedReader(new InputStreamReader(json, "UTF-8"));
String str;
while ((str = in.readLine()) != null)
buf.append(str);
in.close();
// Inject color values for WebView body background and links
final String backgroundColor = colorToHex(ThemeStore.primaryColor(this));
final String contentColor = ThemeSingleton.get().darkTheme ? "#ffffff" : "#000000";
webView.loadData(buf.toString()
.replace("{style-placeholder}",
String.format("body { background-color: %s; color: %s; }", backgroundColor, contentColor))
.replace("{link-color}", colorToHex(ThemeSingleton.get().positiveColor.getDefaultColor()))
.replace("{link-color-active}", colorToHex(ColorUtil.lightenColor(ThemeSingleton.get().positiveColor.getDefaultColor())))
, "text/html", "UTF-8");
} catch (Throwable e) {
webView.loadData("<h1>Unable to load</h1><p>" + e.getLocalizedMessage() + "</p>", "text/html", "UTF-8");
}
setChangelogRead(this);
}
}

View file

@ -1,74 +0,0 @@
package code.name.monkey.retromusic.ui.activities
import android.content.Context
import android.content.pm.PackageManager
import android.os.Bundle
import code.name.monkey.appthemehelper.ThemeStore
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.ui.activities.base.AbsBaseActivity
import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.internal.ThemeSingleton
import kotlinx.android.synthetic.main.activity_whats_new.*
import java.io.BufferedReader
import java.io.InputStreamReader
class WhatsNewActivity : AbsBaseActivity() {
private fun setChangelogRead(context: Context) {
try {
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
val currentVersion = pInfo.versionCode
PreferenceUtil.getInstance().setLastChangeLogVersion(currentVersion)
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
}
}
private fun colorToHex(color: Int): String {
return Integer.toHexString(color).substring(2)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_whats_new)
setStatusbarColorAuto()
setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
toolbar.setBackgroundColor(ThemeStore.primaryColor(this))
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this))
setSupportActionBar(toolbar)
title = null
toolbar.setNavigationOnClickListener { onBackPressed() }
whatNewtitle.setTextColor(ThemeStore.textColorPrimary(this))
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this))
try {
val buf = StringBuilder()
val json = assets.open("retro-changelog.html")
val inputStream = BufferedReader(InputStreamReader(json, "UTF-8"))
while (inputStream.readLine() != null) {
buf.append(inputStream.readLine())
}
inputStream.close()
// Inject color values for WebView body background and links
val backgroundColor = colorToHex(ThemeStore.primaryColor(this))
val contentColor = if (ThemeSingleton.get().darkTheme) "#ffffff" else "#000000"
webView.loadData(buf.toString()
.replace("{style-placeholder}",
String.format("body { background-color: %s; color: %s; }", backgroundColor, contentColor))
.replace("{link-color}", colorToHex(ThemeSingleton.get().positiveColor.defaultColor))
.replace("{link-color-active}", colorToHex(ColorUtil.lightenColor(ThemeSingleton.get().positiveColor.defaultColor))), "text/html", "UTF-8")
} catch (e: Throwable) {
webView.loadData("<h1>Unable to load</h1><p>" + e.localizedMessage + "</p>", "text/html", "UTF-8")
}
setChangelogRead(this)
}
}

View file

@ -10,7 +10,7 @@ import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability import com.google.android.gms.common.GoogleApiAvailability
import java.io.IOException import java.io.IOException
abstract class AbsCastActivity : AbsBaseActivity() { abstract class AbsCastActivity : AbsCheckPiracy() {
var playServicesAvailable = false var playServicesAvailable = false

View file

@ -0,0 +1,10 @@
package code.name.monkey.retromusic.ui.activities.base;
abstract public class AbsCheckPiracy extends AbsBaseActivity {
@Override
protected void onStart() {
super.onStart();
}
}

View file

@ -10,6 +10,7 @@ import android.view.ViewTreeObserver
import androidx.annotation.FloatRange import androidx.annotation.FloatRange
import androidx.annotation.LayoutRes import androidx.annotation.LayoutRes
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
@ -33,17 +34,14 @@ import code.name.monkey.retromusic.views.BottomNavigationBarTinted
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
import com.sothree.slidinguppanel.SlidingUpPanelLayout import com.sothree.slidinguppanel.SlidingUpPanelLayout
import com.sothree.slidinguppanel.SlidingUpPanelLayout.PanelState import com.sothree.slidinguppanel.SlidingUpPanelLayout.PanelState
import kotlinx.android.synthetic.main.sliding_music_panel_layout.*
abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicServiceActivity(), SlidingUpPanelLayout.PanelSlideListener, AbsPlayerFragment.Callbacks { abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicServiceActivity(), SlidingUpPanelLayout.PanelSlideListener, AbsPlayerFragment.Callbacks {
lateinit var slidingUpPanelLayout: SlidingUpPanelLayout
private lateinit var bottomNavigationView: BottomNavigationBarTinted
private var miniPlayerFragment: MiniPlayerFragment? = null private var miniPlayerFragment: MiniPlayerFragment? = null
var playerFragment: AbsPlayerFragment? = null private var playerFragment: AbsPlayerFragment? = null
private var currentNowPlayingScreen: NowPlayingScreen? = null private var currentNowPlayingScreen: NowPlayingScreen? = null
private var navigationbarColor: Int = 0 private var navigationbarColor: Int = 0
private var taskColor: Int = 0 private var taskColor: Int = 0
private var lightStatusbar: Boolean = false private var lightStatusbar: Boolean = false
@ -52,7 +50,7 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
private val argbEvaluator = ArgbEvaluator() private val argbEvaluator = ArgbEvaluator()
val panelState: SlidingUpPanelLayout.PanelState? val panelState: SlidingUpPanelLayout.PanelState?
get() = slidingUpPanelLayout.panelState get() = slidingLayout.panelState
private val isOneOfTheseThemes: Boolean private val isOneOfTheseThemes: Boolean
get() = (currentNowPlayingScreen == NowPlayingScreen.ADAPTIVE) get() = (currentNowPlayingScreen == NowPlayingScreen.ADAPTIVE)
@ -61,8 +59,6 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(createContentView()) setContentView(createContentView())
slidingUpPanelLayout = findViewById(R.id.sliding_layout);
bottomNavigationView = findViewById(R.id.bottom_navigation);
chooseFragmentForTheme() chooseFragmentForTheme()
setupSlidingUpPanel() setupSlidingUpPanel()
@ -78,9 +74,9 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
override fun onServiceConnected() { override fun onServiceConnected() {
super.onServiceConnected() super.onServiceConnected()
if (!MusicPlayerRemote.playingQueue.isEmpty()) { if (!MusicPlayerRemote.playingQueue.isEmpty()) {
slidingUpPanelLayout.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { slidingLayout.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() { override fun onGlobalLayout() {
slidingUpPanelLayout.viewTreeObserver.removeOnGlobalLayoutListener(this) slidingLayout.viewTreeObserver.removeOnGlobalLayoutListener(this)
hideBottomBar(false) hideBottomBar(false)
} }
}) })
@ -97,11 +93,11 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
val heightOfBarWithTabs = resources.getDimensionPixelSize(R.dimen.mini_player_height_expanded) val heightOfBarWithTabs = resources.getDimensionPixelSize(R.dimen.mini_player_height_expanded)
if (hide) { if (hide) {
slidingUpPanelLayout.panelHeight = 0 slidingLayout.panelHeight = 0
collapsePanel() collapsePanel()
} else { } else {
if (!MusicPlayerRemote.playingQueue.isEmpty()) { if (!MusicPlayerRemote.playingQueue.isEmpty()) {
slidingUpPanelLayout.panelHeight = if (bottomNavigationView.visibility == View.VISIBLE) heightOfBarWithTabs else heightOfBar slidingLayout.panelHeight = if (bottomNavigationView.visibility == View.VISIBLE) heightOfBarWithTabs else heightOfBar
} }
} }
} }
@ -109,7 +105,7 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
protected fun wrapSlidingMusicPanel(@LayoutRes resId: Int): View { protected fun wrapSlidingMusicPanel(@LayoutRes resId: Int): View {
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
val slidingMusicPanelLayout = layoutInflater.inflate(R.layout.sliding_music_panel_layout, null) val slidingMusicPanelLayout = layoutInflater.inflate(R.layout.sliding_music_panel_layout, null)
val contentContainer = slidingMusicPanelLayout.findViewById<ViewGroup>(R.id.content_container) val contentContainer = slidingMusicPanelLayout.findViewById<ViewGroup>(R.id.mainContentFrame)
layoutInflater.inflate(resId, contentContainer) layoutInflater.inflate(resId, contentContainer)
return slidingMusicPanelLayout return slidingMusicPanelLayout
} }
@ -120,7 +116,7 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
} }
open fun handleBackPress(): Boolean { open fun handleBackPress(): Boolean {
if (slidingUpPanelLayout.panelHeight != 0 && playerFragment!!.onBackPressed()) if (slidingLayout.panelHeight != 0 && playerFragment!!.onBackPressed())
return true return true
if (panelState == SlidingUpPanelLayout.PanelState.EXPANDED) { if (panelState == SlidingUpPanelLayout.PanelState.EXPANDED) {
collapsePanel() collapsePanel()
@ -140,18 +136,18 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
bottomNavigationView.visibility = if (toggle) View.GONE else View.VISIBLE bottomNavigationView.visibility = if (toggle) View.GONE else View.VISIBLE
} }
fun getBottomNavigationView(): BottomNavigationView? { fun getBottomNavigationView(): BottomNavigationBarTinted? {
return bottomNavigationView return bottomNavigationView
} }
private fun setupSlidingUpPanel() { private fun setupSlidingUpPanel() {
slidingUpPanelLayout.viewTreeObserver slidingLayout.viewTreeObserver
.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { .addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() { override fun onGlobalLayout() {
slidingUpPanelLayout.viewTreeObserver.removeOnGlobalLayoutListener(this) slidingLayout.viewTreeObserver.removeOnGlobalLayoutListener(this)
if (panelState == PanelState.EXPANDED) { if (panelState == PanelState.EXPANDED) {
onPanelSlide(slidingUpPanelLayout, 1f) onPanelSlide(slidingLayout, 1f)
onPanelExpanded() onPanelExpanded()
} else if (panelState == PanelState.COLLAPSED) { } else if (panelState == PanelState.COLLAPSED) {
onPanelCollapsed() onPanelCollapsed()
@ -161,7 +157,7 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
} }
}) })
slidingUpPanelLayout.addPanelSlideListener(this) slidingLayout.addPanelSlideListener(this)
} }
@ -180,7 +176,7 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
} }
} }
fun onPanelCollapsed() { open fun onPanelCollapsed() {
// restore values // restore values
super.setLightStatusbar(lightStatusbar) super.setLightStatusbar(lightStatusbar)
super.setTaskDescriptionColor(taskColor) super.setTaskDescriptionColor(taskColor)
@ -193,7 +189,7 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
playerFragment!!.onHide() playerFragment!!.onHide()
} }
fun onPanelExpanded() { open fun onPanelExpanded() {
val playerFragmentColor = playerFragment!!.paletteColor val playerFragmentColor = playerFragment!!.paletteColor
super.setTaskDescriptionColor(playerFragmentColor) super.setTaskDescriptionColor(playerFragmentColor)
@ -229,11 +225,11 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
NowPlayingScreen.COLOR -> ColorFragment() NowPlayingScreen.COLOR -> ColorFragment()
else -> PlayerFragment() else -> PlayerFragment()
} // must implement AbsPlayerFragment } // must implement AbsPlayerFragment
supportFragmentManager.beginTransaction().replace(R.id.player_fragment_container, fragment).commit() supportFragmentManager.beginTransaction().replace(R.id.playerFragmentContainer, fragment).commit()
supportFragmentManager.executePendingTransactions() supportFragmentManager.executePendingTransactions()
playerFragment = supportFragmentManager.findFragmentById(R.id.player_fragment_container) as AbsPlayerFragment playerFragment = supportFragmentManager.findFragmentById(R.id.playerFragmentContainer) as AbsPlayerFragment
miniPlayerFragment = supportFragmentManager.findFragmentById(R.id.mini_player_fragment) as MiniPlayerFragment miniPlayerFragment = supportFragmentManager.findFragmentById(R.id.miniPlayerFragment) as MiniPlayerFragment
miniPlayerFragment!!.view!!.setOnClickListener { expandPanel() } miniPlayerFragment!!.view!!.setOnClickListener { expandPanel() }
} }
@ -246,11 +242,11 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
} }
private fun collapsePanel() { private fun collapsePanel() {
slidingUpPanelLayout.panelState = PanelState.COLLAPSED slidingLayout.panelState = PanelState.COLLAPSED
} }
private fun expandPanel() { private fun expandPanel() {
slidingUpPanelLayout.panelState = PanelState.EXPANDED slidingLayout.panelState = PanelState.EXPANDED
} }
@ -265,9 +261,17 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
super.setLightNavigationBar(true) super.setLightNavigationBar(true)
super.setLightStatusbar(isColorLight) super.setLightStatusbar(isColorLight)
} else if (currentNowPlayingScreen == NowPlayingScreen.FULL || currentNowPlayingScreen == NowPlayingScreen.CARD || } else if (currentNowPlayingScreen == NowPlayingScreen.FULL || currentNowPlayingScreen == NowPlayingScreen.CARD ||
currentNowPlayingScreen == NowPlayingScreen.FIT ||
currentNowPlayingScreen == NowPlayingScreen.BLUR || currentNowPlayingScreen == NowPlayingScreen.BLUR_CARD) { currentNowPlayingScreen == NowPlayingScreen.BLUR || currentNowPlayingScreen == NowPlayingScreen.BLUR_CARD) {
super.setLightStatusbar(false) super.setLightStatusbar(false)
super.setLightNavigationBar(true) super.setLightNavigationBar(true)
} else if (currentNowPlayingScreen == NowPlayingScreen.COLOR) {
super.setNavigationbarColor(paletteColor)
super.setLightNavigationBar(isColorLight)
super.setLightStatusbar(isColorLight)
} else {
super.setLightStatusbar(ColorUtil.isColorLight(ThemeStore.primaryColor(this)))
super.setLightNavigationBar(true)
} }
} }
} }

View file

@ -2,7 +2,6 @@ package code.name.monkey.retromusic.ui.activities.base
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.view.KeyEvent import android.view.KeyEvent
@ -101,7 +100,7 @@ abstract class AbsThemeActivity : ATHActivity(), Runnable {
VersionUtils.hasLollipop() -> statusBar.setBackgroundColor(ColorUtil.darkenColor(color)) VersionUtils.hasLollipop() -> statusBar.setBackgroundColor(ColorUtil.darkenColor(color))
else -> statusBar.setBackgroundColor(color) else -> statusBar.setBackgroundColor(color)
} }
} else if (Build.VERSION.SDK_INT >= 21) { } else {
when { when {
VersionUtils.hasMarshmallow() -> window.statusBarColor = color VersionUtils.hasMarshmallow() -> window.statusBarColor = color
else -> window.statusBarColor = ColorUtil.darkenColor(color) else -> window.statusBarColor = ColorUtil.darkenColor(color)

View file

@ -59,7 +59,7 @@ open class MediaEntryViewHolder(w: View) : RecyclerView.ViewHolder(w), View.OnCl
recyclerView = w.findViewById(R.id.recycler_view) recyclerView = w.findViewById(R.id.recycler_view)
mask = w.findViewById(R.id.mask) mask = w.findViewById(R.id.mask)
playSongs = w.findViewById(R.id.play_songs) playSongs = w.findViewById(R.id.playSongs)
w.setOnClickListener(this) w.setOnClickListener(this)
w.setOnLongClickListener(this) w.setOnLongClickListener(this)

View file

@ -177,6 +177,7 @@ open class SongAdapter @JvmOverloads constructor(protected val activity: AppComp
init { init {
setImageTransitionName(activity.getString(R.string.transition_album_art)) setImageTransitionName(activity.getString(R.string.transition_album_art))
if (menu != null) {
menu!!.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) { menu!!.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
override val song: Song override val song: Song
get() = this@ViewHolder.song get() = this@ViewHolder.song
@ -189,6 +190,7 @@ open class SongAdapter @JvmOverloads constructor(protected val activity: AppComp
} }
}) })
} }
}
protected open fun onSongMenuItemClick(item: MenuItem): Boolean { protected open fun onSongMenuItemClick(item: MenuItem): Boolean {
if (image != null && image!!.visibility == View.VISIBLE) { if (image != null && image!!.visibility == View.VISIBLE) {

View file

@ -9,17 +9,18 @@ enum class NowPlayingScreen constructor(@param:StringRes @field:StringRes
val titleRes: Int, val titleRes: Int,
@param:DrawableRes @field:DrawableRes val drawableResId: Int, @param:DrawableRes @field:DrawableRes val drawableResId: Int,
val id: Int) { val id: Int) {
NORMAL(R.string.normal, R.drawable.np_normal, 0), ADAPTIVE(R.string.adaptive, R.drawable.np_adaptive, 10),
BLUR(R.string.blur, R.drawable.np_blur, 4),
BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9),
CARD(R.string.card, R.drawable.np_card, 6),
COLOR(R.string.color, R.drawable.np_color, 5),
FIT(R.string.fit, R.drawable.np_adaptive, 12),
FLAT(R.string.flat, R.drawable.np_flat, 1), FLAT(R.string.flat, R.drawable.np_flat, 1),
FULL(R.string.full, R.drawable.np_full, 2), FULL(R.string.full, R.drawable.np_full, 2),
PLAIN(R.string.plain, R.drawable.np_plain, 3),
BLUR(R.string.blur, R.drawable.np_blur, 4),
COLOR(R.string.color, R.drawable.np_color, 5),
CARD(R.string.card, R.drawable.np_card, 6),
//TINY(R.string.tiny, R.drawable.np_tiny, 7),
SIMPLE(R.string.simple, R.drawable.np_simple, 8),
BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9),
ADAPTIVE(R.string.adaptive, R.drawable.np_adaptive, 10),
MATERIAL(R.string.material, R.drawable.np_material, 11), MATERIAL(R.string.material, R.drawable.np_material, 11),
FIT(R.string.fit, R.drawable.np_adaptive, 12) NORMAL(R.string.normal, R.drawable.np_normal, 0),
PLAIN(R.string.plain, R.drawable.np_plain, 3),
//TINY(R.string.tiny, R.drawable.np_tiny, 7),
SIMPLE(R.string.simple, R.drawable.np_simple, 8)
} }

View file

@ -1,7 +1,6 @@
package code.name.monkey.retromusic.ui.fragments.base package code.name.monkey.retromusic.ui.fragments.base
import android.os.Bundle import android.os.Bundle
import code.name.monkey.retromusic.ui.fragments.mainactivity.LibraryFragment import code.name.monkey.retromusic.ui.fragments.mainactivity.LibraryFragment
open class AbsLibraryPagerFragment : AbsMusicServiceFragment() { open class AbsLibraryPagerFragment : AbsMusicServiceFragment() {

View file

@ -41,15 +41,15 @@ abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A : RecyclerVie
activity!!.resources.getInteger(R.integer.default_list_columns_land) activity!!.resources.getInteger(R.integer.default_list_columns_land)
} else activity!!.resources.getInteger(R.integer.default_list_columns) } else activity!!.resources.getInteger(R.integer.default_list_columns)
protected val isLandscape: Boolean private val isLandscape: Boolean
get() = RetroUtil.isLandscape() get() = RetroUtil.isLandscape()
fun getGridSize(): Int { fun getGridSize(): Int {
if (gridSize == 0) { if (gridSize == 0) {
if (isLandscape) { gridSize = if (isLandscape) {
gridSize = loadGridSizeLand() loadGridSizeLand()
} else { } else {
gridSize = loadGridSize() loadGridSize()
} }
} }
return gridSize return gridSize

View file

@ -0,0 +1,461 @@
package code.name.monkey.retromusic.ui.fragments.mainactivity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.afollestad.materialcab.MaterialCab;
import com.google.android.material.appbar.AppBarLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.common.ATHToolbarActivity;
import code.name.monkey.appthemehelper.util.ATHUtil;
import code.name.monkey.appthemehelper.util.TintHelper;
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog;
import code.name.monkey.retromusic.dialogs.SleepTimerDialog;
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
import code.name.monkey.retromusic.helper.SortOrder;
import code.name.monkey.retromusic.interfaces.CabHolder;
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks;
import code.name.monkey.retromusic.loaders.SongLoader;
import code.name.monkey.retromusic.ui.activities.SettingsActivity;
import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment;
import code.name.monkey.retromusic.ui.fragments.base.AbsMainActivityFragment;
import code.name.monkey.retromusic.util.NavigationUtil;
import code.name.monkey.retromusic.util.RetroColorUtil;
import code.name.monkey.retromusic.util.RetroUtil;
public class LibraryFragment extends AbsMainActivityFragment implements CabHolder, MainActivityFragmentCallbacks {
public static final String TAG = "LibraryFragment";
private static final String CURRENT_TAB_ID = "current_tab_id";
private Toolbar toolbar;
private AppBarLayout appBarLayout;
private TextView bannerTitle;
private View contentContainer;
private MaterialCab cab;
private FragmentManager fragmentManager;
public static Fragment newInstance(int tab) {
Bundle args = new Bundle();
args.putInt(CURRENT_TAB_ID, tab);
LibraryFragment fragment = new LibraryFragment();
fragment.setArguments(args);
return fragment;
}
public static Fragment newInstance() {
return new LibraryFragment();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_library, container, false);
contentContainer = view.findViewById(R.id.fragmentContainer);
bannerTitle = view.findViewById(R.id.bannerTitle);
appBarLayout = view.findViewById(R.id.appBarLayout);
toolbar = view.findViewById(R.id.toolbar);
return view;
}
public void setTitle(@StringRes int name) {
bannerTitle.setText(getString(name));
}
public void addOnAppBarOffsetChangedListener(AppBarLayout.OnOffsetChangedListener onOffsetChangedListener) {
appBarLayout.addOnOffsetChangedListener(onOffsetChangedListener);
}
public void removeOnAppBarOffsetChangedListener(AppBarLayout.OnOffsetChangedListener onOffsetChangedListener) {
appBarLayout.removeOnOffsetChangedListener(onOffsetChangedListener);
}
public int getTotalAppBarScrollingRange() {
return appBarLayout.getTotalScrollRange();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setStatusbarColorAuto(view);
setupToolbar();
inflateFragment();
}
private void inflateFragment() {
if (getArguments() == null) {
selectedFragment(SongsFragment.Companion.newInstance());
return;
}
switch (getArguments().getInt(CURRENT_TAB_ID)) {
default:
case R.id.action_song:
selectedFragment(SongsFragment.Companion.newInstance());
break;
case R.id.action_album:
selectedFragment(AlbumsFragment.Companion.newInstance());
break;
case R.id.action_artist:
selectedFragment(ArtistsFragment.Companion.newInstance());
break;
case R.id.action_playlist:
selectedFragment(PlaylistsFragment.Companion.newInstance());
break;
}
}
@SuppressWarnings("ConstantConditions")
private void setupToolbar() {
bannerTitle.setTextColor(ThemeStore.textColorPrimary(getContext()));
int primaryColor = ThemeStore.primaryColor(getContext());
TintHelper.setTintAuto(contentContainer, primaryColor, true);
toolbar.setBackgroundColor(primaryColor);
toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp);
appBarLayout.setBackgroundColor(primaryColor);
appBarLayout.addOnOffsetChangedListener((appBarLayout, verticalOffset) ->
getMainActivity().setLightStatusbar(!ATHUtil.isWindowBackgroundDark(getContext())));
getMainActivity().setTitle(null);
getMainActivity().setSupportActionBar(toolbar);
}
private Fragment getCurrentFragment() {
if (fragmentManager == null) {
return SongsFragment.Companion.newInstance();
}
return fragmentManager.findFragmentByTag(LibraryFragment.TAG);
}
@Override
public boolean handleBackPress() {
if (cab != null && cab.isActive()) {
cab.finish();
return true;
}
return false;
}
private void selectedFragment(Fragment fragment) {
fragmentManager = getChildFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction
.replace(R.id.fragmentContainer, fragment, TAG)
.commit();
}
@NonNull
@Override
public MaterialCab openCab(int menuRes, MaterialCab.Callback callback) {
if (cab != null && cab.isActive()) {
cab.finish();
}
//noinspection ConstantConditions
cab = new MaterialCab(getMainActivity(), R.id.cab_stub)
.setMenu(menuRes)
.setCloseDrawableRes(R.drawable.ic_close_white_24dp)
.setBackgroundColor(
RetroColorUtil.shiftBackgroundColorForLightText(ThemeStore.primaryColor(getActivity())))
.start(callback);
return cab;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_main, menu);
Fragment currentFragment = getCurrentFragment();
if (currentFragment instanceof AbsLibraryPagerRecyclerViewCustomGridSizeFragment
&& currentFragment.isAdded()) {
AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment = (AbsLibraryPagerRecyclerViewCustomGridSizeFragment) currentFragment;
MenuItem gridSizeItem = menu.findItem(R.id.action_grid_size);
if (RetroUtil.isLandscape()) {
gridSizeItem.setTitle(R.string.action_grid_size_land);
}
setUpGridSizeMenu(fragment, gridSizeItem.getSubMenu());
setUpSortOrderMenu(fragment, menu.findItem(R.id.action_sort_order).getSubMenu());
} else {
menu.add(0, R.id.action_new_playlist, 0, R.string.new_playlist_title);
menu.removeItem(R.id.action_grid_size);
}
Activity activity = getActivity();
if (activity == null) {
return;
}
ToolbarContentTintHelper.handleOnCreateOptionsMenu(getActivity(), toolbar, menu, ATHToolbarActivity.getToolbarBackgroundColor(toolbar));
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
Activity activity = getActivity();
if (activity == null) {
return;
}
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(activity, toolbar);
}
private void setUpSortOrderMenu(
@NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment,
@NonNull SubMenu sortOrderMenu) {
String currentSortOrder = fragment.getSortOrder();
sortOrderMenu.clear();
if (fragment instanceof AlbumsFragment) {
sortOrderMenu.add(0, R.id.action_album_sort_order_asc, 0, R.string.sort_order_a_z)
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_A_Z));
sortOrderMenu.add(0, R.id.action_album_sort_order_desc, 1, R.string.sort_order_z_a)
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_Z_A));
sortOrderMenu.add(0, R.id.action_album_sort_order_artist, 2, R.string.sort_order_artist)
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_ARTIST));
sortOrderMenu.add(0, R.id.action_album_sort_order_year, 3, R.string.sort_order_year)
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_YEAR));
} else if (fragment instanceof ArtistsFragment) {
sortOrderMenu.add(0, R.id.action_artist_sort_order_asc, 0, R.string.sort_order_a_z)
.setChecked(currentSortOrder.equals(SortOrder.ArtistSortOrder.ARTIST_A_Z));
sortOrderMenu.add(0, R.id.action_artist_sort_order_desc, 1, R.string.sort_order_z_a)
.setChecked(currentSortOrder.equals(SortOrder.ArtistSortOrder.ARTIST_Z_A));
} else if (fragment instanceof SongsFragment) {
sortOrderMenu.add(0, R.id.action_song_sort_order_asc, 0, R.string.sort_order_a_z)
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_A_Z));
sortOrderMenu.add(0, R.id.action_song_sort_order_desc, 1, R.string.sort_order_z_a)
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_Z_A));
sortOrderMenu.add(0, R.id.action_song_sort_order_artist, 2, R.string.sort_order_artist)
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_ARTIST));
sortOrderMenu.add(0, R.id.action_song_sort_order_album, 3, R.string.sort_order_album)
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_ALBUM));
sortOrderMenu.add(0, R.id.action_song_sort_order_year, 4, R.string.sort_order_year)
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_YEAR));
sortOrderMenu.add(0, R.id.action_song_sort_order_date, 4, R.string.sort_order_date)
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_DATE));
}
sortOrderMenu.setGroupCheckable(0, true, true);
}
private boolean handleSortOrderMenuItem(
@NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment
fragment, @NonNull MenuItem item) {
String sortOrder = null;
if (fragment instanceof AlbumsFragment) {
switch (item.getItemId()) {
case R.id.action_album_sort_order_asc:
sortOrder = SortOrder.AlbumSortOrder.ALBUM_A_Z;
break;
case R.id.action_album_sort_order_desc:
sortOrder = SortOrder.AlbumSortOrder.ALBUM_Z_A;
break;
case R.id.action_album_sort_order_artist:
sortOrder = SortOrder.AlbumSortOrder.ALBUM_ARTIST;
break;
case R.id.action_album_sort_order_year:
sortOrder = SortOrder.AlbumSortOrder.ALBUM_YEAR;
break;
}
} else if (fragment instanceof ArtistsFragment) {
switch (item.getItemId()) {
case R.id.action_artist_sort_order_asc:
sortOrder = SortOrder.ArtistSortOrder.ARTIST_A_Z;
break;
case R.id.action_artist_sort_order_desc:
sortOrder = SortOrder.ArtistSortOrder.ARTIST_Z_A;
break;
}
} else if (fragment instanceof SongsFragment) {
switch (item.getItemId()) {
case R.id.action_song_sort_order_asc:
sortOrder = SortOrder.SongSortOrder.SONG_A_Z;
break;
case R.id.action_song_sort_order_desc:
sortOrder = SortOrder.SongSortOrder.SONG_Z_A;
break;
case R.id.action_song_sort_order_artist:
sortOrder = SortOrder.SongSortOrder.SONG_ARTIST;
break;
case R.id.action_song_sort_order_album:
sortOrder = SortOrder.SongSortOrder.SONG_ALBUM;
break;
case R.id.action_song_sort_order_year:
sortOrder = SortOrder.SongSortOrder.SONG_YEAR;
break;
case R.id.action_song_sort_order_date:
sortOrder = SortOrder.SongSortOrder.SONG_DATE;
break;
}
}
if (sortOrder != null) {
item.setChecked(true);
fragment.setAndSaveSortOrder(sortOrder);
return true;
}
return false;
}
@SuppressWarnings("ConstantConditions")
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
//if (pager == null) return false;
Fragment currentFragment = getCurrentFragment();
if (currentFragment instanceof AbsLibraryPagerRecyclerViewCustomGridSizeFragment) {
AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment = (AbsLibraryPagerRecyclerViewCustomGridSizeFragment) currentFragment;
if (handleGridSizeMenuItem(fragment, item)) {
return true;
}
if (handleSortOrderMenuItem(fragment, item)) {
return true;
}
}
int id = item.getItemId();
switch (id) {
case R.id.action_new_playlist:
CreatePlaylistDialog.Companion.create().show(getChildFragmentManager(), "CREATE_PLAYLIST");
return true;
case R.id.action_shuffle_all:
MusicPlayerRemote.INSTANCE.openAndShuffleQueue(SongLoader.INSTANCE.getAllSongs(getContext())
.blockingFirst(), true);
return true;
case R.id.action_search:
NavigationUtil.goToSearch(getMainActivity());
break;
case R.id.action_equalizer:
NavigationUtil.openEqualizer(getActivity());
return true;
case R.id.action_sleep_timer:
if (getFragmentManager() != null) {
new SleepTimerDialog().show(getFragmentManager(), TAG);
}
return true;
case R.id.action_settings:
startActivity(new Intent(getContext(), SettingsActivity.class));
break;
}
return super.onOptionsItemSelected(item);
}
private void setUpGridSizeMenu(
@NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment,
@NonNull SubMenu gridSizeMenu) {
switch (fragment.getGridSize()) {
case 1:
gridSizeMenu.findItem(R.id.action_grid_size_1).setChecked(true);
break;
case 2:
gridSizeMenu.findItem(R.id.action_grid_size_2).setChecked(true);
break;
case 3:
gridSizeMenu.findItem(R.id.action_grid_size_3).setChecked(true);
break;
case 4:
gridSizeMenu.findItem(R.id.action_grid_size_4).setChecked(true);
break;
case 5:
gridSizeMenu.findItem(R.id.action_grid_size_5).setChecked(true);
break;
case 6:
gridSizeMenu.findItem(R.id.action_grid_size_6).setChecked(true);
break;
case 7:
gridSizeMenu.findItem(R.id.action_grid_size_7).setChecked(true);
break;
case 8:
gridSizeMenu.findItem(R.id.action_grid_size_8).setChecked(true);
break;
}
int maxGridSize = fragment.getMaxGridSize();
if (maxGridSize < 8) {
gridSizeMenu.findItem(R.id.action_grid_size_8).setVisible(false);
}
if (maxGridSize < 7) {
gridSizeMenu.findItem(R.id.action_grid_size_7).setVisible(false);
}
if (maxGridSize < 6) {
gridSizeMenu.findItem(R.id.action_grid_size_6).setVisible(false);
}
if (maxGridSize < 5) {
gridSizeMenu.findItem(R.id.action_grid_size_5).setVisible(false);
}
if (maxGridSize < 4) {
gridSizeMenu.findItem(R.id.action_grid_size_4).setVisible(false);
}
if (maxGridSize < 3) {
gridSizeMenu.findItem(R.id.action_grid_size_3).setVisible(false);
}
}
private boolean handleGridSizeMenuItem(
@NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment
fragment, @NonNull MenuItem item) {
int gridSize = 0;
switch (item.getItemId()) {
case R.id.action_grid_size_1:
gridSize = 1;
break;
case R.id.action_grid_size_2:
gridSize = 2;
break;
case R.id.action_grid_size_3:
gridSize = 3;
break;
case R.id.action_grid_size_4:
gridSize = 4;
break;
case R.id.action_grid_size_5:
gridSize = 5;
break;
case R.id.action_grid_size_6:
gridSize = 6;
break;
case R.id.action_grid_size_7:
gridSize = 7;
break;
case R.id.action_grid_size_8:
gridSize = 8;
break;
}
if (gridSize > 0) {
item.setChecked(true);
fragment.setAndSaveGridSize(gridSize);
return true;
}
return false;
}
}

View file

@ -1,364 +0,0 @@
package code.name.monkey.retromusic.ui.fragments.mainactivity
import android.content.Intent
import android.os.Bundle
import android.view.*
import android.widget.TextView
import androidx.annotation.StringRes
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.Fragment
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog
import code.name.monkey.retromusic.dialogs.SleepTimerDialog
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder
import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
import code.name.monkey.retromusic.loaders.SongLoader
import code.name.monkey.retromusic.ui.activities.SettingsActivity
import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment
import code.name.monkey.retromusic.ui.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.RetroColorUtil
import code.name.monkey.retromusic.util.RetroUtil
import com.afollestad.materialcab.MaterialCab
import com.google.android.material.appbar.AppBarLayout
class LibraryFragment : AbsMainActivityFragment(), CabHolder, MainActivityFragmentCallbacks, AppBarLayout.OnOffsetChangedListener {
override fun onOffsetChanged(p0: AppBarLayout?, p1: Int) {
mainActivity.setLightStatusbar(!ATHUtil.isWindowBackgroundDark(context))
}
lateinit var toolbar: Toolbar
lateinit var appbar: AppBarLayout
lateinit var title: TextView
lateinit var contentContainer: View
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_library, container, false)
toolbar = view.findViewById(R.id.toolbar)
appbar = view.findViewById(R.id.app_bar)
title = view.findViewById(R.id.title)
contentContainer = view.findViewById(R.id.fragment_container)
return view
}
private var cab: MaterialCab? = null
val totalAppBarScrollingRange: Int
get() = appbar.totalScrollRange
private fun getCurrentFragment(): Fragment? {
return if (fragmentManager == null) {
SongsFragment.newInstance()
} else fragmentManager!!.findFragmentById(R.id.fragment_container)
}
private fun selectedFragment(fragment: Fragment) {
val fragmentManager = childFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction()
fragmentTransaction
.replace(R.id.fragment_container, fragment, TAG)
.commit()
fragmentManager.executePendingTransactions()
}
fun setTitle(@StringRes name: Int) {
title.text = getString(name)
}
fun addOnAppBarOffsetChangedListener(onOffsetChangedListener: AppBarLayout.OnOffsetChangedListener) {
appbar.addOnOffsetChangedListener(onOffsetChangedListener)
}
fun removeOnAppBarOffsetChangedListener(onOffsetChangedListener: AppBarLayout.OnOffsetChangedListener) {
appbar.removeOnOffsetChangedListener(onOffsetChangedListener)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setStatusbarColorAuto(view)
setupToolbar()
inflateFragment()
}
private fun inflateFragment() {
if (arguments == null) {
selectedFragment(SongsFragment.newInstance())
return
}
when (arguments!!.getInt(CURRENT_TAB_ID)) {
R.id.action_song -> selectedFragment(SongsFragment.newInstance())
R.id.action_album -> selectedFragment(AlbumsFragment.newInstance())
R.id.action_artist -> selectedFragment(ArtistsFragment.newInstance())
R.id.action_playlist -> selectedFragment(PlaylistsFragment.newInstance())
else -> selectedFragment(SongsFragment.newInstance())
}
}
private fun setupToolbar() {
title.setTextColor(ThemeStore.textColorPrimary(context!!))
val primaryColor = ThemeStore.primaryColor(context!!)
TintHelper.setTintAuto(contentContainer, primaryColor, true)
toolbar.setBackgroundColor(primaryColor)
appbar.setBackgroundColor(primaryColor)
appbar.addOnOffsetChangedListener(this)
mainActivity.title = null
mainActivity.setSupportActionBar(toolbar)
toolbar.navigationIcon = RetroUtil.getTintedDrawable(mainActivity, R.drawable.ic_menu_white_24dp, ThemeStore.textColorPrimary(mainActivity))
}
override fun handleBackPress(): Boolean {
if (cab != null && cab!!.isActive) {
cab!!.finish()
return true
}
return false
}
override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
if (cab != null && cab!!.isActive) {
cab!!.finish()
}
cab = MaterialCab(mainActivity, R.id.cab_stub)
.setMenu(menuRes)
.setCloseDrawableRes(R.drawable.ic_close_white_24dp)
.setBackgroundColor(
RetroColorUtil.shiftBackgroundColorForLightText(ThemeStore.primaryColor(activity!!)))
.start(callback)
return cab as MaterialCab
}
private fun isPlaylistFragment(): Boolean {
return true
}
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
super.onCreateOptionsMenu(menu, inflater)
inflater!!.inflate(R.menu.menu_main, menu)
if (isPlaylistFragment()) {
menu!!.add(0, R.id.action_new_playlist, 0, R.string.new_playlist_title)
}
val currentFragment = getCurrentFragment()
if (currentFragment is AbsLibraryPagerRecyclerViewCustomGridSizeFragment<*, *> && currentFragment.isAdded) {
val fragment = currentFragment as AbsLibraryPagerRecyclerViewCustomGridSizeFragment<*, *>?
val gridSizeItem = menu!!.findItem(R.id.action_grid_size)
if (RetroUtil.isLandscape()) {
gridSizeItem.setTitle(R.string.action_grid_size_land)
}
setUpGridSizeMenu(fragment!!, gridSizeItem.subMenu)
setUpSortOrderMenu(fragment, menu.findItem(R.id.action_sort_order).subMenu)
} else {
menu!!.removeItem(R.id.action_grid_size)
}
ToolbarContentTintHelper.handleOnCreateOptionsMenu(activity!!, toolbar, menu, ATHToolbarActivity.getToolbarBackgroundColor(toolbar))
}
override fun onPrepareOptionsMenu(menu: Menu?) {
super.onPrepareOptionsMenu(menu)
val activity = activity ?: return
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(activity, toolbar)
}
private fun setUpSortOrderMenu(
fragment: AbsLibraryPagerRecyclerViewCustomGridSizeFragment<*, *>,
sortOrderMenu: SubMenu) {
val currentSortOrder = fragment.getSortOrder()
sortOrderMenu.clear()
when (fragment) {
is AlbumsFragment -> {
sortOrderMenu.add(0, R.id.action_album_sort_order_asc, 0, R.string.sort_order_a_z).isChecked = currentSortOrder == SortOrder.AlbumSortOrder.ALBUM_A_Z
sortOrderMenu.add(0, R.id.action_album_sort_order_desc, 1, R.string.sort_order_z_a).isChecked = currentSortOrder == SortOrder.AlbumSortOrder.ALBUM_Z_A
sortOrderMenu.add(0, R.id.action_album_sort_order_artist, 2, R.string.sort_order_artist).isChecked = currentSortOrder == SortOrder.AlbumSortOrder.ALBUM_ARTIST
sortOrderMenu.add(0, R.id.action_album_sort_order_year, 3, R.string.sort_order_year).isChecked = currentSortOrder == SortOrder.AlbumSortOrder.ALBUM_YEAR
}
is ArtistsFragment -> {
sortOrderMenu.add(0, R.id.action_artist_sort_order_asc, 0, R.string.sort_order_a_z).isChecked = currentSortOrder == SortOrder.ArtistSortOrder.ARTIST_A_Z
sortOrderMenu.add(0, R.id.action_artist_sort_order_desc, 1, R.string.sort_order_z_a).isChecked = currentSortOrder == SortOrder.ArtistSortOrder.ARTIST_Z_A
}
is SongsFragment -> {
sortOrderMenu.add(0, R.id.action_song_sort_order_asc, 0, R.string.sort_order_a_z).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_A_Z
sortOrderMenu.add(0, R.id.action_song_sort_order_desc, 1, R.string.sort_order_z_a).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_Z_A
sortOrderMenu.add(0, R.id.action_song_sort_order_artist, 2, R.string.sort_order_artist).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_ARTIST
sortOrderMenu.add(0, R.id.action_song_sort_order_album, 3, R.string.sort_order_album).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_ALBUM
sortOrderMenu.add(0, R.id.action_song_sort_order_year, 4, R.string.sort_order_year).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_YEAR
sortOrderMenu.add(0, R.id.action_song_sort_order_date, 4, R.string.sort_order_date).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_DATE
}
}
sortOrderMenu.setGroupCheckable(0, true, true)
}
private fun handleSortOrderMenuItem(
fragment: AbsLibraryPagerRecyclerViewCustomGridSizeFragment<*, *>, item: MenuItem): Boolean {
var sortOrder: String? = null
when (fragment) {
is AlbumsFragment -> when (item.itemId) {
R.id.action_album_sort_order_asc -> sortOrder = SortOrder.AlbumSortOrder.ALBUM_A_Z
R.id.action_album_sort_order_desc -> sortOrder = SortOrder.AlbumSortOrder.ALBUM_Z_A
R.id.action_album_sort_order_artist -> sortOrder = SortOrder.AlbumSortOrder.ALBUM_ARTIST
R.id.action_album_sort_order_year -> sortOrder = SortOrder.AlbumSortOrder.ALBUM_YEAR
}
is ArtistsFragment -> when (item.itemId) {
R.id.action_artist_sort_order_asc -> sortOrder = SortOrder.ArtistSortOrder.ARTIST_A_Z
R.id.action_artist_sort_order_desc -> sortOrder = SortOrder.ArtistSortOrder.ARTIST_Z_A
}
is SongsFragment -> when (item.itemId) {
R.id.action_song_sort_order_asc -> sortOrder = SortOrder.SongSortOrder.SONG_A_Z
R.id.action_song_sort_order_desc -> sortOrder = SortOrder.SongSortOrder.SONG_Z_A
R.id.action_song_sort_order_artist -> sortOrder = SortOrder.SongSortOrder.SONG_ARTIST
R.id.action_song_sort_order_album -> sortOrder = SortOrder.SongSortOrder.SONG_ALBUM
R.id.action_song_sort_order_year -> sortOrder = SortOrder.SongSortOrder.SONG_YEAR
R.id.action_song_sort_order_date -> sortOrder = SortOrder.SongSortOrder.SONG_DATE
}
}
if (sortOrder != null) {
item.isChecked = true
fragment.setAndSaveSortOrder(sortOrder)
return true
}
return false
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
//if (pager == null) return false;
val currentFragment = getCurrentFragment()
if (currentFragment is AbsLibraryPagerRecyclerViewCustomGridSizeFragment<*, *>) {
val fragment = currentFragment as AbsLibraryPagerRecyclerViewCustomGridSizeFragment<*, *>?
if (handleGridSizeMenuItem(fragment!!, item)) {
return true
}
if (handleSortOrderMenuItem(fragment, item)) {
return true
}
}
val id = item.itemId
when (id) {
R.id.action_new_playlist -> {
CreatePlaylistDialog.create().show(childFragmentManager, "CREATE_PLAYLIST")
return true
}
R.id.action_shuffle_all -> {
MusicPlayerRemote.openAndShuffleQueue(SongLoader.getAllSongs(context!!).blockingFirst(), true)
return true
}
R.id.action_equalizer -> {
NavigationUtil.openEqualizer(activity!!)
return true
}
R.id.action_sleep_timer -> {
if (fragmentManager != null) {
SleepTimerDialog().show(fragmentManager!!, TAG)
}
return true
}
R.id.action_settings -> startActivity(Intent(context, SettingsActivity::class.java))
}
return super.onOptionsItemSelected(item)
}
private fun setUpGridSizeMenu(
fragment: AbsLibraryPagerRecyclerViewCustomGridSizeFragment<*, *>,
gridSizeMenu: SubMenu) {
when (fragment.getGridSize()) {
1 -> gridSizeMenu.findItem(R.id.action_grid_size_1).isChecked = true
2 -> gridSizeMenu.findItem(R.id.action_grid_size_2).isChecked = true
3 -> gridSizeMenu.findItem(R.id.action_grid_size_3).isChecked = true
4 -> gridSizeMenu.findItem(R.id.action_grid_size_4).isChecked = true
5 -> gridSizeMenu.findItem(R.id.action_grid_size_5).isChecked = true
6 -> gridSizeMenu.findItem(R.id.action_grid_size_6).isChecked = true
7 -> gridSizeMenu.findItem(R.id.action_grid_size_7).isChecked = true
8 -> gridSizeMenu.findItem(R.id.action_grid_size_8).isChecked = true
}
val maxGridSize = fragment.maxGridSize
if (maxGridSize < 8) {
gridSizeMenu.findItem(R.id.action_grid_size_8).isVisible = false
}
if (maxGridSize < 7) {
gridSizeMenu.findItem(R.id.action_grid_size_7).isVisible = false
}
if (maxGridSize < 6) {
gridSizeMenu.findItem(R.id.action_grid_size_6).isVisible = false
}
if (maxGridSize < 5) {
gridSizeMenu.findItem(R.id.action_grid_size_5).isVisible = false
}
if (maxGridSize < 4) {
gridSizeMenu.findItem(R.id.action_grid_size_4).isVisible = false
}
if (maxGridSize < 3) {
gridSizeMenu.findItem(R.id.action_grid_size_3).isVisible = false
}
}
private fun handleGridSizeMenuItem(
fragment: AbsLibraryPagerRecyclerViewCustomGridSizeFragment<*, *>, item: MenuItem): Boolean {
var gridSize = 0
when (item.itemId) {
R.id.action_grid_size_1 -> gridSize = 1
R.id.action_grid_size_2 -> gridSize = 2
R.id.action_grid_size_3 -> gridSize = 3
R.id.action_grid_size_4 -> gridSize = 4
R.id.action_grid_size_5 -> gridSize = 5
R.id.action_grid_size_6 -> gridSize = 6
R.id.action_grid_size_7 -> gridSize = 7
R.id.action_grid_size_8 -> gridSize = 8
}
if (gridSize > 0) {
item.isChecked = true
fragment.setAndSaveGridSize(gridSize)
return true
}
return false
}
companion object {
const val TAG: String = "LibraryFragment"
private const val CURRENT_TAB_ID = "current_tab_id"
fun newInstance(tab: Int): Fragment {
val args = Bundle()
args.putInt(CURRENT_TAB_ID, tab)
val fragment = LibraryFragment()
fragment.arguments = args
return fragment
}
fun newInstance(): Fragment {
return LibraryFragment()
}
}
}

View file

@ -40,6 +40,7 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.abs_playlists.*
import kotlinx.android.synthetic.main.fragment_banner_home.* import kotlinx.android.synthetic.main.fragment_banner_home.*
import kotlinx.android.synthetic.main.home_section_content.* import kotlinx.android.synthetic.main.home_section_content.*
import java.io.File import java.io.File
@ -181,6 +182,10 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
loadImageFromStorage(userImage) loadImageFromStorage(userImage)
getTimeOfTheDay() getTimeOfTheDay()
searchView.setOnClickListener {
NavigationUtil.goToSearch(activity!!)
}
} }
private fun setupToolbar() { private fun setupToolbar() {
@ -212,7 +217,7 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
} }
override fun showData(homes: ArrayList<Any>) { override fun showData(list: ArrayList<Any>) {
//homeAdapter.swapDataSet(homes); //homeAdapter.swapDataSet(homes);
} }

View file

@ -7,8 +7,10 @@ import android.view.ViewGroup
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.transform.CarousalPagerTransformer
import code.name.monkey.retromusic.transform.ParallaxPagerTransformer import code.name.monkey.retromusic.transform.ParallaxPagerTransformer
import code.name.monkey.retromusic.ui.adapter.album.AlbumCoverPagerAdapter import code.name.monkey.retromusic.ui.adapter.album.AlbumCoverPagerAdapter
import code.name.monkey.retromusic.ui.fragments.NowPlayingScreen
import code.name.monkey.retromusic.ui.fragments.base.AbsMusicServiceFragment import code.name.monkey.retromusic.ui.fragments.base.AbsMusicServiceFragment
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.android.synthetic.main.fragment_player_album_cover.* import kotlinx.android.synthetic.main.fragment_player_album_cover.*
@ -40,7 +42,18 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
viewPager.addOnPageChangeListener(this) viewPager.addOnPageChangeListener(this)
viewPager.setPageTransformer(true, PreferenceUtil.getInstance().getAlbumCoverTransform(context)) //noinspection ConstantConditions
if (PreferenceUtil.getInstance().carouselEffect() &&
!((PreferenceUtil.getInstance().nowPlayingScreen == NowPlayingScreen.FULL)
|| (PreferenceUtil.getInstance().nowPlayingScreen == NowPlayingScreen.FIT))) {
viewPager.clipToPadding = false
viewPager.setPadding(96, 0, 96, 0)
viewPager.pageMargin = 18
viewPager.setPageTransformer(false, CarousalPagerTransformer(context!!))
} else {
viewPager.offscreenPageLimit = 2
viewPager.setPageTransformer(true, PreferenceUtil.getInstance().albumCoverTransform)
}
} }
override fun onDestroyView() { override fun onDestroyView() {
@ -113,6 +126,5 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
companion object { companion object {
val TAG: String = PlayerAlbumCoverFragment::class.java.simpleName val TAG: String = PlayerAlbumCoverFragment::class.java.simpleName
const val VISIBILITY_ANIM_DURATION: Long = 300
} }
} }

View file

@ -34,8 +34,8 @@ class AdaptiveFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks
} }
private fun setUpSubFragments() { private fun setUpSubFragments() {
playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playback_controls_fragment) as AdaptivePlaybackControlsFragment playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as AdaptivePlaybackControlsFragment
val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.player_album_cover_fragment) as PlayerAlbumCoverFragment val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
playerAlbumCoverFragment.apply { playerAlbumCoverFragment.apply {
removeSlideEffect() removeSlideEffect()
}.setCallbacks(this) }.setCallbacks(this)

View file

@ -210,14 +210,14 @@ class ColorFragment : AbsPlayerFragment() {
updateLyricsAsyncTask!!.cancel(false) updateLyricsAsyncTask!!.cancel(false)
} }
val song = MusicPlayerRemote.currentSong val song = MusicPlayerRemote.currentSong
updateLyricsAsyncTask = object : AsyncTask<Void, Void, Lyrics>() { updateLyricsAsyncTask = object : AsyncTask<Void?, Void?, Lyrics?>() {
override fun onPreExecute() { override fun onPreExecute() {
super.onPreExecute() super.onPreExecute()
lyrics = null lyrics = null
playerToolbar.menu.removeItem(R.id.action_show_lyrics) playerToolbar.menu.removeItem(R.id.action_show_lyrics)
} }
override fun doInBackground(vararg params: Void): Lyrics? { override fun doInBackground(vararg params: Void?): Lyrics? {
val data = MusicUtil.getLyrics(song) val data = MusicUtil.getLyrics(song)
return if (TextUtils.isEmpty(data)) { return if (TextUtils.isEmpty(data)) {
null null
@ -233,7 +233,7 @@ class ColorFragment : AbsPlayerFragment() {
} }
} }
override fun onCancelled(s: Lyrics) { override fun onCancelled(s: Lyrics?) {
onPostExecute(null) onPostExecute(null)
} }
}.execute() }.execute()

View file

@ -55,6 +55,9 @@ class FullPlaybackControlsFragment : AbsPlayerControlsFragment() {
val volumeFragment = childFragmentManager.findFragmentById(R.id.volumeFragment) as VolumeFragment? val volumeFragment = childFragmentManager.findFragmentById(R.id.volumeFragment) as VolumeFragment?
volumeFragment!!.tintWhiteColor() volumeFragment!!.tintWhiteColor()
songTotalTime.setTextColor(Color.WHITE)
songCurrentProgress.setTextColor(Color.WHITE)
} }
override fun onResume() { override fun onResume() {

View file

@ -0,0 +1,229 @@
package code.name.monkey.retromusic.ui.fragments.player.lockscreen
import android.animation.ObjectAnimator
import android.graphics.PorterDuff
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.DecelerateInterpolator
import android.view.animation.LinearInterpolator
import android.widget.SeekBar
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.util.MusicUtil
import kotlinx.android.synthetic.main.fragment_lock_screen_playback_controls.*
import kotlinx.android.synthetic.main.media_button.*
import kotlinx.android.synthetic.main.player_time.*
/**
* @author Hemanth S (h4h13).
*/
class LockScreenPlayerControlsFragment : AbsPlayerControlsFragment() {
private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null
private var lastPlaybackControlsColor: Int = 0
private var lastDisabledPlaybackControlsColor: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_lock_screen_playback_controls, container, false)
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setUpMusicControllers()
}
private fun updateSong() {
val song = MusicPlayerRemote.currentSong
title.text = song.title
text.text = String.format("%s - %s", song.artistName, song.albumName)
}
override fun onResume() {
super.onResume()
progressViewUpdateHelper!!.start()
}
override fun onPause() {
super.onPause()
progressViewUpdateHelper!!.stop()
}
override fun onServiceConnected() {
updatePlayPauseDrawableState()
updateRepeatState()
updateShuffleState()
updateSong()
}
override fun onPlayingMetaChanged() {
super.onPlayingMetaChanged()
updateSong()
}
override fun onPlayStateChanged() {
updatePlayPauseDrawableState()
}
override fun onRepeatModeChanged() {
updateRepeatState()
}
override fun onShuffleModeChanged() {
updateShuffleState()
}
override fun setDark(color: Int) {
setProgressBarColor(progressSlider, color)
val colorBg = ATHUtil.resolveColor(activity, android.R.attr.colorBackground)
if (ColorUtil.isColorLight(colorBg)) {
lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(activity, true)
lastDisabledPlaybackControlsColor = MaterialValueHelper.getSecondaryDisabledTextColor(activity, true)
} else {
lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(activity, false)
lastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(activity, false)
}
updatePrevNextColor()
val isDark = ColorUtil.isColorLight(color)
text!!.setTextColor(color)
TintHelper.setTintAuto(playPauseButton, MaterialValueHelper.getPrimaryTextColor(context, isDark), false)
TintHelper.setTintAuto(playPauseButton, color, true)
}
fun setProgressBarColor(progressBar: SeekBar?, newColor: Int) {
TintHelper.setTintAuto(progressBar!!, newColor, false)
//LayerDrawable ld = (LayerDrawable) progressBar.getProgressDrawable();
//ClipDrawable clipDrawable = (ClipDrawable) ld.findDrawableByLayerId(android.R.id.progress);
//clipDrawable.setColorFilter(newColor, PorterDuff.Mode.SRC_IN);
}
private fun setUpPlayPauseFab() {
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
}
private fun updatePlayPauseDrawableState() {
if (MusicPlayerRemote.isPlaying) {
playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp)
} else {
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp)
}
}
private fun setUpMusicControllers() {
setUpPlayPauseFab()
setUpPrevNext()
setUpProgressSlider()
setUpShuffleButton()
setUpRepeatButton()
}
private fun setUpPrevNext() {
updatePrevNextColor()
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
previousButton.setOnClickListener { MusicPlayerRemote.back() }
}
private fun updatePrevNextColor() {
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
private fun setUpShuffleButton() {
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
}
override fun updateShuffleState() {
when (MusicPlayerRemote.shuffleMode) {
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
}
private fun setUpRepeatButton() {
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
}
override fun updateRepeatState() {
when (MusicPlayerRemote.repeatMode) {
MusicService.REPEAT_MODE_NONE -> {
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
MusicService.REPEAT_MODE_ALL -> {
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
MusicService.REPEAT_MODE_THIS -> {
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp)
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
}
}
public override fun show() {
playPauseButton!!.animate()
.scaleX(1f)
.scaleY(1f)
.rotation(360f)
.setInterpolator(DecelerateInterpolator())
.start()
}
public override fun hide() {
if (playPauseButton != null) {
playPauseButton!!.apply {
scaleX = 0f
scaleY = 0f
rotation = 0f
}
}
}
override fun setUpProgressSlider() {
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) {
MusicPlayerRemote.seekTo(progress)
onUpdateProgressViews(MusicPlayerRemote.songProgressMillis,
MusicPlayerRemote.songDurationMillis)
}
}
})
}
override fun onUpdateProgressViews(progress: Int, total: Int) {
progressSlider.max = total
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
animator.duration = 1500
animator.interpolator = LinearInterpolator()
animator.start()
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
}
}

View file

@ -121,9 +121,9 @@ class MaterialControlsFragment : AbsPlayerControlsFragment() {
private fun updatePlayPauseDrawableState() { private fun updatePlayPauseDrawableState() {
if (MusicPlayerRemote.isPlaying) { if (MusicPlayerRemote.isPlaying) {
playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp) playPauseButton.setImageResource(R.drawable.ic_pause_white_big);
} else { } else {
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp) playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_big);
} }
} }

View file

@ -96,6 +96,7 @@ class PlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setUpSubFragments() setUpSubFragments()
setUpPlayerToolbar() setUpPlayerToolbar()
snowfall.visibility= if (PreferenceUtil.getInstance().isSnowFall) View.VISIBLE else View.GONE
} }
private fun setUpSubFragments() { private fun setUpSubFragments() {

View file

@ -1,16 +1,28 @@
package code.name.monkey.retromusic.ui.fragments.settings package code.name.monkey.retromusic.ui.fragments.settings
import android.graphics.Bitmap
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.Constants.USER_PROFILE
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.ui.activities.SettingsActivity import code.name.monkey.retromusic.ui.activities.SettingsActivity
import code.name.monkey.retromusic.util.Compressor
import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.fragment_main_settings.* import kotlinx.android.synthetic.main.fragment_main_settings.*
import java.io.File
import java.util.*
class MainSettingsFragment : Fragment(), View.OnClickListener { class MainSettingsFragment : Fragment(), View.OnClickListener {
override fun onClick(v: View) { override fun onClick(v: View) {
@ -44,6 +56,12 @@ class MainSettingsFragment : Fragment(), View.OnClickListener {
imageSettings.setOnClickListener(this) imageSettings.setOnClickListener(this)
notificationSettings.setOnClickListener(this) notificationSettings.setOnClickListener(this)
otherSettings.setOnClickListener(this) otherSettings.setOnClickListener(this)
text.setTextColor(ThemeStore.textColorSecondary(context!!));
titleWelcome.setTextColor(ThemeStore.textColorPrimary(context!!));
titleWelcome.text = String.format("%s %s!", getTimeOfTheDay(), PreferenceUtil.getInstance().userName);
loadImageFromStorage();
userInfoContainer.setOnClickListener { NavigationUtil.goToUserInfo(activity!!) }
} }
private fun inflateFragment(fragment: Fragment, @StringRes title: Int) { private fun inflateFragment(fragment: Fragment, @StringRes title: Int) {
@ -51,4 +69,42 @@ class MainSettingsFragment : Fragment(), View.OnClickListener {
(activity as SettingsActivity).setupFragment(fragment, title) (activity as SettingsActivity).setupFragment(fragment, title)
} }
} }
private fun getTimeOfTheDay(): String {
var message = getString(R.string.title_good_day)
val c = Calendar.getInstance()
val timeOfDay = c.get(Calendar.HOUR_OF_DAY)
when (timeOfDay) {
in 0..5 -> message = getString(R.string.title_good_night)
in 6..11 -> message = getString(R.string.title_good_morning)
in 12..15 -> message = getString(R.string.title_good_afternoon)
in 16..19 -> message = getString(R.string.title_good_evening)
in 20..23 -> message = getString(R.string.title_good_night)
}
return message
}
override fun onDestroyView() {
super.onDestroyView()
disposable.clear()
}
private val disposable = CompositeDisposable()
private fun loadImageFromStorage() {
disposable.add(Compressor(context!!)
.setMaxHeight(300)
.setMaxWidth(300)
.setQuality(75)
.setCompressFormat(Bitmap.CompressFormat.WEBP)
.compressToBitmapAsFlowable(
File(PreferenceUtil.getInstance().profileImage, USER_PROFILE))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ userImage.setImageBitmap(it) }, {
userImage.setImageDrawable(ContextCompat.getDrawable(context!!, R.drawable.ic_person_flat))
}))
}
} }

View file

@ -1,14 +1,22 @@
package code.name.monkey.retromusic.ui.fragments.settings package code.name.monkey.retromusic.ui.fragments.settings
import android.app.ActivityManager
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.preference.TwoStatePreference import androidx.preference.TwoStatePreference
import code.name.monkey.retromusic.App import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.ui.activities.SettingsActivity.Companion.RESULT_ENABLE
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
class PersonaizeSettingsFragment : AbsSettingsFragment(), SharedPreferences.OnSharedPreferenceChangeListener { class PersonaizeSettingsFragment : AbsSettingsFragment(), SharedPreferences.OnSharedPreferenceChangeListener {
override fun invalidateSettings() { override fun invalidateSettings() {
val cornerWindow = findPreference("corner_window") as TwoStatePreference val cornerWindow = findPreference("corner_window") as TwoStatePreference
cornerWindow.setOnPreferenceChangeListener { _, newValue -> cornerWindow.setOnPreferenceChangeListener { _, newValue ->
@ -17,15 +25,17 @@ class PersonaizeSettingsFragment : AbsSettingsFragment(), SharedPreferences.OnSh
return@setOnPreferenceChangeListener false return@setOnPreferenceChangeListener false
} }
activity!!.recreate() activity!!.recreate()
true return@setOnPreferenceChangeListener true
} }
val toggleFullScreen = findPreference("toggle_full_screen") as TwoStatePreference val toggleFullScreen = findPreference("toggle_full_screen") as TwoStatePreference
toggleFullScreen.setOnPreferenceChangeListener { _, newValue -> toggleFullScreen.setOnPreferenceChangeListener { _, _ ->
activity!!.recreate() activity!!.recreate()
true true
} }
} }
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
@ -36,7 +46,6 @@ class PersonaizeSettingsFragment : AbsSettingsFragment(), SharedPreferences.OnSh
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
PreferenceUtil.getInstance().registerOnSharedPreferenceChangedListener(this) PreferenceUtil.getInstance().registerOnSharedPreferenceChangedListener(this)
} }

View file

@ -11,6 +11,7 @@ import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.VersionUtils import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.App import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.color.ColorChooserDialog import com.afollestad.materialdialogs.color.ColorChooserDialog
@ -64,6 +65,7 @@ class ThemeSettingsFragment : AbsSettingsFragment() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
activity!!.setTheme(PreferenceUtil.getThemeResFromPrefValue(theme)) activity!!.setTheme(PreferenceUtil.getThemeResFromPrefValue(theme))
DynamicShortcutManager(activity!!).updateDynamicShortcuts()
} }
activity!!.recreate() activity!!.recreate()
//invalidateSettings(); //invalidateSettings();
@ -92,6 +94,7 @@ class ThemeSettingsFragment : AbsSettingsFragment() {
colorAppShortcuts.setOnPreferenceChangeListener { _, newValue -> colorAppShortcuts.setOnPreferenceChangeListener { _, newValue ->
// Save preference // Save preference
PreferenceUtil.getInstance().setColoredAppShortcuts(newValue as Boolean) PreferenceUtil.getInstance().setColoredAppShortcuts(newValue as Boolean)
DynamicShortcutManager(activity!!).updateDynamicShortcuts()
true true
} }
} }

View file

@ -26,7 +26,7 @@ import code.name.monkey.retromusic.ui.activities.LicenseActivity;
import code.name.monkey.retromusic.ui.activities.LyricsActivity; import code.name.monkey.retromusic.ui.activities.LyricsActivity;
import code.name.monkey.retromusic.ui.activities.PlayingQueueActivity; import code.name.monkey.retromusic.ui.activities.PlayingQueueActivity;
import code.name.monkey.retromusic.ui.activities.PlaylistDetailActivity; import code.name.monkey.retromusic.ui.activities.PlaylistDetailActivity;
import code.name.monkey.retromusic.ui.activities.ProVersionActivity; import code.name.monkey.retromusic.ui.activities.PurchaseActivity;
import code.name.monkey.retromusic.ui.activities.SearchActivity; import code.name.monkey.retromusic.ui.activities.SearchActivity;
import code.name.monkey.retromusic.ui.activities.SettingsActivity; import code.name.monkey.retromusic.ui.activities.SettingsActivity;
import code.name.monkey.retromusic.ui.activities.SupportDevelopmentActivity; import code.name.monkey.retromusic.ui.activities.SupportDevelopmentActivity;
@ -106,7 +106,7 @@ public class NavigationUtil {
} }
public static void goToProVersion(@NonNull Activity activity) { public static void goToProVersion(@NonNull Activity activity) {
ActivityCompat.startActivity(activity, new Intent(activity, ProVersionActivity.class), null); ActivityCompat.startActivity(activity, new Intent(activity, PurchaseActivity.class), null);
} }
public static void goToSettings(@NonNull Activity activity) { public static void goToSettings(@NonNull Activity activity) {

View file

@ -0,0 +1,13 @@
package code.name.monkey.retromusic.util;
import android.content.Context;
import com.github.javiersantos.piracychecker.utils.LibraryUtilsKt;
public class PiracyCheckerUtils {
public static String getAPKSignature(Context context) {
return LibraryUtilsKt.getCurrentSignature(context);
}
}

View file

@ -30,6 +30,8 @@ import code.name.monkey.retromusic.transform.DepthTransformation;
import code.name.monkey.retromusic.transform.HingeTransformation; import code.name.monkey.retromusic.transform.HingeTransformation;
import code.name.monkey.retromusic.transform.HorizontalFlipTransformation; import code.name.monkey.retromusic.transform.HorizontalFlipTransformation;
import code.name.monkey.retromusic.transform.NormalPageTransformer; 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.transform.VerticalFlipTransformation;
import code.name.monkey.retromusic.ui.activities.MainActivity; import code.name.monkey.retromusic.ui.activities.MainActivity;
import code.name.monkey.retromusic.ui.fragments.AlbumCoverStyle; import code.name.monkey.retromusic.ui.fragments.AlbumCoverStyle;
@ -113,6 +115,7 @@ public final class PreferenceUtil {
private static final String ALBUM_DETAIL_STYLE = "album_detail_style"; private static final String ALBUM_DETAIL_STYLE = "album_detail_style";
private static final String PAUSE_ON_ZERO_VOLUME = "pause_on_zero_volume"; private static final String PAUSE_ON_ZERO_VOLUME = "pause_on_zero_volume";
private static final String NOW_PLAYING_SCREEN = "now_playing_screen"; private static final String NOW_PLAYING_SCREEN = "now_playing_screen";
private static final String SNOW_FALL_EFFECT = "snow_fall_effect";
private static PreferenceUtil sInstance; private static PreferenceUtil sInstance;
private final SharedPreferences mPreferences; private final SharedPreferences mPreferences;
@ -144,8 +147,12 @@ public final class PreferenceUtil {
} }
} }
public boolean isSnowFall() {
return mPreferences.getBoolean(SNOW_FALL_EFFECT, false);
}
public final String getArtistSortOrder() { public final String getArtistSortOrder() {
return mPreferences.getString(ARTIST_SORT_ORDER, SortOrder.ArtistSortOrder.Companion.getARTIST_A_Z()); return mPreferences.getString(ARTIST_SORT_ORDER, SortOrder.ArtistSortOrder.ARTIST_A_Z);
} }
public void setArtistSortOrder(final String sortOrder) { public void setArtistSortOrder(final String sortOrder) {
@ -155,7 +162,7 @@ public final class PreferenceUtil {
} }
public final String getArtistSongSortOrder() { public final String getArtistSongSortOrder() {
return mPreferences.getString(ARTIST_SONG_SORT_ORDER, SortOrder.ArtistSongSortOrder.Companion.getSONG_A_Z()); return mPreferences.getString(ARTIST_SONG_SORT_ORDER, SortOrder.ArtistSongSortOrder.SONG_A_Z);
} }
public final boolean isHomeBanner() { public final boolean isHomeBanner() {
@ -164,11 +171,11 @@ public final class PreferenceUtil {
public final String getArtistAlbumSortOrder() { public final String getArtistAlbumSortOrder() {
return mPreferences return mPreferences
.getString(ARTIST_ALBUM_SORT_ORDER, SortOrder.ArtistAlbumSortOrder.Companion.getALBUM_YEAR()); .getString(ARTIST_ALBUM_SORT_ORDER, SortOrder.ArtistAlbumSortOrder.ALBUM_YEAR);
} }
public final String getAlbumSortOrder() { public final String getAlbumSortOrder() {
return mPreferences.getString(ALBUM_SORT_ORDER, SortOrder.AlbumSortOrder.Companion.getALBUM_A_Z()); return mPreferences.getString(ALBUM_SORT_ORDER, SortOrder.AlbumSortOrder.ALBUM_A_Z);
} }
public void setAlbumSortOrder(final String sortOrder) { public void setAlbumSortOrder(final String sortOrder) {
@ -179,11 +186,11 @@ public final class PreferenceUtil {
public final String getAlbumSongSortOrder() { public final String getAlbumSongSortOrder() {
return mPreferences return mPreferences
.getString(ALBUM_SONG_SORT_ORDER, SortOrder.AlbumSongSortOrder.Companion.getSONG_TRACK_LIST()); .getString(ALBUM_SONG_SORT_ORDER, SortOrder.AlbumSongSortOrder.SONG_TRACK_LIST);
} }
public final String getSongSortOrder() { public final String getSongSortOrder() {
return mPreferences.getString(SONG_SORT_ORDER, SortOrder.SongSortOrder.Companion.getSONG_A_Z()); return mPreferences.getString(SONG_SORT_ORDER, SortOrder.SongSortOrder.SONG_A_Z);
} }
public void setSongSortOrder(final String sortOrder) { public void setSongSortOrder(final String sortOrder) {
@ -193,7 +200,7 @@ public final class PreferenceUtil {
} }
public final String getGenreSortOrder() { public final String getGenreSortOrder() {
return mPreferences.getString(GENRE_SORT_ORDER, SortOrder.GenreSortOrder.Companion.getGENRE_A_Z()); return mPreferences.getString(GENRE_SORT_ORDER, SortOrder.GenreSortOrder.GENRE_A_Z);
} }
public boolean isScreenOnEnabled() { public boolean isScreenOnEnabled() {
@ -288,9 +295,6 @@ public final class PreferenceUtil {
editor.apply(); editor.apply();
} }
public int getLastLyricsType() {
return mPreferences.getInt(LAST_KNOWN_LYRICS_TYPE, R.id.normalLyrics);
}
public void setLastLyricsType(int group) { public void setLastLyricsType(int group) {
final SharedPreferences.Editor editor = mPreferences.edit(); final SharedPreferences.Editor editor = mPreferences.edit();
@ -632,7 +636,7 @@ public final class PreferenceUtil {
public String getAlbumDetailSongSortOrder() { public String getAlbumDetailSongSortOrder() {
return mPreferences return mPreferences
.getString(ALBUM_DETAIL_SONG_SORT_ORDER, SortOrder.AlbumSongSortOrder.Companion.getSONG_TRACK_LIST()); .getString(ALBUM_DETAIL_SONG_SORT_ORDER, SortOrder.AlbumSongSortOrder.SONG_TRACK_LIST);
} }
public void setAlbumDetailSongSortOrder(String sortOrder) { public void setAlbumDetailSongSortOrder(String sortOrder) {
@ -643,7 +647,7 @@ public final class PreferenceUtil {
public String getArtistDetailSongSortOrder() { public String getArtistDetailSongSortOrder() {
return mPreferences return mPreferences
.getString(ARTIST_DETAIL_SONG_SORT_ORDER, SortOrder.ArtistSongSortOrder.Companion.getSONG_A_Z()); .getString(ARTIST_DETAIL_SONG_SORT_ORDER, SortOrder.ArtistSongSortOrder.SONG_A_Z);
} }
public void setArtistDetailSongSortOrder(String sortOrder) { public void setArtistDetailSongSortOrder(String sortOrder) {
@ -737,7 +741,7 @@ public final class PreferenceUtil {
} }
public ViewPager.PageTransformer getAlbumCoverTransform(Context context) { public ViewPager.PageTransformer getAlbumCoverTransform() {
int style = Integer.parseInt(Objects.requireNonNull(mPreferences.getString(ALBUM_COVER_TRANSFORM, "0"))); int style = Integer.parseInt(Objects.requireNonNull(mPreferences.getString(ALBUM_COVER_TRANSFORM, "0")));
switch (style) { switch (style) {
default: default:
@ -753,6 +757,8 @@ public final class PreferenceUtil {
return new VerticalFlipTransformation(); return new VerticalFlipTransformation();
case 5: case 5:
return new HingeTransformation(); return new HingeTransformation();
case 6:
return new StackTransformer();
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners
android:topLeftRadius="8dp"
android:topRightRadius="8dp" />
<solid android:color="@color/md_red_500" />
</shape>

View file

@ -88,7 +88,8 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginStart="64dp" android:layout_marginStart="64dp"
android:layout_marginEnd="64dp" android:layout_marginEnd="64dp"
app:behavior_overlapTop="24dp" android:elevation="@dimen/card_elevation"
app:behavior_overlapTop="72dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView

View file

@ -50,13 +50,12 @@
android:orientation="horizontal"> android:orientation="horizontal">
<code.name.monkey.retromusic.views.HeightFitSquareLayout <code.name.monkey.retromusic.views.HeightFitSquareLayout
android:id="@+id/album_cover_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="center_horizontal"> android:layout_gravity="center_horizontal">
<fragment <fragment
android:id="@+id/player_album_cover_fragment" android:id="@+id/playerAlbumCoverFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -69,14 +68,13 @@
android:orientation="vertical"> android:orientation="vertical">
<fragment <fragment
android:id="@+id/playback_controls_fragment" android:id="@+id/playbackControlsFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.blur.BlurPlaybackControlsFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.blur.BlurPlaybackControlsFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" /> android:layout_weight="1" />
<FrameLayout <FrameLayout
android:id="@+id/toolbar_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"

View file

@ -12,6 +12,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<com.jetradarmobile.snowfall.SnowfallView
android:id="@+id/snowfall"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include layout="@layout/shadow_statusbar_toolbar" /> <include layout="@layout/shadow_statusbar_toolbar" />
<code.name.monkey.retromusic.views.FitSystemWindowsLayout <code.name.monkey.retromusic.views.FitSystemWindowsLayout
@ -37,12 +42,11 @@
android:orientation="horizontal"> android:orientation="horizontal">
<code.name.monkey.retromusic.views.HeightFitSquareLayout <code.name.monkey.retromusic.views.HeightFitSquareLayout
android:id="@+id/album_cover_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<fragment <fragment
android:id="@+id/player_album_cover_fragment" android:id="@+id/playerAlbumCoverFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -68,7 +72,7 @@
</FrameLayout> </FrameLayout>
<fragment <fragment
android:id="@+id/playback_controls_fragment" android:id="@+id/playbackControlsFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.normal.PlayerPlaybackControlsFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.normal.PlayerPlaybackControlsFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View file

@ -8,7 +8,7 @@
android:orientation="vertical"> android:orientation="vertical">
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/image_container" android:id="@+id/imageContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="256dp" android:layout_height="256dp"
app:cardCornerRadius="12dp" app:cardCornerRadius="12dp"
@ -21,7 +21,7 @@
android:scaleType="centerCrop" /> android:scaleType="centerCrop" />
<androidx.appcompat.widget.AppCompatImageButton <androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/play_songs" android:id="@+id/playSongs"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"

View file

@ -56,7 +56,7 @@
android:layout_weight="0"> android:layout_weight="0">
<fragment <fragment
android:id="@+id/player_album_cover_fragment" android:id="@+id/playerAlbumCoverFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
@ -69,7 +69,7 @@
tools:background="@color/md_white_1000"> tools:background="@color/md_white_1000">
<fragment <fragment
android:id="@+id/playback_controls_fragment" android:id="@+id/playbackControlsFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.blur.BlurPlaybackControlsFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.blur.BlurPlaybackControlsFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
@ -80,7 +80,6 @@
<FrameLayout <FrameLayout
android:id="@+id/toolbar_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"

View file

@ -12,6 +12,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<com.jetradarmobile.snowfall.SnowfallView
android:id="@+id/snowfall"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include layout="@layout/shadow_statusbar_toolbar" /> <include layout="@layout/shadow_statusbar_toolbar" />
<code.name.monkey.retromusic.views.FitSystemWindowsLayout <code.name.monkey.retromusic.views.FitSystemWindowsLayout
@ -33,12 +38,11 @@
android:orientation="vertical"> android:orientation="vertical">
<code.name.monkey.retromusic.views.WidthFitSquareLayout <code.name.monkey.retromusic.views.WidthFitSquareLayout
android:id="@+id/album_cover_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<fragment <fragment
android:id="@+id/player_album_cover_fragment" android:id="@+id/playerAlbumCoverFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -46,7 +50,7 @@
</code.name.monkey.retromusic.views.WidthFitSquareLayout> </code.name.monkey.retromusic.views.WidthFitSquareLayout>
<fragment <fragment
android:id="@+id/playback_controls_fragment" android:id="@+id/playbackControlsFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.normal.PlayerPlaybackControlsFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.normal.PlayerPlaybackControlsFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View file

@ -8,7 +8,7 @@
android:orientation="vertical"> android:orientation="vertical">
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/image_container" android:id="@+id/imageContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="256dp" android:layout_height="256dp"
app:cardCornerRadius="12dp" app:cardCornerRadius="12dp"
@ -21,7 +21,7 @@
android:scaleType="centerCrop" /> android:scaleType="centerCrop" />
<androidx.appcompat.widget.AppCompatImageButton <androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/play_songs" android:id="@+id/playSongs"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"

View file

@ -5,6 +5,28 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="12dp"
app:cardUseCompatPadding="true">
<code.name.monkey.retromusic.views.IconImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="14dp"
app:srcCompat="@drawable/ic_search_white_24dp" />
<code.name.monkey.appthemehelper.common.views.ATEPrimaryTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="12dp"
android:text="@string/search_hint" />
</com.google.android.material.card.MaterialCardView>
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
style="@style/SubTitleTextAppearance" style="@style/SubTitleTextAppearance"
android:text="@string/for_you" /> android:text="@string/for_you" />

View file

@ -39,13 +39,12 @@
android:orientation="vertical"> android:orientation="vertical">
<code.name.monkey.retromusic.views.WidthFitSquareLayout <code.name.monkey.retromusic.views.WidthFitSquareLayout
android:id="@+id/album_cover_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"> android:layout_gravity="center_horizontal">
<fragment <fragment
android:id="@+id/player_album_cover_fragment" android:id="@+id/playerAlbumCoverFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
@ -58,7 +57,7 @@
tools:background="@color/md_white_1000"> tools:background="@color/md_white_1000">
<fragment <fragment
android:id="@+id/playback_controls_fragment" android:id="@+id/playbackControlsFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.blur.BlurPlaybackControlsFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.blur.BlurPlaybackControlsFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -66,7 +65,6 @@
</FrameLayout> </FrameLayout>
<FrameLayout <FrameLayout
android:id="@+id/toolbar_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"

View file

@ -11,7 +11,10 @@
android:id="@+id/colorGradientBackground" android:id="@+id/colorGradientBackground"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<com.jetradarmobile.snowfall.SnowfallView
android:id="@+id/snowfall"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include layout="@layout/shadow_statusbar_toolbar" /> <include layout="@layout/shadow_statusbar_toolbar" />
<code.name.monkey.retromusic.views.FitSystemWindowsLayout <code.name.monkey.retromusic.views.FitSystemWindowsLayout
@ -33,7 +36,7 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<fragment <fragment
android:id="@+id/player_album_cover_fragment" android:id="@+id/playerAlbumCoverFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -46,7 +49,7 @@
android:layout_weight="1"> android:layout_weight="1">
<fragment <fragment
android:id="@+id/playback_controls_fragment" android:id="@+id/playbackControlsFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.normal.PlayerPlaybackControlsFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.normal.PlayerPlaybackControlsFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View file

@ -8,7 +8,7 @@
android:orientation="vertical"> android:orientation="vertical">
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/image_container" android:id="@+id/imageContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="196dp" android:layout_height="196dp"
app:cardCornerRadius="12dp" app:cardCornerRadius="12dp"
@ -21,7 +21,7 @@
android:scaleType="centerCrop" /> android:scaleType="centerCrop" />
<androidx.appcompat.widget.AppCompatImageButton <androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/play_songs" android:id="@+id/playSongs"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"

View file

@ -5,6 +5,28 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="12dp"
app:cardUseCompatPadding="true">
<code.name.monkey.retromusic.views.IconImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="14dp"
app:srcCompat="@drawable/ic_search_white_24dp" />
<code.name.monkey.appthemehelper.common.views.ATEPrimaryTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="12dp"
android:text="@string/search_hint" />
</com.google.android.material.card.MaterialCardView>
<code.name.monkey.appthemehelper.common.views.ATEPrimaryTextView <code.name.monkey.appthemehelper.common.views.ATEPrimaryTextView
style="@style/SubTitleTextAppearance" style="@style/SubTitleTextAppearance"
android:text="@string/for_you" /> android:text="@string/for_you" />

View file

@ -1,134 +1,60 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<ImageView <com.google.android.material.appbar.AppBarLayout
android:id="@+id/albumImage" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content">
android:scaleType="centerCrop"
android:tint="#80000000" />
<code.name.monkey.retromusic.views.FitSystemWindowsLayout <androidx.appcompat.widget.Toolbar
android:id="@+id/container" android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottomAppBar"
style="@style/Widget.MaterialComponents.BottomAppBar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp"
android:elevation="8dp"
app:backgroundTint="@color/md_red_500"
app:contentInsetLeft="0dp" app:contentInsetLeft="0dp"
app:fabAlignmentMode="end" app:contentInsetStart="0dp"
app:fabCradleRoundedCornerRadius="8dp" app:contentInsetStartWithNavigation="0dp"
app:navigationIcon="@drawable/ic_keyboard_backspace_black_24dp" app:layout_scrollFlags="scroll|enterAlways"
app:title="@string/lyrics" app:subtitleTextAppearance="@style/TextAppearance.AppCompat.Caption"
app:titleMargin="0dp" app:titleMargin="0dp"
app:titleMarginStart="0dp" /> app:titleMarginStart="0dp"
app:titleTextAppearance="@style/TextAppearance.AppCompat.Subhead" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
style="@style/TabLayoutStyle"
android:background="@android:color/transparent"
app:tabTextAppearance="@style/TabTextAppearance">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/synced_lyrics" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/normal_lyrics" />
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab" android:id="@+id/fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="14dp"
android:src="@drawable/ic_edit_white_24dp" android:src="@drawable/ic_edit_white_24dp"
app:layout_anchor="@id/bottomAppBar" /> app:useCompatPadding="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="52dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<RadioGroup
android:id="@+id/actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingEnd="12dp">
<RadioButton
android:id="@+id/syncedLyrics"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_weight="1"
android:background="@drawable/toggle_outline_buttons"
android:button="@null"
android:gravity="center"
android:padding="12dp"
android:text="@string/synced_lyrics"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption"
android:textColor="@color/md_white_1000" />
<RadioButton
android:id="@+id/normalLyrics"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_weight="1"
android:background="@drawable/toggle_outline_buttons"
android:button="@null"
android:gravity="center"
android:padding="12dp"
android:text="@string/normal_lyrics"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption"
android:textColor="@color/md_white_1000" />
</RadioGroup>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadingEdge="vertical">
<TextView
android:id="@+id/offlineLyrics"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:lineSpacingExtra="3dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingBottom="16dp"
android:text="@string/no_lyrics_found"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="@color/md_white_1000"
android:visibility="gone" />
</ScrollView>
<code.name.monkey.retromusic.views.LyricView
android:id="@+id/lyricsView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:fadeInFadeOut="true"
app:highlightColor="@color/md_white_1000"
app:hint="No Lyrics"
app:hintColor="@color/md_grey_400"
app:lineSpace="15dp"
app:textAlign="left"
app:textSize="18sp" />
</FrameLayout>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
</code.name.monkey.retromusic.views.FitSystemWindowsLayout>
</FrameLayout>

View file

@ -18,6 +18,7 @@
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
android:paddingStart="0dp" android:paddingStart="0dp"
android:paddingEnd="8dp" android:paddingEnd="8dp"
app:headerLayout="@layout/navigation_drawer_header"
app:itemBackground="@drawable/navigation_item" app:itemBackground="@drawable/navigation_item"
app:itemTextAppearance="@style/NavigationViewTitleTextAppearance" app:itemTextAppearance="@style/NavigationViewTitleTextAppearance"
app:menu="@menu/menu_drawer" /> app:menu="@menu/menu_drawer" />

View file

@ -21,7 +21,7 @@
app:title=""> app:title="">
<TextView <TextView
android:id="@+id/whatNewtitle" android:id="@+id/bannerTitle"
style="@style/BigTitleTextAppearance" style="@style/BigTitleTextAppearance"
android:text="@string/whats_new" /> android:text="@string/whats_new" />

View file

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:background="@color/md_red_500">
<LinearLayout
android:id="@+id/media_titles"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="fill"
android:focusable="true"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:text="@string/normal_lyrics"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
android:textColor="@color/md_white_1000" />
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:text="@string/normal_lyrics"
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
android:textColor="@color/md_white_1000" />
</LinearLayout>
<LinearLayout
android:id="@+id/media_actions"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:focusable="true"
android:gravity="center"
android:layoutDirection="ltr"
android:orientation="horizontal">
<ImageButton
android:id="@+id/button_prev"
android:layout_width="0dp"
android:layout_height="@dimen/app_widget_small_button_height"
android:layout_weight="1"
android:background="@drawable/widget_selector"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_skip_previous_white_24dp"
tools:tint="@color/ate_secondary_text_dark" />
<ImageButton
android:id="@+id/button_toggle_play_pause"
android:layout_width="0dp"
android:layout_height="@dimen/app_widget_small_button_height"
android:layout_weight="1"
android:background="@drawable/widget_selector"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_play_arrow_white_24dp"
tools:tint="@color/ate_secondary_text_dark" />
<ImageButton
android:id="@+id/button_next"
android:layout_width="0dp"
android:layout_height="@dimen/app_widget_small_button_height"
android:layout_weight="1"
android:background="@drawable/widget_selector"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_skip_next_white_24dp"
tools:tint="@color/ate_secondary_text_dark" />
</LinearLayout>
</LinearLayout>

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -10,15 +9,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:src="@drawable/diwali" /> android:src="@drawable/img_offer" />
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:cardCornerRadius="8dp"
app:cardBackgroundColor="@color/md_red_500"
app:cardUseCompatPadding="true">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -31,50 +22,50 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center"> android:layout_gravity="center">
<code.name.monkey.appthemehelper.common.views.ATEPrimaryTextView xmlns:tools="http://schemas.android.com/tools" <TextView
android:id="@+id/title" android:id="@+id/title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:text="70" android:text="70"
android:textColor="@android:color/white" android:textAppearance="@style/TextAppearance.MaterialComponents.Headline1"
android:textSize="108sp" android:textColor="@android:color/black"
tools:ignore="MissingPrefix" /> tools:ignore="MissingPrefix" />
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:paddingTop="32dp" android:paddingTop="32dp"
android:paddingBottom="32dp"> android:paddingBottom="32dp">
<code.name.monkey.appthemehelper.common.views.ATESecondaryTextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:text="%" android:text="%"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Title" android:textColor="@android:color/black" />
android:textColor="@android:color/white" />
<code.name.monkey.appthemehelper.common.views.ATESecondaryTextView <TextView
android:id="@+id/off" android:id="@+id/off"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:text="Off" android:text="Off"
android:textColor="@android:color/white" android:textColor="@android:color/black"
android:textStyle="italic" /> android:textStyle="italic" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<code.name.monkey.appthemehelper.common.views.ATESecondaryTextView
</LinearLayout>
<TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center_horizontal|bottom"
android:gravity="center" android:gravity="center"
android:text="Diwali offer" android:text="Christmas offer"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Title" android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5"
android:textColor="@android:color/white" /> android:textColor="@android:color/black" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</FrameLayout> </FrameLayout>

View file

@ -3,27 +3,27 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content">
<com.google.android.material.card.MaterialCardView
android:id="@+id/player_album_art_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="8dp"
app:cardElevation="8dp"
app:cardUseCompatPadding="true">
<code.name.monkey.retromusic.views.WidthFitSquareLayout <code.name.monkey.retromusic.views.WidthFitSquareLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<com.google.android.material.card.MaterialCardView
android:id="@+id/player_album_art_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardCornerRadius="8dp"
app:cardElevation="8dp"
app:cardUseCompatPadding="true">
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/player_image" android:id="@+id/player_image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleType="centerCrop" android:scaleType="centerCrop"
tools:ignore="ContentDescription,UnusedAttribute" /> tools:ignore="ContentDescription,UnusedAttribute" />
</code.name.monkey.retromusic.views.WidthFitSquareLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
</code.name.monkey.retromusic.views.WidthFitSquareLayout>
</FrameLayout> </FrameLayout>

View file

@ -23,7 +23,7 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:elevation="0dp" android:elevation="0dp"
@ -42,7 +42,7 @@
tools:ignore="UnusedAttribute"> tools:ignore="UnusedAttribute">
<TextView <TextView
android:id="@+id/title" android:id="@+id/bannerTitle"
style="@style/BigTitleTextAppearanceToolbar" style="@style/BigTitleTextAppearanceToolbar"
android:text="@string/app_name" android:text="@string/app_name"
tools:ignore="MissingPrefix" /> tools:ignore="MissingPrefix" />
@ -57,7 +57,7 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<FrameLayout <FrameLayout
android:id="@+id/fragment_container" android:id="@+id/fragmentContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/playback_controls" android:id="@+id/playback_controls"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -10,53 +9,21 @@
tools:ignore="MissingPrefix"> tools:ignore="MissingPrefix">
<SeekBar <SeekBar
android:id="@+id/player_progress_slider" android:id="@+id/progressSlider"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxHeight="3dp" android:maxHeight="3dp"
android:paddingEnd="24dp"
android:paddingStart="24dp" android:paddingStart="24dp"
android:paddingEnd="24dp"
android:progressDrawable="@drawable/color_progress_seek" android:progressDrawable="@drawable/color_progress_seek"
tools:progress="20" /> tools:progress="20" />
<include layout="@layout/player_time" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingEnd="16dp"
android:paddingStart="16dp">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/player_song_current_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:alpha="0.75"
android:paddingEnd="8dp"
android:paddingStart="8dp"
android:textSize="12sp"
android:textStyle="bold"
tools:text="22.00" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/player_song_total_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:alpha="0.75"
android:paddingEnd="8dp"
android:paddingStart="8dp"
android:textSize="12sp"
android:textStyle="bold"
tools:text="22.00" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center" android:gravity="center"
android:orientation="vertical"> android:orientation="vertical">
@ -66,8 +33,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end" android:ellipsize="end"
android:gravity="center" android:gravity="center"
android:paddingEnd="16dp" android:padding="16dp"
android:paddingStart="16dp"
android:singleLine="true" android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
tools:text="Title" /> tools:text="Title" />
@ -77,83 +43,20 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginTop="8dp"
android:ellipsize="marquee" android:ellipsize="marquee"
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true" android:focusableInTouchMode="true"
android:gravity="center" android:gravity="center"
android:marqueeRepeatLimit="marquee_forever" android:marqueeRepeatLimit="marquee_forever"
android:paddingEnd="16dp"
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingEnd="16dp"
android:scrollHorizontally="true" android:scrollHorizontally="true"
android:singleLine="true" android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textAppearance="@style/TextAppearance.AppCompat.Body1"
tools:text="Title" /> tools:text="Title" />
</LinearLayout> </LinearLayout>
<RelativeLayout <include layout="@layout/media_button" />
android:id="@+id/player_media_controller_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:minHeight="72dp"
tools:ignore="ContentDescription,UnusedAttribute">
<androidx.appcompat.widget.AppCompatImageButton <include layout="@layout/volume_controls" />
android:id="@+id/player_prev_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_toStartOf="@+id/player_play_pause_button"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_skip_previous_white_24dp"
app:tint="@color/md_white_1000"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/player_next_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="24dp"
android:layout_toEndOf="@+id/player_play_pause_button"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_skip_next_white_24dp"
app:tint="@color/md_white_1000"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/player_play_pause_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/title_container"
android:layout_centerInParent="true"
android:background="@drawable/color_circle_gradient"
android:elevation="4dp"
android:padding="12dp"
app:srcCompat="@drawable/ic_play_arrow_white_24dp" />
</RelativeLayout>
<FrameLayout
android:id="@+id/volume_fragment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0">
<fragment
android:id="@+id/volume_fragment"
android:name="code.name.monkey.retromusic.ui.fragments.VolumeFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout="@layout/fragment_volume" />
</FrameLayout>
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fadingEdge="vertical">
<TextView
android:id="@+id/offlineLyrics"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:lineSpacingExtra="3dp"
android:padding="16dp"
android:text="@string/no_lyrics_found"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6" />
</ScrollView>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container" android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="match_parent">
<com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView <com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
android:id="@+id/recyclerView" android:id="@+id/recyclerView"
@ -23,5 +23,4 @@
android:textColor="?android:textColorSecondary" android:textColor="?android:textColorSecondary"
android:visibility="gone" /> android:visibility="gone" />
</FrameLayout> </FrameLayout>

View file

@ -12,6 +12,55 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout
android:id="@+id/userInfoContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingTop="12dp"
android:paddingEnd="8dp"
android:paddingBottom="12dp">
<code.name.monkey.retromusic.views.CircularImageView
android:id="@+id/userImage"
android:layout_width="38dp"
android:layout_height="38dp"
android:layout_weight="0"
app:civ_border="false" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:paddingStart="18dp"
android:paddingEnd="12dp"
android:paddingBottom="8dp">
<code.name.monkey.appthemehelper.common.views.ATEPrimaryTextView
android:id="@+id/titleWelcome"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:singleLine="true"
android:text="@string/general_settings_title"
android:textSize="@dimen/ate_default_textsize_subheading" />
<code.name.monkey.appthemehelper.common.views.ATESecondaryTextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:maxLines="4"
android:text="@string/lets_play_something"
android:textSize="@dimen/ate_default_textsize_body"
tools:text="Summary" />
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/generalSettings" android:id="@+id/generalSettings"
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -12,6 +12,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<com.jetradarmobile.snowfall.SnowfallView
android:id="@+id/snowfall"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include layout="@layout/shadow_statusbar_toolbar" /> <include layout="@layout/shadow_statusbar_toolbar" />
<code.name.monkey.retromusic.views.FitSystemWindowsLayout <code.name.monkey.retromusic.views.FitSystemWindowsLayout

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<code.name.monkey.retromusic.views.LyricView
android:id="@+id/lyricsView"
app:fadeInFadeOut="true"
app:highlightColor="@color/md_white_1000"
app:hint="No Lyrics"
app:hintColor="@color/md_grey_400"
app:lineSpace="15dp"
app:textAlign="left"
app:textSize="18sp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View file

@ -150,4 +150,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:nestedScrollingEnabled="false" /> android:nestedScrollingEnabled="false" />
</LinearLayout> </LinearLayout>
<Space
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginBottom="16dp" />
</LinearLayout> </LinearLayout>

View file

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout> <include layout="@layout/status_bar" />
</FrameLayout>

View file

@ -8,7 +8,7 @@
android:orientation="vertical"> android:orientation="vertical">
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/image_container" android:id="@+id/imageContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="172dp" android:layout_height="172dp"
app:cardCornerRadius="12dp" app:cardCornerRadius="12dp"
@ -21,7 +21,7 @@
android:scaleType="centerCrop" /> android:scaleType="centerCrop" />
<androidx.appcompat.widget.AppCompatImageButton <androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/play_songs" android:id="@+id/playSongs"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
@ -48,7 +48,6 @@
<code.name.monkey.appthemehelper.common.views.ATEPrimaryTextView <code.name.monkey.appthemehelper.common.views.ATEPrimaryTextView
android:id="@+id/title" android:id="@+id/title"
android:textStyle="bold"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:ellipsize="end" android:ellipsize="end"
@ -56,6 +55,7 @@
android:paddingStart="8dp" android:paddingStart="8dp"
android:paddingEnd="8dp" android:paddingEnd="8dp"
android:textSize="14sp" android:textSize="14sp"
android:textStyle="bold"
tools:ignore="MissingPrefix" tools:ignore="MissingPrefix"
tools:text="My top tracks" /> tools:text="My top tracks" />

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