change application id for release
This commit is contained in:
parent
0cd75de1ee
commit
9d08253655
159 changed files with 801 additions and 801 deletions
125
app/src/main/java/com/dkanada/gramophone/util/CalendarUtil.java
Normal file
125
app/src/main/java/com/dkanada/gramophone/util/CalendarUtil.java
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
package com.dkanada.gramophone.util;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
public class CalendarUtil {
|
||||
private static final long MS_PER_MINUTE = 60 * 1000;
|
||||
private static final long MS_PER_DAY = 24 * 60 * MS_PER_MINUTE;
|
||||
|
||||
private Calendar calendar;
|
||||
|
||||
public CalendarUtil() {
|
||||
this.calendar = Calendar.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time elapsed so far today in milliseconds.
|
||||
*
|
||||
* @return Time elapsed today in milliseconds.
|
||||
*/
|
||||
public long getElapsedToday() {
|
||||
// Time elapsed so far today
|
||||
return (calendar.get(Calendar.HOUR_OF_DAY) * 60
|
||||
+ calendar.get(Calendar.MINUTE)) * MS_PER_MINUTE
|
||||
+ calendar.get(Calendar.SECOND) * 1000
|
||||
+ calendar.get(Calendar.MILLISECOND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time elapsed so far last N days in milliseconds.
|
||||
*
|
||||
* @return Time elapsed since N days in milliseconds.
|
||||
*/
|
||||
public long getElapsedDays(int numDays) {
|
||||
long elapsed = getElapsedToday();
|
||||
elapsed += numDays * MS_PER_DAY;
|
||||
|
||||
return elapsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time elapsed so far this week in milliseconds.
|
||||
*
|
||||
* @return Time elapsed this week in milliseconds.
|
||||
*/
|
||||
public long getElapsedWeek() {
|
||||
// Today + days passed this week
|
||||
long elapsed = getElapsedToday();
|
||||
|
||||
final int passedWeekdays = calendar.get(Calendar.DAY_OF_WEEK) - 1 - calendar.getFirstDayOfWeek();
|
||||
if (passedWeekdays > 0) {
|
||||
elapsed += passedWeekdays * MS_PER_DAY;
|
||||
}
|
||||
|
||||
return elapsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time elapsed so far this month in milliseconds.
|
||||
*
|
||||
* @return Time elapsed this month in milliseconds.
|
||||
*/
|
||||
public long getElapsedMonth() {
|
||||
// Today and the rest of this month
|
||||
return getElapsedToday() + ((calendar.get(Calendar.DAY_OF_MONTH) - 1) * MS_PER_DAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time elapsed so far this month and the last numMonths months in milliseconds.
|
||||
*
|
||||
* @param numMonths Additional number of months prior to the current month to calculate.
|
||||
* @return Time elapsed this month and the last numMonths months in milliseconds.
|
||||
*/
|
||||
public long getElapsedMonths(int numMonths) {
|
||||
// Today and the rest of this month
|
||||
long elapsed = getElapsedMonth();
|
||||
|
||||
// Previous numMonths months
|
||||
int month = calendar.get(Calendar.MONTH);
|
||||
int year = calendar.get(Calendar.YEAR);
|
||||
for (int i = 0; i < numMonths; i++) {
|
||||
month--;
|
||||
|
||||
if (month < Calendar.JANUARY) {
|
||||
month = Calendar.DECEMBER;
|
||||
year--;
|
||||
}
|
||||
|
||||
elapsed += getDaysInMonth(year, month) * MS_PER_DAY;
|
||||
}
|
||||
|
||||
return elapsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time elapsed so far this year in milliseconds.
|
||||
*
|
||||
* @return Time elapsed this year in milliseconds.
|
||||
*/
|
||||
public long getElapsedYear() {
|
||||
// Today + rest of this month + previous months until January
|
||||
long elapsed = getElapsedMonth();
|
||||
|
||||
int month = calendar.get(Calendar.MONTH) - 1;
|
||||
int year = calendar.get(Calendar.YEAR);
|
||||
while (month > Calendar.JANUARY) {
|
||||
elapsed += getDaysInMonth(year, month) * MS_PER_DAY;
|
||||
month--;
|
||||
}
|
||||
|
||||
return elapsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of days for the given month in the given year.
|
||||
*
|
||||
* @param year The year.
|
||||
* @param month The month (1 - 12).
|
||||
* @return The days in that month/year.
|
||||
*/
|
||||
private int getDaysInMonth(int year, int month) {
|
||||
final Calendar monthCal = new GregorianCalendar(calendar.get(Calendar.YEAR), month, 1);
|
||||
return monthCal.getActualMaximum(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
}
|
||||
120
app/src/main/java/com/dkanada/gramophone/util/ImageUtil.java
Normal file
120
app/src/main/java/com/dkanada/gramophone/util/ImageUtil.java
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
package com.dkanada.gramophone.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import androidx.annotation.AttrRes;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.kabouzeid.appthemehelper.util.TintHelper;
|
||||
|
||||
public class ImageUtil {
|
||||
|
||||
public static int calculateInSampleSize(int width, int height, int reqWidth) {
|
||||
// setting reqWidth matching to desired 1:1 ratio and screen-size
|
||||
if (width < height) {
|
||||
reqWidth = (height / width) * reqWidth;
|
||||
} else {
|
||||
reqWidth = (width / height) * reqWidth;
|
||||
}
|
||||
|
||||
int inSampleSize = 1;
|
||||
|
||||
if (height > reqWidth || width > reqWidth) {
|
||||
final int halfHeight = height / 2;
|
||||
final int halfWidth = width / 2;
|
||||
|
||||
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
|
||||
// height and width larger than the requested height and width.
|
||||
while ((halfHeight / inSampleSize) > reqWidth
|
||||
&& (halfWidth / inSampleSize) > reqWidth) {
|
||||
inSampleSize *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
return inSampleSize;
|
||||
}
|
||||
|
||||
public static Bitmap resizeBitmap(@NonNull Bitmap src, int maxForSmallerSize) {
|
||||
int width = src.getWidth();
|
||||
int height = src.getHeight();
|
||||
|
||||
final int dstWidth;
|
||||
final int dstHeight;
|
||||
|
||||
if (width < height) {
|
||||
if (maxForSmallerSize >= width) {
|
||||
return src;
|
||||
}
|
||||
|
||||
float ratio = (float) height / width;
|
||||
dstWidth = maxForSmallerSize;
|
||||
dstHeight = Math.round(maxForSmallerSize * ratio);
|
||||
} else {
|
||||
if (maxForSmallerSize >= height) {
|
||||
return src;
|
||||
}
|
||||
|
||||
float ratio = (float) width / height;
|
||||
dstWidth = Math.round(maxForSmallerSize * ratio);
|
||||
dstHeight = maxForSmallerSize;
|
||||
}
|
||||
|
||||
return Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false);
|
||||
}
|
||||
|
||||
public static Bitmap createBitmap(Drawable drawable) {
|
||||
return createBitmap(drawable, 1f);
|
||||
}
|
||||
|
||||
public static Bitmap createBitmap(Drawable drawable, float sizeMultiplier) {
|
||||
Bitmap bitmap = Bitmap.createBitmap((int) (drawable.getIntrinsicWidth() * sizeMultiplier), (int) (drawable.getIntrinsicHeight() * sizeMultiplier), Bitmap.Config.ARGB_8888);
|
||||
Canvas c = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, c.getWidth(), c.getHeight());
|
||||
drawable.draw(c);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public static Drawable getVectorDrawable(@NonNull Resources res, @DrawableRes int resId, @Nullable Resources.Theme theme) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
return res.getDrawable(resId, theme);
|
||||
}
|
||||
|
||||
return VectorDrawableCompat.create(res, resId, theme);
|
||||
}
|
||||
|
||||
public static Drawable getTintedVectorDrawable(@NonNull Resources res, @DrawableRes int resId, @Nullable Resources.Theme theme, @ColorInt int color) {
|
||||
return TintHelper.createTintedDrawable(getVectorDrawable(res, resId, theme), color);
|
||||
}
|
||||
|
||||
public static Drawable getTintedVectorDrawable(@NonNull Context context, @DrawableRes int id, @ColorInt int color) {
|
||||
return TintHelper.createTintedDrawable(getVectorDrawable(context.getResources(), id, context.getTheme()), color);
|
||||
}
|
||||
|
||||
public static Drawable getVectorDrawable(@NonNull Context context, @DrawableRes int id) {
|
||||
return getVectorDrawable(context.getResources(), id, context.getTheme());
|
||||
}
|
||||
|
||||
public static Drawable resolveDrawable(@NonNull Context context, @AttrRes int drawableAttr) {
|
||||
TypedArray a = context.obtainStyledAttributes(new int[]{drawableAttr});
|
||||
Drawable drawable = a.getDrawable(0);
|
||||
a.recycle();
|
||||
return drawable;
|
||||
}
|
||||
|
||||
public static Bitmap resize(InputStream stream, int scaledWidth, int scaledHeight) {
|
||||
final Bitmap bitmap = BitmapFactory.decodeStream(stream);
|
||||
return Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true);
|
||||
}
|
||||
}
|
||||
162
app/src/main/java/com/dkanada/gramophone/util/MusicUtil.java
Normal file
162
app/src/main/java/com/dkanada/gramophone/util/MusicUtil.java
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
package com.dkanada.gramophone.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.dkanada.gramophone.App;
|
||||
import com.dkanada.gramophone.R;
|
||||
import com.dkanada.gramophone.model.Album;
|
||||
import com.dkanada.gramophone.model.Artist;
|
||||
import com.dkanada.gramophone.model.Genre;
|
||||
import com.dkanada.gramophone.model.Playlist;
|
||||
import com.dkanada.gramophone.model.Song;
|
||||
|
||||
import org.jellyfin.apiclient.interaction.Response;
|
||||
import org.jellyfin.apiclient.model.dto.UserItemDataDto;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class MusicUtil {
|
||||
public static Uri getSongFileUri(Song song) {
|
||||
return Uri.parse(App.getApiClient().getApiUrl() + "/Audio/" + song.id + "/stream?static=true");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Intent createShareSongFileIntent(@NonNull final Song song, Context context) {
|
||||
try {
|
||||
return new Intent();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(context, R.string.error_share_file, Toast.LENGTH_SHORT).show();
|
||||
return new Intent();
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getArtistInfoString(@NonNull final Context context, @NonNull final Artist artist) {
|
||||
return artist.genres.size() != 0 ? artist.genres.get(0).name : artist.id;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getAlbumInfoString(@NonNull final Context context, @NonNull final Album album) {
|
||||
return album.artistName;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getSongInfoString(@NonNull final Song song) {
|
||||
return song.albumName;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getGenreInfoString(@NonNull final Context context, @NonNull final Genre genre) {
|
||||
int songCount = genre.songCount;
|
||||
return MusicUtil.getSongCountString(context, songCount);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getPlaylistInfoString(@NonNull final Context context, @NonNull List<Song> songs) {
|
||||
final long duration = getTotalDuration(context, songs);
|
||||
|
||||
return MusicUtil.buildInfoString(
|
||||
MusicUtil.getSongCountString(context, songs.size()),
|
||||
MusicUtil.getReadableDurationString(duration)
|
||||
);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getSongCountString(@NonNull final Context context, int songCount) {
|
||||
final String songString = songCount == 1 ? context.getResources().getString(R.string.song) : context.getResources().getString(R.string.songs);
|
||||
return songCount + " " + songString;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getAlbumCountString(@NonNull final Context context, int albumCount) {
|
||||
final String albumString = albumCount == 1 ? context.getResources().getString(R.string.album) : context.getResources().getString(R.string.albums);
|
||||
return albumCount + " " + albumString;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getYearString(int year) {
|
||||
return year > 0 ? String.valueOf(year) : "-";
|
||||
}
|
||||
|
||||
public static long getTotalDuration(@NonNull final Context context, @NonNull List<Song> songs) {
|
||||
long duration = 0;
|
||||
for (int i = 0; i < songs.size(); i++) {
|
||||
duration += songs.get(i).duration;
|
||||
}
|
||||
|
||||
return duration;
|
||||
}
|
||||
|
||||
public static String getReadableDurationString(long songDurationMillis) {
|
||||
long minutes = (songDurationMillis / 1000) / 60;
|
||||
long seconds = (songDurationMillis / 1000) % 60;
|
||||
if (minutes < 60) {
|
||||
return String.format(Locale.getDefault(), "%01d:%02d", minutes, seconds);
|
||||
} else {
|
||||
long hours = minutes / 60;
|
||||
minutes = minutes % 60;
|
||||
return String.format(Locale.getDefault(), "%d:%02d:%02d", hours, minutes, seconds);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String buildInfoString(@Nullable final String one, @Nullable final String two) {
|
||||
// skip empty strings
|
||||
if (TextUtils.isEmpty(one)) {
|
||||
return TextUtils.isEmpty(two) ? "" : two;
|
||||
}
|
||||
if (TextUtils.isEmpty(two)) {
|
||||
return TextUtils.isEmpty(one) ? "" : one;
|
||||
}
|
||||
|
||||
return one + " • " + two;
|
||||
}
|
||||
|
||||
// iTunes uses for example 1002 for track 2 CD1 or 3011 for track 11 CD3.
|
||||
// this method converts those values to normal track numbers
|
||||
public static int getFixedTrackNumber(int trackNumberToFix) {
|
||||
return trackNumberToFix % 1000;
|
||||
}
|
||||
|
||||
public static void toggleFavorite(@NonNull final Context context, @NonNull final Song song) {
|
||||
song.favorite = !song.favorite;
|
||||
|
||||
String user = App.getApiClient().getCurrentUserId();
|
||||
App.getApiClient().UpdateFavoriteStatusAsync(song.id, user, song.favorite, new Response<UserItemDataDto>() {
|
||||
@Override
|
||||
public void onResponse(UserItemDataDto data) {
|
||||
song.favorite = data.getIsFavorite();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getSectionName(@Nullable String musicMediaTitle) {
|
||||
if (TextUtils.isEmpty(musicMediaTitle)) return "";
|
||||
|
||||
musicMediaTitle = musicMediaTitle.trim().toLowerCase();
|
||||
if (musicMediaTitle.startsWith("the ")) {
|
||||
musicMediaTitle = musicMediaTitle.substring(4);
|
||||
} else if (musicMediaTitle.startsWith("a ")) {
|
||||
musicMediaTitle = musicMediaTitle.substring(2);
|
||||
}
|
||||
|
||||
if (musicMediaTitle.isEmpty()) return "";
|
||||
return String.valueOf(musicMediaTitle.charAt(0)).toUpperCase();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package com.dkanada.gramophone.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityOptionsCompat;
|
||||
import androidx.core.util.Pair;
|
||||
|
||||
import com.dkanada.gramophone.model.Album;
|
||||
import com.dkanada.gramophone.model.Artist;
|
||||
import com.dkanada.gramophone.model.Genre;
|
||||
import com.dkanada.gramophone.model.Playlist;
|
||||
import com.dkanada.gramophone.model.Song;
|
||||
import com.dkanada.gramophone.ui.activities.AlbumDetailActivity;
|
||||
import com.dkanada.gramophone.ui.activities.ArtistDetailActivity;
|
||||
import com.dkanada.gramophone.ui.activities.GenreDetailActivity;
|
||||
import com.dkanada.gramophone.ui.activities.PlaylistDetailActivity;
|
||||
|
||||
public class NavigationUtil {
|
||||
|
||||
public static void goToArtist(@NonNull final Activity activity, final Artist artist, @Nullable Pair... sharedElements) {
|
||||
final Intent intent = new Intent(activity, ArtistDetailActivity.class);
|
||||
intent.putExtra(ArtistDetailActivity.EXTRA_ARTIST, artist);
|
||||
|
||||
startActivitySharedElements(activity, intent, sharedElements);
|
||||
}
|
||||
|
||||
public static void goToAlbum(@NonNull final Activity activity, final Album album, @Nullable Pair... sharedElements) {
|
||||
final Intent intent = new Intent(activity, AlbumDetailActivity.class);
|
||||
intent.putExtra(AlbumDetailActivity.EXTRA_ALBUM, album);
|
||||
|
||||
startActivitySharedElements(activity, intent, sharedElements);
|
||||
}
|
||||
|
||||
public static void goToGenre(@NonNull final Activity activity, final Genre genre, @Nullable Pair... sharedElements) {
|
||||
final Intent intent = new Intent(activity, GenreDetailActivity.class);
|
||||
intent.putExtra(GenreDetailActivity.EXTRA_GENRE, genre);
|
||||
|
||||
startActivitySharedElements(activity, intent, sharedElements);
|
||||
}
|
||||
|
||||
public static void goToPlaylist(@NonNull final Activity activity, final Playlist playlist, @Nullable Pair... sharedElements) {
|
||||
final Intent intent = new Intent(activity, PlaylistDetailActivity.class);
|
||||
intent.putExtra(PlaylistDetailActivity.EXTRA_PLAYLIST, playlist);
|
||||
|
||||
startActivitySharedElements(activity, intent, sharedElements);
|
||||
}
|
||||
|
||||
public static void startActivitySharedElements(@NonNull final Activity activity, Intent intent, @Nullable Pair... sharedElements) {
|
||||
if (sharedElements != null && sharedElements.length > 0) {
|
||||
// noinspection unchecked
|
||||
activity.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, sharedElements).toBundle());
|
||||
} else {
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
103
app/src/main/java/com/dkanada/gramophone/util/PlaylistUtil.java
Normal file
103
app/src/main/java/com/dkanada/gramophone/util/PlaylistUtil.java
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
package com.dkanada.gramophone.util;
|
||||
|
||||
import com.dkanada.gramophone.App;
|
||||
import com.dkanada.gramophone.interfaces.MediaCallback;
|
||||
import com.dkanada.gramophone.model.Playlist;
|
||||
import com.dkanada.gramophone.model.PlaylistSong;
|
||||
import com.dkanada.gramophone.model.Song;
|
||||
|
||||
import org.jellyfin.apiclient.interaction.EmptyResponse;
|
||||
import org.jellyfin.apiclient.interaction.Response;
|
||||
import org.jellyfin.apiclient.model.dto.BaseItemDto;
|
||||
import org.jellyfin.apiclient.model.playlists.PlaylistCreationRequest;
|
||||
import org.jellyfin.apiclient.model.playlists.PlaylistItemQuery;
|
||||
import org.jellyfin.apiclient.model.querying.ItemsResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PlaylistUtil {
|
||||
public static void getPlaylist(PlaylistItemQuery query, MediaCallback callback) {
|
||||
query.setUserId(App.getApiClient().getCurrentUserId());
|
||||
query.setLimit(100);
|
||||
App.getApiClient().GetPlaylistItems(query, new Response<ItemsResult>() {
|
||||
@Override
|
||||
public void onResponse(ItemsResult result) {
|
||||
List<PlaylistSong> songs = new ArrayList<>();
|
||||
for (BaseItemDto itemDto : result.getItems()) {
|
||||
songs.add(new PlaylistSong(itemDto, query.getId()));
|
||||
}
|
||||
|
||||
callback.onLoadMedia(songs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void createPlaylist(final String name, final List<Song> songs) {
|
||||
ArrayList<String> ids = new ArrayList<>();
|
||||
for (Song song : songs) {
|
||||
ids.add(song.id);
|
||||
}
|
||||
|
||||
PlaylistCreationRequest request = new PlaylistCreationRequest();
|
||||
request.setUserId(App.getApiClient().getCurrentUserId());
|
||||
request.setName(name);
|
||||
if (ids.size() != 0) request.setItemIdList(ids);
|
||||
App.getApiClient().CreatePlaylist(request, new Response<>());
|
||||
}
|
||||
|
||||
public static void deletePlaylist(final List<Playlist> playlists) {
|
||||
for (Playlist playlist : playlists) {
|
||||
App.getApiClient().DeleteItem(playlist.id, new EmptyResponse());
|
||||
}
|
||||
}
|
||||
|
||||
public static void addItems(final List<Song> songs, final String playlist) {
|
||||
String[] ids = new String[songs.size()];
|
||||
for (int i = 0; i < songs.size(); i++) {
|
||||
ids[i] = songs.get(i).id;
|
||||
}
|
||||
|
||||
String user = App.getApiClient().getCurrentUserId();
|
||||
App.getApiClient().AddToPlaylist(playlist, ids, user, new EmptyResponse());
|
||||
}
|
||||
|
||||
public static void deleteItems(final List<PlaylistSong> songs, final String playlist) {
|
||||
String[] ids = new String[songs.size()];
|
||||
for (int i = 0; i < songs.size(); i++) {
|
||||
ids[i] = songs.get(i).indexId;
|
||||
}
|
||||
|
||||
App.getApiClient().RemoveFromPlaylist(playlist, ids, new EmptyResponse());
|
||||
}
|
||||
|
||||
public static void moveItem(final String playlist, final PlaylistSong song, int to) {
|
||||
App.getApiClient().MoveItem(playlist, song.indexId, to, new EmptyResponse());
|
||||
}
|
||||
|
||||
public static void renamePlaylist(final String playlist, final String name) {
|
||||
String user = App.getApiClient().getCurrentUserId();
|
||||
App.getApiClient().GetItemAsync(playlist, user, new Response<BaseItemDto>() {
|
||||
@Override
|
||||
public void onResponse(BaseItemDto itemDto) {
|
||||
itemDto.setName(name);
|
||||
renamePlaylistInner(itemDto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void renamePlaylistInner(final BaseItemDto itemDto) {
|
||||
// TODO at some point this should become metadata utilities
|
||||
App.getApiClient().UpdateItem(itemDto.getId(), itemDto, new EmptyResponse());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,392 @@
|
|||
package com.dkanada.gramophone.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import androidx.annotation.StyleRes;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import com.dkanada.gramophone.R;
|
||||
import com.dkanada.gramophone.helper.sort.SortMethod;
|
||||
import com.dkanada.gramophone.helper.sort.SortOrder;
|
||||
import com.dkanada.gramophone.model.CategoryInfo;
|
||||
import com.dkanada.gramophone.ui.fragments.player.NowPlayingScreen;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class PreferenceUtil {
|
||||
public static final String LIBRARY_CATEGORIES = "library_categories";
|
||||
public static final String REMEMBER_LAST_TAB = "remember_last_tab";
|
||||
public static final String LAST_TAB = "last_tab";
|
||||
|
||||
public static final String NOW_PLAYING_SCREEN = "now_playing_screen";
|
||||
|
||||
public static final String ALBUM_SORT_METHOD = "album_sort_method";
|
||||
public static final String SONG_SORT_METHOD = "song_sort_method";
|
||||
|
||||
public static final String ALBUM_SORT_ORDER = "album_sort_order";
|
||||
public static final String SONG_SORT_ORDER = "song_sort_order";
|
||||
|
||||
public static final String ALBUM_GRID_SIZE = "album_grid_size";
|
||||
public static final String ALBUM_GRID_SIZE_LAND = "album_grid_size_land";
|
||||
|
||||
public static final String SONG_GRID_SIZE = "song_grid_size";
|
||||
public static final String SONG_GRID_SIZE_LAND = "song_grid_size_land";
|
||||
|
||||
public static final String ARTIST_GRID_SIZE = "artist_grid_size";
|
||||
public static final String ARTIST_GRID_SIZE_LAND = "artist_grid_size_land";
|
||||
|
||||
public static final String ALBUM_COLORED_FOOTERS = "album_colored_footers";
|
||||
public static final String SONG_COLORED_FOOTERS = "song_colored_footers";
|
||||
public static final String ARTIST_COLORED_FOOTERS = "artist_colored_footers";
|
||||
public static final String ALBUM_ARTIST_COLORED_FOOTERS = "album_artist_colored_footers";
|
||||
|
||||
public static final String COLORED_NOTIFICATION = "colored_notification";
|
||||
public static final String CLASSIC_NOTIFICATION = "classic_notification";
|
||||
|
||||
public static final String GENERAL_THEME = "general_theme";
|
||||
public static final String COLORED_SHORTCUTS = "colored_shortcuts";
|
||||
|
||||
public static final String AUDIO_DUCKING = "audio_ducking";
|
||||
public static final String GAPLESS_PLAYBACK = "gapless_playback";
|
||||
public static final String REMEMBER_SHUFFLE = "remember_shuffle";
|
||||
|
||||
public static final String SHOW_ALBUM_COVER = "show_album_cover";
|
||||
public static final String BLUR_ALBUM_COVER = "blur_album_cover";
|
||||
|
||||
public static final String SLEEP_TIMER_LAST_VALUE = "sleep_timer_last_value";
|
||||
public static final String SLEEP_TIMER_ELAPSED_REALTIME = "sleep_timer_elapsed_real_time";
|
||||
public static final String SLEEP_TIMER_FINISH_SONG = "sleep_timer_finish_music";
|
||||
|
||||
private static PreferenceUtil sInstance;
|
||||
|
||||
private final SharedPreferences mPreferences;
|
||||
|
||||
private PreferenceUtil(final Context context) {
|
||||
mPreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
}
|
||||
|
||||
public static PreferenceUtil getInstance(final Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new PreferenceUtil(context.getApplicationContext());
|
||||
}
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public void registerOnSharedPreferenceChangedListener(SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener) {
|
||||
mPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||
}
|
||||
|
||||
public void unregisterOnSharedPreferenceChangedListener(SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener) {
|
||||
mPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||
}
|
||||
|
||||
@StyleRes
|
||||
public int getGeneralTheme() {
|
||||
return getThemeResFromPrefValue(mPreferences.getString(GENERAL_THEME, "dark"));
|
||||
}
|
||||
|
||||
@StyleRes
|
||||
public static int getThemeResFromPrefValue(String themePrefValue) {
|
||||
switch (themePrefValue) {
|
||||
case "light":
|
||||
return R.style.Theme_Phonograph_Light;
|
||||
case "black":
|
||||
return R.style.Theme_Phonograph_Black;
|
||||
case "dark":
|
||||
default:
|
||||
return R.style.Theme_Phonograph;
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean getRememberLastTab() {
|
||||
return mPreferences.getBoolean(REMEMBER_LAST_TAB, true);
|
||||
}
|
||||
|
||||
public final int getLastTab() {
|
||||
return mPreferences.getInt(LAST_TAB, 0);
|
||||
}
|
||||
|
||||
public void setLastTab(final int value) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putInt(LAST_TAB, value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final NowPlayingScreen getNowPlayingScreen() {
|
||||
int id = mPreferences.getInt(NOW_PLAYING_SCREEN, 0);
|
||||
for (NowPlayingScreen nowPlayingScreen : NowPlayingScreen.values()) {
|
||||
if (nowPlayingScreen.id == id) return nowPlayingScreen;
|
||||
}
|
||||
|
||||
return NowPlayingScreen.CARD;
|
||||
}
|
||||
|
||||
public void setNowPlayingScreen(NowPlayingScreen nowPlayingScreen) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putInt(NOW_PLAYING_SCREEN, nowPlayingScreen.id);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final boolean getColoredNotification() {
|
||||
return mPreferences.getBoolean(COLORED_NOTIFICATION, true);
|
||||
}
|
||||
|
||||
public void setColoredNotification(final boolean value) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putBoolean(COLORED_NOTIFICATION, value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final boolean getClassicNotification() {
|
||||
return mPreferences.getBoolean(CLASSIC_NOTIFICATION, true);
|
||||
}
|
||||
|
||||
public void setClassicNotification(final boolean value) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putBoolean(CLASSIC_NOTIFICATION, value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final boolean getColoredShortcuts() {
|
||||
return mPreferences.getBoolean(COLORED_SHORTCUTS, true);
|
||||
}
|
||||
|
||||
public void setColoredShortcuts(final boolean value) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putBoolean(COLORED_SHORTCUTS, value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final boolean getAudioDucking() {
|
||||
return mPreferences.getBoolean(AUDIO_DUCKING, true);
|
||||
}
|
||||
|
||||
public final boolean getGaplessPlayback() {
|
||||
return mPreferences.getBoolean(GAPLESS_PLAYBACK, true);
|
||||
}
|
||||
|
||||
public final boolean getRememberShuffle() {
|
||||
return mPreferences.getBoolean(REMEMBER_SHUFFLE, true);
|
||||
}
|
||||
|
||||
public final boolean getShowAlbumCover() {
|
||||
return mPreferences.getBoolean(SHOW_ALBUM_COVER, true);
|
||||
}
|
||||
|
||||
public final boolean getBlurAlbumCover() {
|
||||
return mPreferences.getBoolean(BLUR_ALBUM_COVER, true);
|
||||
}
|
||||
|
||||
public final String getAlbumSortOrder() {
|
||||
return mPreferences.getString(ALBUM_SORT_ORDER, SortOrder.DESCENDING);
|
||||
}
|
||||
|
||||
public void setAlbumSortOrder(final String sortOrder) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putString(ALBUM_SORT_ORDER, sortOrder);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public final String getSongSortOrder() {
|
||||
return mPreferences.getString(SONG_SORT_ORDER, SortOrder.DESCENDING);
|
||||
}
|
||||
|
||||
public void setSongSortOrder(final String sortOrder) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putString(SONG_SORT_ORDER, sortOrder);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public final String getAlbumSortMethod() {
|
||||
return mPreferences.getString(ALBUM_SORT_METHOD, SortMethod.NAME);
|
||||
}
|
||||
|
||||
public void setAlbumSortMethod(final String sortMethod) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putString(ALBUM_SORT_METHOD, sortMethod);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public final String getSongSortMethod() {
|
||||
return mPreferences.getString(SONG_SORT_METHOD, SortMethod.NAME);
|
||||
}
|
||||
|
||||
public void setSongSortMethod(final String sortMethod) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putString(SONG_SORT_METHOD, sortMethod);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public int getLastSleepTimerValue() {
|
||||
return mPreferences.getInt(SLEEP_TIMER_LAST_VALUE, 30);
|
||||
}
|
||||
|
||||
public void setLastSleepTimerValue(final int value) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putInt(SLEEP_TIMER_LAST_VALUE, value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public long getNextSleepTimerElapsedRealTime() {
|
||||
return mPreferences.getLong(SLEEP_TIMER_ELAPSED_REALTIME, -1);
|
||||
}
|
||||
|
||||
public void setNextSleepTimerElapsedRealtime(final long value) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putLong(SLEEP_TIMER_ELAPSED_REALTIME, value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public boolean getSleepTimerFinishMusic() {
|
||||
return mPreferences.getBoolean(SLEEP_TIMER_FINISH_SONG, false);
|
||||
}
|
||||
|
||||
public void setSleepTimerFinishMusic(final boolean value) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putBoolean(SLEEP_TIMER_FINISH_SONG, value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final int getAlbumGridSize(Context context) {
|
||||
return mPreferences.getInt(ALBUM_GRID_SIZE, context.getResources().getInteger(R.integer.default_grid_columns));
|
||||
}
|
||||
|
||||
public void setAlbumGridSize(final int gridSize) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putInt(ALBUM_GRID_SIZE, gridSize);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final int getSongGridSize(Context context) {
|
||||
return mPreferences.getInt(SONG_GRID_SIZE, context.getResources().getInteger(R.integer.default_list_columns));
|
||||
}
|
||||
|
||||
public void setSongGridSize(final int gridSize) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putInt(SONG_GRID_SIZE, gridSize);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final int getArtistGridSize(Context context) {
|
||||
return mPreferences.getInt(ARTIST_GRID_SIZE, context.getResources().getInteger(R.integer.default_list_columns));
|
||||
}
|
||||
|
||||
public void setArtistGridSize(final int gridSize) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putInt(ARTIST_GRID_SIZE, gridSize);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final int getAlbumGridSizeLand(Context context) {
|
||||
return mPreferences.getInt(ALBUM_GRID_SIZE_LAND, context.getResources().getInteger(R.integer.default_grid_columns_land));
|
||||
}
|
||||
|
||||
public void setAlbumGridSizeLand(final int gridSize) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putInt(ALBUM_GRID_SIZE_LAND, gridSize);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final int getSongGridSizeLand(Context context) {
|
||||
return mPreferences.getInt(SONG_GRID_SIZE_LAND, context.getResources().getInteger(R.integer.default_list_columns_land));
|
||||
}
|
||||
|
||||
public void setSongGridSizeLand(final int gridSize) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putInt(SONG_GRID_SIZE_LAND, gridSize);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final int getArtistGridSizeLand(Context context) {
|
||||
return mPreferences.getInt(ARTIST_GRID_SIZE_LAND, context.getResources().getInteger(R.integer.default_list_columns_land));
|
||||
}
|
||||
|
||||
public void setArtistGridSizeLand(final int gridSize) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putInt(ARTIST_GRID_SIZE_LAND, gridSize);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final boolean getAlbumColoredFooters() {
|
||||
return mPreferences.getBoolean(ALBUM_COLORED_FOOTERS, true);
|
||||
}
|
||||
|
||||
public void setAlbumColoredFooters(final boolean value) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putBoolean(ALBUM_COLORED_FOOTERS, value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final boolean getAlbumArtistColoredFooters() {
|
||||
return mPreferences.getBoolean(ALBUM_ARTIST_COLORED_FOOTERS, true);
|
||||
}
|
||||
|
||||
public void setAlbumArtistColoredFooters(final boolean value) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putBoolean(ALBUM_ARTIST_COLORED_FOOTERS, value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final boolean getSongColoredFooters() {
|
||||
return mPreferences.getBoolean(SONG_COLORED_FOOTERS, true);
|
||||
}
|
||||
|
||||
public void setSongColoredFooters(final boolean value) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putBoolean(SONG_COLORED_FOOTERS, value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public final boolean getArtistColoredFooters() {
|
||||
return mPreferences.getBoolean(ARTIST_COLORED_FOOTERS, true);
|
||||
}
|
||||
|
||||
public void setArtistColoredFooters(final boolean value) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putBoolean(ARTIST_COLORED_FOOTERS, value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public List<CategoryInfo> getLibraryCategories() {
|
||||
String data = mPreferences.getString(LIBRARY_CATEGORIES, null);
|
||||
if (data != null) {
|
||||
Gson gson = new Gson();
|
||||
Type collectionType = new TypeToken<List<CategoryInfo>>() {
|
||||
}.getType();
|
||||
|
||||
try {
|
||||
return gson.fromJson(data, collectionType);
|
||||
} catch (JsonSyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return getDefaultLibraryCategories();
|
||||
}
|
||||
|
||||
public void setLibraryCategories(List<CategoryInfo> categories) {
|
||||
Gson gson = new Gson();
|
||||
Type collectionType = new TypeToken<List<CategoryInfo>>() {}.getType();
|
||||
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putString(LIBRARY_CATEGORIES, gson.toJson(categories, collectionType));
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public List<CategoryInfo> getDefaultLibraryCategories() {
|
||||
List<CategoryInfo> defaultCategories = new ArrayList<>(5);
|
||||
defaultCategories.add(new CategoryInfo(CategoryInfo.Category.SONGS, true));
|
||||
defaultCategories.add(new CategoryInfo(CategoryInfo.Category.ALBUMS, true));
|
||||
defaultCategories.add(new CategoryInfo(CategoryInfo.Category.ARTISTS, true));
|
||||
defaultCategories.add(new CategoryInfo(CategoryInfo.Category.GENRES, true));
|
||||
defaultCategories.add(new CategoryInfo(CategoryInfo.Category.PLAYLISTS, true));
|
||||
return defaultCategories;
|
||||
}
|
||||
}
|
||||
220
app/src/main/java/com/dkanada/gramophone/util/QueryUtil.java
Normal file
220
app/src/main/java/com/dkanada/gramophone/util/QueryUtil.java
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
package com.dkanada.gramophone.util;
|
||||
|
||||
import com.dkanada.gramophone.App;
|
||||
import com.dkanada.gramophone.helper.sort.SortMethod;
|
||||
import com.dkanada.gramophone.interfaces.MediaCallback;
|
||||
import com.dkanada.gramophone.model.Album;
|
||||
import com.dkanada.gramophone.model.Artist;
|
||||
import com.dkanada.gramophone.model.Genre;
|
||||
import com.dkanada.gramophone.model.Playlist;
|
||||
import com.dkanada.gramophone.model.Song;
|
||||
|
||||
import org.jellyfin.apiclient.interaction.Response;
|
||||
import org.jellyfin.apiclient.model.dto.BaseItemDto;
|
||||
import org.jellyfin.apiclient.model.dto.BaseItemType;
|
||||
import org.jellyfin.apiclient.model.querying.ArtistsQuery;
|
||||
import org.jellyfin.apiclient.model.querying.ItemFields;
|
||||
import org.jellyfin.apiclient.model.querying.ItemQuery;
|
||||
import org.jellyfin.apiclient.model.querying.ItemsByNameQuery;
|
||||
import org.jellyfin.apiclient.model.querying.ItemsResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class QueryUtil {
|
||||
public static BaseItemDto currentLibrary;
|
||||
|
||||
// TODO return BaseItemDto everywhere
|
||||
// will simplify the code for the getPlaylists method
|
||||
public static void getLibraries(MediaCallback callback) {
|
||||
String id = App.getApiClient().getCurrentUserId();
|
||||
App.getApiClient().GetUserViews(id, new Response<ItemsResult>() {
|
||||
@Override
|
||||
public void onResponse(ItemsResult result) {
|
||||
List<BaseItemDto> libraries = new ArrayList<>();
|
||||
libraries.addAll(Arrays.asList(result.getItems()));
|
||||
|
||||
callback.onLoadMedia(libraries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void getPlaylists(MediaCallback callback) {
|
||||
ItemQuery query = new ItemQuery();
|
||||
query.setIncludeItemTypes(new String[]{"Playlist"});
|
||||
query.setUserId(App.getApiClient().getCurrentUserId());
|
||||
query.setLimit(100);
|
||||
query.setRecursive(true);
|
||||
if (currentLibrary != null && query.getParentId() == null) query.setParentId(currentLibrary.getId());
|
||||
App.getApiClient().GetItemsAsync(query, new Response<ItemsResult>() {
|
||||
@Override
|
||||
public void onResponse(ItemsResult result) {
|
||||
List<Playlist> playlists = new ArrayList<>();
|
||||
for (BaseItemDto itemDto : result.getItems()) {
|
||||
playlists.add(new Playlist(itemDto));
|
||||
}
|
||||
|
||||
callback.onLoadMedia(playlists);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void getGenres(MediaCallback callback) {
|
||||
ItemsByNameQuery query = new ItemsByNameQuery();
|
||||
query.setUserId(App.getApiClient().getCurrentUserId());
|
||||
query.setLimit(100);
|
||||
query.setRecursive(true);
|
||||
if (currentLibrary != null && query.getParentId() == null) query.setParentId(currentLibrary.getId());
|
||||
App.getApiClient().GetGenresAsync(query, new Response<ItemsResult>() {
|
||||
@Override
|
||||
public void onResponse(ItemsResult result) {
|
||||
List<Genre> genres = new ArrayList<>();
|
||||
for (BaseItemDto itemDto : result.getItems()) {
|
||||
genres.add(new Genre(itemDto));
|
||||
}
|
||||
|
||||
callback.onLoadMedia(genres);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void getItems(ItemQuery query, MediaCallback callback) {
|
||||
query.setIncludeItemTypes(new String[]{"MusicArtist", "MusicAlbum", "Audio"});
|
||||
query.setUserId(App.getApiClient().getCurrentUserId());
|
||||
query.setLimit(40);
|
||||
query.setRecursive(true);
|
||||
App.getApiClient().GetItemsAsync(query, new Response<ItemsResult>() {
|
||||
@Override
|
||||
public void onResponse(ItemsResult result) {
|
||||
List<Object> items = new ArrayList<>();
|
||||
for (BaseItemDto itemDto : result.getItems()) {
|
||||
if (itemDto.getBaseItemType() == BaseItemType.MusicArtist) {
|
||||
items.add(new Artist(itemDto));
|
||||
} else if (itemDto.getBaseItemType() == BaseItemType.MusicAlbum) {
|
||||
items.add(new Album(itemDto));
|
||||
} else {
|
||||
items.add(new Song(itemDto));
|
||||
}
|
||||
}
|
||||
|
||||
callback.onLoadMedia(items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void getAlbums(ItemQuery query, MediaCallback callback) {
|
||||
query.setIncludeItemTypes(new String[]{"MusicAlbum"});
|
||||
query.setUserId(App.getApiClient().getCurrentUserId());
|
||||
query.setLimit(100);
|
||||
query.setRecursive(true);
|
||||
applySortMethod(query, PreferenceUtil.getInstance(App.getInstance()).getAlbumSortMethod());
|
||||
if (currentLibrary != null && query.getParentId() == null) query.setParentId(currentLibrary.getId());
|
||||
App.getApiClient().GetItemsAsync(query, new Response<ItemsResult>() {
|
||||
@Override
|
||||
public void onResponse(ItemsResult result) {
|
||||
List<Album> albums = new ArrayList<>();
|
||||
for (BaseItemDto itemDto : result.getItems()) {
|
||||
albums.add(new Album(itemDto));
|
||||
}
|
||||
|
||||
callback.onLoadMedia(albums);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void getArtists(MediaCallback callback) {
|
||||
ArtistsQuery query = new ArtistsQuery();
|
||||
query.setFields(new ItemFields[]{ItemFields.Genres});
|
||||
query.setUserId(App.getApiClient().getCurrentUserId());
|
||||
query.setLimit(100);
|
||||
query.setRecursive(true);
|
||||
if (currentLibrary != null && query.getParentId() == null) query.setParentId(currentLibrary.getId());
|
||||
App.getApiClient().GetAlbumArtistsAsync(query, new Response<ItemsResult>() {
|
||||
@Override
|
||||
public void onResponse(ItemsResult result) {
|
||||
List<Artist> artists = new ArrayList<>();
|
||||
for (BaseItemDto itemDto : result.getItems()) {
|
||||
artists.add(new Artist(itemDto));
|
||||
}
|
||||
|
||||
callback.onLoadMedia(artists);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void getSongs(ItemQuery query, MediaCallback callback) {
|
||||
query.setIncludeItemTypes(new String[]{"Audio"});
|
||||
query.setUserId(App.getApiClient().getCurrentUserId());
|
||||
query.setLimit(100);
|
||||
query.setRecursive(true);
|
||||
applySortMethod(query, PreferenceUtil.getInstance(App.getInstance()).getSongSortMethod());
|
||||
if (currentLibrary != null && query.getParentId() == null) query.setParentId(currentLibrary.getId());
|
||||
App.getApiClient().GetItemsAsync(query, new Response<ItemsResult>() {
|
||||
@Override
|
||||
public void onResponse(ItemsResult result) {
|
||||
List<Song> songs = new ArrayList<>();
|
||||
for (BaseItemDto itemDto : result.getItems()) {
|
||||
songs.add(new Song(itemDto));
|
||||
}
|
||||
|
||||
callback.onLoadMedia(songs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void applySortMethod(ItemQuery query, String method) {
|
||||
switch (method) {
|
||||
case SortMethod.NAME:
|
||||
query.setSortBy(new String[]{"SortName"});
|
||||
break;
|
||||
case SortMethod.ALBUM:
|
||||
query.setSortBy(new String[]{"Album"});
|
||||
break;
|
||||
case SortMethod.ARTIST:
|
||||
query.setSortBy(new String[]{"AlbumArtist"});
|
||||
break;
|
||||
case SortMethod.YEAR:
|
||||
query.setSortBy(new String[]{"ProductionYear"});
|
||||
break;
|
||||
case SortMethod.RANDOM:
|
||||
query.setSortBy(new String[]{"Random"});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
78
app/src/main/java/com/dkanada/gramophone/util/ThemeUtil.java
Normal file
78
app/src/main/java/com/dkanada/gramophone/util/ThemeUtil.java
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
package com.dkanada.gramophone.util;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.palette.graphics.Palette;
|
||||
|
||||
import com.kabouzeid.appthemehelper.util.ColorUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
public class ThemeUtil {
|
||||
|
||||
@Nullable
|
||||
public static Palette generatePalette(Bitmap bitmap) {
|
||||
if (bitmap == null) return null;
|
||||
return Palette.from(bitmap).generate();
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
public static int getColor(@Nullable Palette palette, int fallback) {
|
||||
if (palette != null) {
|
||||
if (palette.getVibrantSwatch() != null) {
|
||||
return palette.getVibrantSwatch().getRgb();
|
||||
} else if (palette.getMutedSwatch() != null) {
|
||||
return palette.getMutedSwatch().getRgb();
|
||||
} else if (palette.getDarkVibrantSwatch() != null) {
|
||||
return palette.getDarkVibrantSwatch().getRgb();
|
||||
} else if (palette.getDarkMutedSwatch() != null) {
|
||||
return palette.getDarkMutedSwatch().getRgb();
|
||||
} else if (palette.getLightVibrantSwatch() != null) {
|
||||
return palette.getLightVibrantSwatch().getRgb();
|
||||
} else if (palette.getLightMutedSwatch() != null) {
|
||||
return palette.getLightMutedSwatch().getRgb();
|
||||
} else if (!palette.getSwatches().isEmpty()) {
|
||||
return Collections.max(palette.getSwatches(), SwatchComparator.getInstance()).getRgb();
|
||||
}
|
||||
}
|
||||
|
||||
return fallback;
|
||||
}
|
||||
|
||||
private static class SwatchComparator implements Comparator<Palette.Swatch> {
|
||||
private static SwatchComparator sInstance;
|
||||
|
||||
static SwatchComparator getInstance() {
|
||||
if (sInstance == null) {
|
||||
sInstance = new SwatchComparator();
|
||||
}
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(Palette.Swatch lhs, Palette.Swatch rhs) {
|
||||
return lhs.getPopulation() - rhs.getPopulation();
|
||||
}
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
public static int shiftBackgroundColorForLightText(@ColorInt int backgroundColor) {
|
||||
while (ColorUtil.isColorLight(backgroundColor)) {
|
||||
backgroundColor = ColorUtil.darkenColor(backgroundColor);
|
||||
}
|
||||
|
||||
return backgroundColor;
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
public static int shiftBackgroundColorForDarkText(@ColorInt int backgroundColor) {
|
||||
while (!ColorUtil.isColorLight(backgroundColor)) {
|
||||
backgroundColor = ColorUtil.lightenColor(backgroundColor);
|
||||
}
|
||||
|
||||
return backgroundColor;
|
||||
}
|
||||
}
|
||||
86
app/src/main/java/com/dkanada/gramophone/util/Util.java
Normal file
86
app/src/main/java/com/dkanada/gramophone/util/Util.java
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
package com.dkanada.gramophone.util;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Point;
|
||||
import android.os.Build;
|
||||
import androidx.annotation.AttrRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Display;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import com.dkanada.gramophone.R;
|
||||
|
||||
public class Util {
|
||||
|
||||
public static int getActionBarSize(@NonNull Context context) {
|
||||
TypedValue typedValue = new TypedValue();
|
||||
int[] textSizeAttr = new int[]{R.attr.actionBarSize};
|
||||
int indexOfAttrTextSize = 0;
|
||||
TypedArray a = context.obtainStyledAttributes(typedValue.data, textSizeAttr);
|
||||
int actionBarSize = a.getDimensionPixelSize(indexOfAttrTextSize, -1);
|
||||
a.recycle();
|
||||
return actionBarSize;
|
||||
}
|
||||
|
||||
public static Point getScreenSize(@NonNull Context c) {
|
||||
Display display = ((WindowManager) c.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||
Point size = new Point();
|
||||
display.getSize(size);
|
||||
return size;
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.KITKAT)
|
||||
public static void setStatusBarTranslucent(@NonNull Window window) {
|
||||
window.setFlags(
|
||||
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
|
||||
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
}
|
||||
|
||||
public static void setAllowDrawUnderStatusBar(@NonNull Window window) {
|
||||
window.getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
}
|
||||
|
||||
public static void hideSoftKeyboard(@Nullable Activity activity) {
|
||||
if (activity != null) {
|
||||
View currentFocus = activity.getCurrentFocus();
|
||||
if (currentFocus != null) {
|
||||
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
|
||||
inputMethodManager.hideSoftInputFromWindow(currentFocus.getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isTablet(@NonNull final Resources resources) {
|
||||
return resources.getConfiguration().smallestScreenWidthDp >= 600;
|
||||
}
|
||||
|
||||
public static boolean isLandscape(@NonNull final Resources resources) {
|
||||
return resources.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
|
||||
}
|
||||
|
||||
public static int resolveDimensionPixelSize(@NonNull Context context, @AttrRes int dimenAttr) {
|
||||
TypedArray a = context.obtainStyledAttributes(new int[]{dimenAttr});
|
||||
int dimensionPixelSize = a.getDimensionPixelSize(0, 0);
|
||||
a.recycle();
|
||||
return dimensionPixelSize;
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
public static boolean isRTL(@NonNull Context context) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
Configuration config = context.getResources().getConfiguration();
|
||||
return config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
|
||||
} else return false;
|
||||
}
|
||||
}
|
||||
95
app/src/main/java/com/dkanada/gramophone/util/ViewUtil.java
Normal file
95
app/src/main/java/com/dkanada/gramophone/util/ViewUtil.java
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
package com.dkanada.gramophone.util;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.graphics.drawable.StateListDrawable;
|
||||
import android.os.Build;
|
||||
import androidx.annotation.ColorInt;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.view.animation.PathInterpolator;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.kabouzeid.appthemehelper.util.ATHUtil;
|
||||
import com.kabouzeid.appthemehelper.util.ColorUtil;
|
||||
import com.kabouzeid.appthemehelper.util.MaterialValueHelper;
|
||||
import com.dkanada.gramophone.R;
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
public class ViewUtil {
|
||||
public final static int PHONOGRAPH_ANIM_TIME = 1000;
|
||||
|
||||
public static Animator createBackgroundColorTransition(final View v, @ColorInt final int startColor, @ColorInt final int endColor) {
|
||||
return createColorAnimator(v, "backgroundColor", startColor, endColor);
|
||||
}
|
||||
|
||||
public static Animator createTextColorTransition(final TextView v, @ColorInt final int startColor, @ColorInt final int endColor) {
|
||||
return createColorAnimator(v, "textColor", startColor, endColor);
|
||||
}
|
||||
|
||||
private static Animator createColorAnimator(Object target, String propertyName, @ColorInt int startColor, @ColorInt int endColor) {
|
||||
ObjectAnimator animator;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
animator = ObjectAnimator.ofArgb(target, propertyName, startColor, endColor);
|
||||
} else {
|
||||
animator = ObjectAnimator.ofInt(target, propertyName, startColor, endColor);
|
||||
animator.setEvaluator(new ArgbEvaluator());
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
animator.setInterpolator(new PathInterpolator(0.4f, 0f, 1f, 1f));
|
||||
}
|
||||
|
||||
animator.setDuration(PHONOGRAPH_ANIM_TIME);
|
||||
return animator;
|
||||
}
|
||||
|
||||
public static Drawable createSelectorDrawable(Context context, @ColorInt int color) {
|
||||
final StateListDrawable baseSelector = new StateListDrawable();
|
||||
baseSelector.addState(new int[]{android.R.attr.state_activated}, new ColorDrawable(color));
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
return new RippleDrawable(ColorStateList.valueOf(color), baseSelector, new ColorDrawable(Color.WHITE));
|
||||
}
|
||||
|
||||
baseSelector.addState(new int[]{}, new ColorDrawable(Color.TRANSPARENT));
|
||||
baseSelector.addState(new int[]{android.R.attr.state_pressed}, new ColorDrawable(color));
|
||||
return baseSelector;
|
||||
}
|
||||
|
||||
public static boolean hitTest(View v, int x, int y) {
|
||||
final int tx = (int) (v.getTranslationX() + 0.5f);
|
||||
final int ty = (int) (v.getTranslationY() + 0.5f);
|
||||
final int left = v.getLeft() + tx;
|
||||
final int right = v.getRight() + tx;
|
||||
final int top = v.getTop() + ty;
|
||||
final int bottom = v.getBottom() + ty;
|
||||
|
||||
return (x >= left) && (x <= right) && (y >= top) && (y <= bottom);
|
||||
}
|
||||
|
||||
public static void setUpFastScrollRecyclerViewColor(Context context, FastScrollRecyclerView recyclerView, int accentColor) {
|
||||
recyclerView.setPopupBgColor(accentColor);
|
||||
recyclerView.setPopupTextColor(MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(accentColor)));
|
||||
recyclerView.setThumbColor(accentColor);
|
||||
recyclerView.setTrackColor(ColorUtil.withAlpha(ATHUtil.resolveColor(context, R.attr.colorControlNormal), 0.12f));
|
||||
}
|
||||
|
||||
public static float convertDpToPixel(float dp, Resources resources) {
|
||||
DisplayMetrics metrics = resources.getDisplayMetrics();
|
||||
return dp * metrics.density;
|
||||
}
|
||||
|
||||
public static float convertPixelsToDp(float px, Resources resources) {
|
||||
DisplayMetrics metrics = resources.getDisplayMetrics();
|
||||
return px / metrics.density;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue