mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2025-04-25 21:22:16 +03:00
Delete a bunch of now-unused classes
Also run KtLint
This commit is contained in:
parent
f8a87f7c85
commit
eeb2d13d96
@ -19,7 +19,6 @@ import androidx.lifecycle.LiveData
|
|||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
@ -41,7 +40,6 @@ import org.moire.ultrasonic.util.Constants
|
|||||||
import org.moire.ultrasonic.util.Settings
|
import org.moire.ultrasonic.util.Settings
|
||||||
import org.moire.ultrasonic.util.Util.toast
|
import org.moire.ultrasonic.util.Util.toast
|
||||||
import org.moire.ultrasonic.view.ArtistAdapter
|
import org.moire.ultrasonic.view.ArtistAdapter
|
||||||
import org.moire.ultrasonic.view.EntryAdapter
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,16 +73,16 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
|
|||||||
|
|
||||||
override val mainLayout: Int = R.layout.search
|
override val mainLayout: Int = R.layout.search
|
||||||
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
cancellationToken = CancellationToken()
|
cancellationToken = CancellationToken()
|
||||||
setTitle(this, R.string.search_title)
|
setTitle(this, R.string.search_title)
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
|
|
||||||
|
val buttons = LayoutInflater.from(context).inflate(
|
||||||
val buttons = LayoutInflater.from(context).inflate(R.layout.search_buttons,
|
R.layout.search_buttons,
|
||||||
listView, false)
|
listView, false
|
||||||
|
)
|
||||||
|
|
||||||
if (buttons != null) {
|
if (buttons != null) {
|
||||||
artistsHeading = buttons.findViewById(R.id.search_artists)
|
artistsHeading = buttons.findViewById(R.id.search_artists)
|
||||||
@ -96,11 +94,12 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
|
|||||||
moreSongsButton = buttons.findViewById(R.id.search_more_songs)
|
moreSongsButton = buttons.findViewById(R.id.search_more_songs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listModel.searchResult.observe(
|
||||||
listModel.searchResult.observe(viewLifecycleOwner, {
|
viewLifecycleOwner,
|
||||||
if (it != null) populateList(it)
|
{
|
||||||
})
|
if (it != null) populateList(it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
searchRefresh = view.findViewById(R.id.search_entries_refresh)
|
searchRefresh = view.findViewById(R.id.search_entries_refresh)
|
||||||
searchRefresh!!.isEnabled = false
|
searchRefresh!!.isEnabled = false
|
||||||
@ -131,7 +130,6 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
|
|||||||
|
|
||||||
registerForContextMenu(listView!!)
|
registerForContextMenu(listView!!)
|
||||||
|
|
||||||
|
|
||||||
viewAdapter.register(
|
viewAdapter.register(
|
||||||
TrackViewBinder(
|
TrackViewBinder(
|
||||||
checkable = false,
|
checkable = false,
|
||||||
@ -149,7 +147,6 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// Fragment was started with a query (e.g. from voice search), try to execute search right away
|
// Fragment was started with a query (e.g. from voice search), try to execute search right away
|
||||||
val arguments = arguments
|
val arguments = arguments
|
||||||
if (arguments != null) {
|
if (arguments != null) {
|
||||||
@ -432,14 +429,14 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
|
|||||||
list.addAll(artists)
|
list.addAll(artists)
|
||||||
if (artists.size > DEFAULT_ARTISTS) {
|
if (artists.size > DEFAULT_ARTISTS) {
|
||||||
// FIXME
|
// FIXME
|
||||||
//list.add((moreArtistsButton, true)
|
// list.add((moreArtistsButton, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val albums = searchResult.albums
|
val albums = searchResult.albums
|
||||||
if (albums.isNotEmpty()) {
|
if (albums.isNotEmpty()) {
|
||||||
//mergeAdapter!!.addView(albumsHeading)
|
// mergeAdapter!!.addView(albumsHeading)
|
||||||
list.addAll(albums)
|
list.addAll(albums)
|
||||||
//mergeAdapter!!.addAdapter(albumAdapter)
|
// mergeAdapter!!.addAdapter(albumAdapter)
|
||||||
// if (albums.size > DEFAULT_ALBUMS) {
|
// if (albums.size > DEFAULT_ALBUMS) {
|
||||||
// moreAlbumsAdapter = mergeAdapter!!.addView(moreAlbumsButton, true)
|
// moreAlbumsAdapter = mergeAdapter!!.addView(moreAlbumsButton, true)
|
||||||
// }
|
// }
|
||||||
@ -550,6 +547,5 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
|
|||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
override fun onItemClick(item: Identifiable) {
|
override fun onItemClick(item: Identifiable) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,181 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of Subsonic.
|
|
||||||
|
|
||||||
Subsonic is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Subsonic is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Copyright 2009 (C) Sindre Mehus
|
|
||||||
*/
|
|
||||||
package org.moire.ultrasonic.view;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import timber.log.Timber;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import org.moire.ultrasonic.R;
|
|
||||||
import org.moire.ultrasonic.data.ActiveServerProvider;
|
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory;
|
|
||||||
import org.moire.ultrasonic.service.MusicService;
|
|
||||||
import org.moire.ultrasonic.service.MusicServiceFactory;
|
|
||||||
import org.moire.ultrasonic.imageloader.ImageLoader;
|
|
||||||
import org.moire.ultrasonic.util.Settings;
|
|
||||||
import org.moire.ultrasonic.util.Util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to display albums in a {@code ListView}.
|
|
||||||
*
|
|
||||||
* @author Sindre Mehus
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
public class AlbumView extends UpdateView
|
|
||||||
{
|
|
||||||
private static Drawable starDrawable;
|
|
||||||
private static Drawable starHollowDrawable;
|
|
||||||
private static String theme;
|
|
||||||
|
|
||||||
private final Context context;
|
|
||||||
private MusicDirectory.Entry entry;
|
|
||||||
private EntryAdapter.AlbumViewHolder viewHolder;
|
|
||||||
private final ImageLoader imageLoader;
|
|
||||||
private boolean maximized = false;
|
|
||||||
|
|
||||||
public AlbumView(Context context, ImageLoader imageLoader)
|
|
||||||
{
|
|
||||||
super(context);
|
|
||||||
this.context = context;
|
|
||||||
this.imageLoader = imageLoader;
|
|
||||||
|
|
||||||
String theme = Settings.getTheme();
|
|
||||||
boolean themesMatch = theme.equals(AlbumView.theme);
|
|
||||||
AlbumView.theme = theme;
|
|
||||||
|
|
||||||
if (starHollowDrawable == null || !themesMatch)
|
|
||||||
{
|
|
||||||
starHollowDrawable = Util.getDrawableFromAttribute(context, R.attr.star_hollow);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (starDrawable == null || !themesMatch)
|
|
||||||
{
|
|
||||||
starDrawable = Util.getDrawableFromAttribute(context, R.attr.star_full);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLayout()
|
|
||||||
{
|
|
||||||
LayoutInflater.from(context).inflate(R.layout.album_list_item_legacy, this, true);
|
|
||||||
viewHolder = new EntryAdapter.AlbumViewHolder();
|
|
||||||
viewHolder.title = findViewById(R.id.album_title);
|
|
||||||
viewHolder.artist = findViewById(R.id.album_artist);
|
|
||||||
viewHolder.cover_art = findViewById(R.id.album_coverart);
|
|
||||||
viewHolder.star = findViewById(R.id.album_star);
|
|
||||||
setTag(viewHolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setViewHolder(EntryAdapter.AlbumViewHolder viewHolder)
|
|
||||||
{
|
|
||||||
this.viewHolder = viewHolder;
|
|
||||||
this.viewHolder.cover_art.invalidate();
|
|
||||||
setTag(this.viewHolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MusicDirectory.Entry getEntry()
|
|
||||||
{
|
|
||||||
return this.entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMaximized() {
|
|
||||||
return maximized;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void maximizeOrMinimize() {
|
|
||||||
maximized = !maximized;
|
|
||||||
if (this.viewHolder.title != null) {
|
|
||||||
this.viewHolder.title.setSingleLine(!maximized);
|
|
||||||
}
|
|
||||||
if (this.viewHolder.artist != null) {
|
|
||||||
this.viewHolder.artist.setSingleLine(!maximized);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAlbum(final MusicDirectory.Entry album)
|
|
||||||
{
|
|
||||||
viewHolder.cover_art.setTag(album);
|
|
||||||
imageLoader.loadImage(viewHolder.cover_art, album, false, 0);
|
|
||||||
this.entry = album;
|
|
||||||
|
|
||||||
String title = album.getTitle();
|
|
||||||
String artist = album.getArtist();
|
|
||||||
boolean starred = album.getStarred();
|
|
||||||
|
|
||||||
viewHolder.title.setText(title);
|
|
||||||
viewHolder.artist.setText(artist);
|
|
||||||
viewHolder.artist.setVisibility(artist == null ? View.GONE : View.VISIBLE);
|
|
||||||
viewHolder.star.setImageDrawable(starred ? starDrawable : starHollowDrawable);
|
|
||||||
|
|
||||||
if (ActiveServerProvider.Companion.isOffline() || "-1".equals(album.getId()))
|
|
||||||
{
|
|
||||||
viewHolder.star.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
viewHolder.star.setOnClickListener(new View.OnClickListener()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onClick(View view)
|
|
||||||
{
|
|
||||||
final boolean isStarred = album.getStarred();
|
|
||||||
final String id = album.getId();
|
|
||||||
|
|
||||||
if (!isStarred)
|
|
||||||
{
|
|
||||||
viewHolder.star.setImageDrawable(starDrawable);
|
|
||||||
album.setStarred(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
viewHolder.star.setImageDrawable(starHollowDrawable);
|
|
||||||
album.setStarred(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
final MusicService musicService = MusicServiceFactory.getMusicService();
|
|
||||||
new Thread(new Runnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
boolean useId3 = Settings.getShouldUseId3Tags();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!isStarred)
|
|
||||||
{
|
|
||||||
musicService.star(!useId3 ? id : null, useId3 ? id : null, null);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
musicService.unstar(!useId3 ? id : null, useId3 ? id : null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Timber.e(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of Subsonic.
|
|
||||||
|
|
||||||
Subsonic is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Subsonic is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Copyright 2010 (C) Sindre Mehus
|
|
||||||
*/
|
|
||||||
package org.moire.ultrasonic.view;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.CheckedTextView;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory.Entry;
|
|
||||||
import org.moire.ultrasonic.imageloader.ImageLoader;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the adapter for the display of a single list item (song, album, etc)
|
|
||||||
*
|
|
||||||
* @author Sindre Mehus
|
|
||||||
*/
|
|
||||||
public class EntryAdapter extends ArrayAdapter<Entry>
|
|
||||||
{
|
|
||||||
private final Context context;
|
|
||||||
private final ImageLoader imageLoader;
|
|
||||||
private final boolean checkable;
|
|
||||||
|
|
||||||
public EntryAdapter(Context context, ImageLoader imageLoader, List<Entry> entries, boolean checkable)
|
|
||||||
{
|
|
||||||
super(context, android.R.layout.simple_list_item_1, entries);
|
|
||||||
|
|
||||||
this.context = context;
|
|
||||||
this.imageLoader = imageLoader;
|
|
||||||
this.checkable = checkable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent)
|
|
||||||
{
|
|
||||||
Entry entry = getItem(position);
|
|
||||||
|
|
||||||
if (entry.isDirectory())
|
|
||||||
{
|
|
||||||
AlbumView view;
|
|
||||||
|
|
||||||
if (convertView instanceof AlbumView)
|
|
||||||
{
|
|
||||||
AlbumView currentView = (AlbumView) convertView;
|
|
||||||
|
|
||||||
if (currentView.getEntry().equals(entry))
|
|
||||||
{
|
|
||||||
return currentView;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AlbumViewHolder viewHolder = (AlbumViewHolder) currentView.getTag();
|
|
||||||
view = currentView;
|
|
||||||
view.setViewHolder(viewHolder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
view = new AlbumView(context, imageLoader);
|
|
||||||
view.setLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
view.setAlbum(entry);
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SongView view;
|
|
||||||
|
|
||||||
if (convertView instanceof SongView)
|
|
||||||
{
|
|
||||||
SongView currentView = (SongView) convertView;
|
|
||||||
|
|
||||||
if (currentView.getEntry().equals(entry))
|
|
||||||
{
|
|
||||||
currentView.update();
|
|
||||||
return currentView;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SongViewHolder viewHolder = (SongViewHolder) convertView.getTag();
|
|
||||||
view = currentView;
|
|
||||||
view.setViewHolder(viewHolder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
view = new SongView(context);
|
|
||||||
view.setLayout(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
view.setSong(entry, checkable, false);
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SongViewHolder
|
|
||||||
{
|
|
||||||
CheckedTextView check;
|
|
||||||
TextView track;
|
|
||||||
TextView title;
|
|
||||||
TextView status;
|
|
||||||
TextView artist;
|
|
||||||
TextView duration;
|
|
||||||
LinearLayout rating;
|
|
||||||
ImageView fiveStar1;
|
|
||||||
ImageView fiveStar2;
|
|
||||||
ImageView fiveStar3;
|
|
||||||
ImageView fiveStar4;
|
|
||||||
ImageView fiveStar5;
|
|
||||||
ImageView star;
|
|
||||||
ImageView drag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class AlbumViewHolder
|
|
||||||
{
|
|
||||||
TextView artist;
|
|
||||||
ImageView cover_art;
|
|
||||||
ImageView star;
|
|
||||||
TextView title;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,155 +0,0 @@
|
|||||||
package org.moire.ultrasonic.view;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.AbsListView;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
|
|
||||||
import org.moire.ultrasonic.util.Settings;
|
|
||||||
import org.moire.ultrasonic.util.Util;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.WeakHashMap;
|
|
||||||
|
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A View that is periodically refreshed
|
|
||||||
* @deprecated
|
|
||||||
* Use LiveData to ensure that the content is up-to-date
|
|
||||||
**/
|
|
||||||
public class UpdateView extends LinearLayout
|
|
||||||
{
|
|
||||||
private static final WeakHashMap<UpdateView, ?> INSTANCES = new WeakHashMap<UpdateView, Object>();
|
|
||||||
|
|
||||||
private static Handler backgroundHandler;
|
|
||||||
private static Handler uiHandler;
|
|
||||||
private static Runnable updateRunnable;
|
|
||||||
|
|
||||||
public UpdateView(Context context)
|
|
||||||
{
|
|
||||||
super(context);
|
|
||||||
|
|
||||||
setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
||||||
INSTANCES.put(this, null);
|
|
||||||
startUpdater();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPressed(boolean pressed)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static synchronized void startUpdater()
|
|
||||||
{
|
|
||||||
if (uiHandler != null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiHandler = new Handler();
|
|
||||||
updateRunnable = new Runnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
updateAll();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
new Thread(new Runnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
Thread.currentThread().setName("startUpdater");
|
|
||||||
Looper.prepare();
|
|
||||||
backgroundHandler = new Handler(Looper.myLooper());
|
|
||||||
uiHandler.post(updateRunnable);
|
|
||||||
Looper.loop();
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void updateAll()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Collection<UpdateView> views = new ArrayList<UpdateView>();
|
|
||||||
|
|
||||||
for (UpdateView view : INSTANCES.keySet())
|
|
||||||
{
|
|
||||||
if (view.isShown())
|
|
||||||
{
|
|
||||||
views.add(view);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateAllLive(views);
|
|
||||||
}
|
|
||||||
catch (Throwable x)
|
|
||||||
{
|
|
||||||
Timber.w(x, "Error when updating song views.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void updateAllLive(final Iterable<UpdateView> views)
|
|
||||||
{
|
|
||||||
final Runnable runnable = new Runnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for (UpdateView view : views)
|
|
||||||
{
|
|
||||||
view.update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Throwable x)
|
|
||||||
{
|
|
||||||
Timber.w(x, "Error when updating song views.");
|
|
||||||
}
|
|
||||||
|
|
||||||
uiHandler.postDelayed(updateRunnable, Settings.getViewRefreshInterval());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
backgroundHandler.post(new Runnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Thread.currentThread().setName("updateAllLive-Background");
|
|
||||||
|
|
||||||
for (UpdateView view : views)
|
|
||||||
{
|
|
||||||
view.updateBackground();
|
|
||||||
}
|
|
||||||
uiHandler.post(runnable);
|
|
||||||
}
|
|
||||||
catch (Throwable x)
|
|
||||||
{
|
|
||||||
Timber.w(x, "Error when updating song views.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updateBackground()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void update()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -54,7 +54,7 @@ class AlbumRowBinder(
|
|||||||
val popup = Helper.createPopupMenu(holder.itemView)
|
val popup = Helper.createPopupMenu(holder.itemView)
|
||||||
|
|
||||||
popup.setOnMenuItemClickListener { menuItem ->
|
popup.setOnMenuItemClickListener { menuItem ->
|
||||||
onContextMenuClick(menuItem, item)
|
onContextMenuClick(menuItem, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
@ -69,7 +69,6 @@ class AlbumRowBinder(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the view properties of an Item row
|
* Holds the view properties of an Item row
|
||||||
*/
|
*/
|
||||||
@ -84,7 +83,6 @@ class AlbumRowBinder(
|
|||||||
var coverArtId: String? = null
|
var coverArtId: String? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the star / unstar action for an album
|
* Handles the star / unstar action for an album
|
||||||
*/
|
*/
|
||||||
@ -118,4 +116,3 @@ class AlbumRowBinder(
|
|||||||
return ViewHolder(inflater.inflate(layout, parent, false))
|
return ViewHolder(inflater.inflate(layout, parent, false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class ArtistRowBinder(
|
|||||||
val onItemClick: (ArtistOrIndex) -> Unit,
|
val onItemClick: (ArtistOrIndex) -> Unit,
|
||||||
val onContextMenuClick: (MenuItem, ArtistOrIndex) -> Boolean,
|
val onContextMenuClick: (MenuItem, ArtistOrIndex) -> Boolean,
|
||||||
private val imageLoader: ImageLoader,
|
private val imageLoader: ImageLoader,
|
||||||
): ItemViewBinder<ArtistOrIndex, ArtistRowBinder.ViewHolder>(), KoinComponent {
|
) : ItemViewBinder<ArtistOrIndex, ArtistRowBinder.ViewHolder>(), KoinComponent {
|
||||||
|
|
||||||
val layout = R.layout.artist_list_item
|
val layout = R.layout.artist_list_item
|
||||||
val contextMenuLayout = R.menu.artist_context_menu
|
val contextMenuLayout = R.menu.artist_context_menu
|
||||||
|
@ -10,19 +10,20 @@ import android.widget.PopupMenu
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.drakeet.multitype.ItemViewBinder
|
import com.drakeet.multitype.ItemViewBinder
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
import org.moire.ultrasonic.R
|
import org.moire.ultrasonic.R
|
||||||
import org.moire.ultrasonic.domain.Identifiable
|
import org.moire.ultrasonic.domain.Identifiable
|
||||||
import org.moire.ultrasonic.domain.MusicFolder
|
import org.moire.ultrasonic.domain.MusicFolder
|
||||||
import org.moire.ultrasonic.service.RxBus
|
import org.moire.ultrasonic.service.RxBus
|
||||||
import java.lang.ref.WeakReference
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This little view shows the currently selected Folder (or catalog) on the music server.
|
* This little view shows the currently selected Folder (or catalog) on the music server.
|
||||||
* When clicked it will drop down a list of all available Folders and allow you to
|
* When clicked it will drop down a list of all available Folders and allow you to
|
||||||
* select one. The intended usage is to supply a filter to lists of artists, albums, etc
|
* select one. The intended usage is to supply a filter to lists of artists, albums, etc
|
||||||
*/
|
*/
|
||||||
class FolderSelectorBinder(context: Context
|
class FolderSelectorBinder(
|
||||||
|
context: Context
|
||||||
) : ItemViewBinder<FolderSelectorBinder.FolderHeader, FolderSelectorBinder.ViewHolder>(), KoinComponent {
|
) : ItemViewBinder<FolderSelectorBinder.FolderHeader, FolderSelectorBinder.ViewHolder>(), KoinComponent {
|
||||||
|
|
||||||
private val weakContext: WeakReference<Context> = WeakReference(context)
|
private val weakContext: WeakReference<Context> = WeakReference(context)
|
||||||
@ -112,7 +113,7 @@ class FolderSelectorBinder(context: Context
|
|||||||
data class FolderHeader(
|
data class FolderHeader(
|
||||||
val folders: List<MusicFolder>,
|
val folders: List<MusicFolder>,
|
||||||
val selected: String?
|
val selected: String?
|
||||||
): Identifiable {
|
) : Identifiable {
|
||||||
override val id: String
|
override val id: String
|
||||||
get() = "FOLDERSELECTOR"
|
get() = "FOLDERSELECTOR"
|
||||||
|
|
||||||
@ -123,5 +124,4 @@ class FolderSelectorBinder(context: Context
|
|||||||
return longId.compareTo(other.longId)
|
return longId.compareTo(other.longId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
package org.moire.ultrasonic.adapters
|
|
||||||
|
|
||||||
import com.drakeet.multitype.MultiTypeAdapter
|
|
||||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
|
||||||
import org.moire.ultrasonic.domain.Identifiable
|
|
||||||
|
|
||||||
class SectionedAdapter<T : Identifiable> : MultiTypeAdapter(), FastScrollRecyclerView.SectionedAdapter {
|
|
||||||
override fun getSectionName(position: Int): String {
|
|
||||||
// var listPosition = if (selectFolderHeader != null) position - 1 else position
|
|
||||||
//
|
|
||||||
// // Show the first artist's initial in the popup when the list is
|
|
||||||
// // scrolled up to the "Select Folder" row
|
|
||||||
// if (listPosition < 0) listPosition = 0
|
|
||||||
//
|
|
||||||
// return getSectionFromName(currentList[listPosition].name ?: " ")
|
|
||||||
return "X"
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,7 +13,6 @@ import androidx.lifecycle.MutableLiveData
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
import org.koin.core.component.get
|
import org.koin.core.component.get
|
||||||
import org.koin.core.component.inject
|
|
||||||
import org.moire.ultrasonic.R
|
import org.moire.ultrasonic.R
|
||||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory
|
import org.moire.ultrasonic.domain.MusicDirectory
|
||||||
@ -21,7 +20,6 @@ import org.moire.ultrasonic.featureflags.Feature
|
|||||||
import org.moire.ultrasonic.featureflags.FeatureStorage
|
import org.moire.ultrasonic.featureflags.FeatureStorage
|
||||||
import org.moire.ultrasonic.service.DownloadFile
|
import org.moire.ultrasonic.service.DownloadFile
|
||||||
import org.moire.ultrasonic.service.DownloadStatus
|
import org.moire.ultrasonic.service.DownloadStatus
|
||||||
import org.moire.ultrasonic.service.MediaPlayerController
|
|
||||||
import org.moire.ultrasonic.service.MusicServiceFactory
|
import org.moire.ultrasonic.service.MusicServiceFactory
|
||||||
import org.moire.ultrasonic.service.RxBus
|
import org.moire.ultrasonic.service.RxBus
|
||||||
import org.moire.ultrasonic.util.Settings
|
import org.moire.ultrasonic.util.Settings
|
||||||
@ -130,10 +128,10 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
|||||||
|
|
||||||
// Minimize or maximize the Text view (if song title is very long)
|
// Minimize or maximize the Text view (if song title is very long)
|
||||||
itemView.setOnLongClickListener {
|
itemView.setOnLongClickListener {
|
||||||
if (!song.isDirectory) {
|
if (!song.isDirectory) {
|
||||||
maximizeOrMinimize()
|
maximizeOrMinimize()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,7 +150,6 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun setupStarButtons(song: MusicDirectory.Entry) {
|
private fun setupStarButtons(song: MusicDirectory.Entry) {
|
||||||
if (useFiveStarRating) {
|
if (useFiveStarRating) {
|
||||||
// Hide single star
|
// Hide single star
|
||||||
@ -191,7 +188,6 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Suppress("MagicNumber")
|
@Suppress("MagicNumber")
|
||||||
private fun setFiveStars(rating: Int) {
|
private fun setFiveStars(rating: Int) {
|
||||||
fiveStar1.setImageDrawable(
|
fiveStar1.setImageDrawable(
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
package org.moire.ultrasonic.adapters.legacy
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.ArrayAdapter
|
|
||||||
import androidx.lifecycle.LifecycleOwner
|
|
||||||
import org.moire.ultrasonic.R
|
|
||||||
import org.moire.ultrasonic.adapters.ImageHelper
|
|
||||||
import org.moire.ultrasonic.adapters.TrackViewHolder
|
|
||||||
import org.moire.ultrasonic.service.DownloadFile
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Legacy bridge to provide Views to a ListView using RecyclerView.ViewHolders
|
|
||||||
*/
|
|
||||||
class SongListAdapter(
|
|
||||||
ctx: Context,
|
|
||||||
entries: List<DownloadFile?>?,
|
|
||||||
val lifecycleOwner: LifecycleOwner
|
|
||||||
) :
|
|
||||||
ArrayAdapter<DownloadFile?>(ctx, android.R.layout.simple_list_item_1, entries!!) {
|
|
||||||
|
|
||||||
val layout = R.layout.song_list_item
|
|
||||||
private val imageHelper: ImageHelper = ImageHelper(context)
|
|
||||||
|
|
||||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
|
||||||
val downloadFile = getItem(position)!!
|
|
||||||
var view = convertView
|
|
||||||
val holder: TrackViewHolder
|
|
||||||
|
|
||||||
if (view == null) {
|
|
||||||
val inflater = LayoutInflater.from(context)
|
|
||||||
view = inflater.inflate(layout, parent, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (view?.tag is TrackViewHolder) {
|
|
||||||
holder = view.tag as TrackViewHolder
|
|
||||||
} else {
|
|
||||||
holder = TrackViewHolder(view!!)
|
|
||||||
view.tag = holder
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.imageHelper = imageHelper
|
|
||||||
|
|
||||||
holder.setSong(
|
|
||||||
file = downloadFile,
|
|
||||||
checkable = false,
|
|
||||||
draggable = true
|
|
||||||
)
|
|
||||||
|
|
||||||
// Observe download status
|
|
||||||
downloadFile.status.observe(
|
|
||||||
lifecycleOwner,
|
|
||||||
{
|
|
||||||
holder.updateStatus(it)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
downloadFile.progress.observe(
|
|
||||||
lifecycleOwner,
|
|
||||||
{
|
|
||||||
holder.updateProgress(it)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return view
|
|
||||||
}
|
|
||||||
}
|
|
@ -73,7 +73,6 @@ class AlbumListFragment : EntryListFragment<MusicDirectory.Entry>() {
|
|||||||
addOnScrollListener(scrollListener)
|
addOnScrollListener(scrollListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
viewAdapter.register(
|
viewAdapter.register(
|
||||||
AlbumRowBinder(
|
AlbumRowBinder(
|
||||||
{ entry -> onItemClick(entry) },
|
{ entry -> onItemClick(entry) },
|
||||||
@ -82,8 +81,6 @@ class AlbumListFragment : EntryListFragment<MusicDirectory.Entry>() {
|
|||||||
context = requireContext()
|
context = requireContext()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemClick(item: MusicDirectory.Entry) {
|
override fun onItemClick(item: MusicDirectory.Entry) {
|
||||||
@ -94,5 +91,4 @@ class AlbumListFragment : EntryListFragment<MusicDirectory.Entry>() {
|
|||||||
bundle.putString(Constants.INTENT_EXTRA_NAME_PARENT_ID, item.parent)
|
bundle.putString(Constants.INTENT_EXTRA_NAME_PARENT_ID, item.parent)
|
||||||
findNavController().navigate(itemClickTarget, bundle)
|
findNavController().navigate(itemClickTarget, bundle)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import org.moire.ultrasonic.domain.Artist
|
|||||||
import org.moire.ultrasonic.domain.ArtistOrIndex
|
import org.moire.ultrasonic.domain.ArtistOrIndex
|
||||||
import org.moire.ultrasonic.model.ArtistListModel
|
import org.moire.ultrasonic.model.ArtistListModel
|
||||||
import org.moire.ultrasonic.util.Constants
|
import org.moire.ultrasonic.util.Constants
|
||||||
import org.moire.ultrasonic.util.Settings
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays the list of Artists from the media library
|
* Displays the list of Artists from the media library
|
||||||
@ -44,7 +43,6 @@ class ArtistListFragment : EntryListFragment<ArtistOrIndex>() {
|
|||||||
*/
|
*/
|
||||||
override val itemClickTarget = R.id.selectArtistToSelectAlbum
|
override val itemClickTarget = R.id.selectArtistToSelectAlbum
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The central function to pass a query to the model and return a LiveData object
|
* The central function to pass a query to the model and return a LiveData object
|
||||||
*/
|
*/
|
||||||
@ -78,6 +76,5 @@ class ArtistListFragment : EntryListFragment<ArtistOrIndex>() {
|
|||||||
findNavController().navigate(itemClickTarget, bundle)
|
findNavController().navigate(itemClickTarget, bundle)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Constants.ALPHABETICAL_BY_NAME
|
// Constants.ALPHABETICAL_BY_NAME
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,6 @@ class BookmarksFragment : TrackCollectionFragment() {
|
|||||||
|
|
||||||
// Why?
|
// Why?
|
||||||
selectButton?.visibility = View.GONE
|
selectButton?.visibility = View.GONE
|
||||||
playNextButton?.visibility = View.GONE
|
|
||||||
playLastButton?.visibility = View.GONE
|
|
||||||
moreButton?.visibility = View.GONE
|
moreButton?.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,26 +39,14 @@ class BookmarksFragment : TrackCollectionFragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun enableButtons(selection: List<MusicDirectory.Entry>) {
|
override fun enableButtons(selection: List<MusicDirectory.Entry>) {
|
||||||
val enabled = selection.isNotEmpty()
|
super.enableButtons(selection)
|
||||||
var unpinEnabled = false
|
|
||||||
var deleteEnabled = false
|
|
||||||
var pinnedCount = 0
|
|
||||||
|
|
||||||
for (song in selection) {
|
|
||||||
val downloadFile = mediaPlayerController.getDownloadFileForSong(song)
|
|
||||||
if (downloadFile.isWorkDone) {
|
|
||||||
deleteEnabled = true
|
|
||||||
}
|
|
||||||
if (downloadFile.isSaved) {
|
|
||||||
pinnedCount++
|
|
||||||
unpinEnabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
playNowButton?.isVisible = (enabled && deleteEnabled)
|
|
||||||
pinButton?.isVisible = (enabled && !isOffline() && selection.size > pinnedCount)
|
|
||||||
unpinButton!!.isVisible = (enabled && unpinEnabled)
|
|
||||||
downloadButton!!.isVisible = (enabled && !deleteEnabled && !isOffline())
|
|
||||||
deleteButton!!.isVisible = (enabled && deleteEnabled)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ abstract class EntryListFragment<T : GenericEntry> : MultiListFragment<T>() {
|
|||||||
// FIXME
|
// FIXME
|
||||||
fun showFolderHeader(): Boolean {
|
fun showFolderHeader(): Boolean {
|
||||||
return listModel.showSelectFolderHeader(arguments) &&
|
return listModel.showSelectFolderHeader(arguments) &&
|
||||||
!listModel.isOffline() && !Settings.shouldUseId3Tags
|
!listModel.isOffline() && !Settings.shouldUseId3Tags
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
|
@ -24,7 +24,6 @@ import org.moire.ultrasonic.subsonic.DownloadHandler
|
|||||||
import org.moire.ultrasonic.subsonic.ImageLoaderProvider
|
import org.moire.ultrasonic.subsonic.ImageLoaderProvider
|
||||||
import org.moire.ultrasonic.util.Constants
|
import org.moire.ultrasonic.util.Constants
|
||||||
import org.moire.ultrasonic.util.Util
|
import org.moire.ultrasonic.util.Util
|
||||||
import org.moire.ultrasonic.view.SelectMusicFolderView
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract Model, which can be extended to display a list of items of type T from the API
|
* An abstract Model, which can be extended to display a list of items of type T from the API
|
||||||
@ -38,7 +37,6 @@ abstract class MultiListFragment<T : Identifiable> : Fragment() {
|
|||||||
protected var refreshListView: SwipeRefreshLayout? = null
|
protected var refreshListView: SwipeRefreshLayout? = null
|
||||||
internal var listView: RecyclerView? = null
|
internal var listView: RecyclerView? = null
|
||||||
internal lateinit var viewManager: LinearLayoutManager
|
internal lateinit var viewManager: LinearLayoutManager
|
||||||
internal var selectFolderHeader: SelectMusicFolderView? = null
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Adapter for the RecyclerView
|
* The Adapter for the RecyclerView
|
||||||
@ -162,10 +160,9 @@ abstract class MultiListFragment<T : Identifiable> : Fragment() {
|
|||||||
try {
|
try {
|
||||||
bundle = arguments?.clone() as Bundle
|
bundle = arguments?.clone() as Bundle
|
||||||
} catch (ignored: Exception) {
|
} catch (ignored: Exception) {
|
||||||
bundle = Bundle()
|
bundle = Bundle()
|
||||||
}
|
}
|
||||||
|
|
||||||
return bundle
|
return bundle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import androidx.lifecycle.viewModelScope
|
|||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import java.util.Collections
|
||||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
@ -48,7 +49,6 @@ import org.moire.ultrasonic.util.EntryByDiscAndTrackComparator
|
|||||||
import org.moire.ultrasonic.util.Settings
|
import org.moire.ultrasonic.util.Settings
|
||||||
import org.moire.ultrasonic.util.Util
|
import org.moire.ultrasonic.util.Util
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.Collections
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays a group of tracks, eg. the songs of an album, of a playlist etc.
|
* Displays a group of tracks, eg. the songs of an album, of a playlist etc.
|
||||||
@ -371,7 +371,7 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Entry>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val isArtist = arguments?.getBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, false)?: false
|
val isArtist = arguments?.getBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, false) ?: false
|
||||||
|
|
||||||
// FIXME WHICH id if no arguments?
|
// FIXME WHICH id if no arguments?
|
||||||
val id = arguments?.getString(Constants.INTENT_EXTRA_NAME_ID)
|
val id = arguments?.getString(Constants.INTENT_EXTRA_NAME_ID)
|
||||||
@ -570,7 +570,7 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Entry>() {
|
|||||||
moreButton!!.visibility = View.GONE
|
moreButton!!.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
moreButton!!.visibility = View.VISIBLE
|
moreButton!!.visibility = View.VISIBLE
|
||||||
if (arguments?.getInt(Constants.INTENT_EXTRA_NAME_RANDOM, 0) ?:0 > 0) {
|
if (arguments?.getInt(Constants.INTENT_EXTRA_NAME_RANDOM, 0) ?: 0 > 0) {
|
||||||
moreButton!!.setOnClickListener {
|
moreButton!!.setOnClickListener {
|
||||||
val offset = requireArguments().getInt(
|
val offset = requireArguments().getInt(
|
||||||
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0
|
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0
|
||||||
@ -594,7 +594,7 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Entry>() {
|
|||||||
|
|
||||||
val isAlbumList = arguments?.containsKey(
|
val isAlbumList = arguments?.containsKey(
|
||||||
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE
|
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE
|
||||||
)?:false
|
) ?: false
|
||||||
|
|
||||||
playAllButtonVisible = !(isAlbumList || entryList.isEmpty()) && !allVideos
|
playAllButtonVisible = !(isAlbumList || entryList.isEmpty()) && !allVideos
|
||||||
shareButtonVisible = !isOffline() && songCount > 0
|
shareButtonVisible = !isOffline() && songCount > 0
|
||||||
@ -615,11 +615,11 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Entry>() {
|
|||||||
viewAdapter.submitList(entryList)
|
viewAdapter.submitList(entryList)
|
||||||
}
|
}
|
||||||
|
|
||||||
val playAll = arguments?.getBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, false)?:false
|
val playAll = arguments?.getBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, false) ?: false
|
||||||
|
|
||||||
if (playAll && songCount > 0) {
|
if (playAll && songCount > 0) {
|
||||||
playAll(
|
playAll(
|
||||||
arguments?.getBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE, false)?:false,
|
arguments?.getBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE, false) ?: false,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,6 @@ import org.moire.ultrasonic.util.Settings
|
|||||||
|
|
||||||
class AlbumListModel(application: Application) : GenericListModel(application) {
|
class AlbumListModel(application: Application) : GenericListModel(application) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val list: MutableLiveData<List<MusicDirectory.Entry>> = MutableLiveData(listOf())
|
val list: MutableLiveData<List<MusicDirectory.Entry>> = MutableLiveData(listOf())
|
||||||
var lastType: String? = null
|
var lastType: String? = null
|
||||||
private var loadedUntil: Int = 0
|
private var loadedUntil: Int = 0
|
||||||
@ -38,28 +36,28 @@ class AlbumListModel(application: Application) : GenericListModel(application) {
|
|||||||
|
|
||||||
fun getAlbumsOfArtist(musicService: MusicService, refresh: Boolean, id: String, name: String?) {
|
fun getAlbumsOfArtist(musicService: MusicService, refresh: Boolean, id: String, name: String?) {
|
||||||
|
|
||||||
var root = MusicDirectory()
|
var root = MusicDirectory()
|
||||||
val musicDirectory = musicService.getArtist(id, name, refresh)
|
val musicDirectory = musicService.getArtist(id, name, refresh)
|
||||||
|
|
||||||
if (Settings.shouldShowAllSongsByArtist &&
|
if (Settings.shouldShowAllSongsByArtist &&
|
||||||
musicDirectory.findChild(allSongsId) == null &&
|
musicDirectory.findChild(allSongsId) == null &&
|
||||||
hasOnlyFolders(musicDirectory)
|
hasOnlyFolders(musicDirectory)
|
||||||
) {
|
) {
|
||||||
val allSongs = MusicDirectory.Entry(allSongsId)
|
val allSongs = MusicDirectory.Entry(allSongsId)
|
||||||
|
|
||||||
allSongs.isDirectory = true
|
allSongs.isDirectory = true
|
||||||
allSongs.artist = name
|
allSongs.artist = name
|
||||||
allSongs.parent = id
|
allSongs.parent = id
|
||||||
allSongs.title = String.format(
|
allSongs.title = String.format(
|
||||||
context.resources.getString(R.string.select_album_all_songs), name
|
context.resources.getString(R.string.select_album_all_songs), name
|
||||||
)
|
)
|
||||||
|
|
||||||
root.addFirst(allSongs)
|
root.addFirst(allSongs)
|
||||||
root.addAll(musicDirectory.getChildren())
|
root.addAll(musicDirectory.getChildren())
|
||||||
} else {
|
} else {
|
||||||
root = musicDirectory
|
root = musicDirectory
|
||||||
}
|
}
|
||||||
list.postValue(root.getChildren())
|
list.postValue(root.getChildren())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(
|
override fun load(
|
||||||
@ -138,5 +136,4 @@ class AlbumListModel(application: Application) : GenericListModel(application) {
|
|||||||
albumListType != "highest" && albumListType != "recent" &&
|
albumListType != "highest" && albumListType != "recent" &&
|
||||||
albumListType != "frequent"
|
albumListType != "frequent"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,6 @@ import android.os.Bundle
|
|||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -18,7 +16,6 @@ import org.koin.core.component.inject
|
|||||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||||
import org.moire.ultrasonic.data.ServerSetting
|
import org.moire.ultrasonic.data.ServerSetting
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory
|
import org.moire.ultrasonic.domain.MusicDirectory
|
||||||
import org.moire.ultrasonic.domain.MusicFolder
|
|
||||||
import org.moire.ultrasonic.service.MusicService
|
import org.moire.ultrasonic.service.MusicService
|
||||||
import org.moire.ultrasonic.service.MusicServiceFactory
|
import org.moire.ultrasonic.service.MusicServiceFactory
|
||||||
import org.moire.ultrasonic.util.CommunicationError
|
import org.moire.ultrasonic.util.CommunicationError
|
||||||
@ -109,11 +106,10 @@ open class GenericListModel(application: Application) :
|
|||||||
) {
|
) {
|
||||||
// Update the list of available folders if enabled
|
// Update the list of available folders if enabled
|
||||||
if (showSelectFolderHeader(args) && !isOffline && !useId3Tags) {
|
if (showSelectFolderHeader(args) && !isOffline && !useId3Tags) {
|
||||||
//FIXME
|
// FIXME
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some shared helper functions
|
* Some shared helper functions
|
||||||
*/
|
*/
|
||||||
@ -121,8 +117,7 @@ open class GenericListModel(application: Application) :
|
|||||||
// Returns true if the directory contains only folders
|
// Returns true if the directory contains only folders
|
||||||
internal fun hasOnlyFolders(musicDirectory: MusicDirectory) =
|
internal fun hasOnlyFolders(musicDirectory: MusicDirectory) =
|
||||||
musicDirectory.getChildren(includeDirs = true, includeFiles = false).size ==
|
musicDirectory.getChildren(includeDirs = true, includeFiles = false).size ==
|
||||||
musicDirectory.getChildren(includeDirs = true, includeFiles = true).size
|
musicDirectory.getChildren(includeDirs = true, includeFiles = true).size
|
||||||
|
|
||||||
internal val allSongsId = "-1"
|
internal val allSongsId = "-1"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,26 +2,15 @@ package org.moire.ultrasonic.model
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.moire.ultrasonic.domain.Artist
|
|
||||||
import org.moire.ultrasonic.domain.Identifiable
|
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory
|
|
||||||
import org.moire.ultrasonic.domain.SearchCriteria
|
import org.moire.ultrasonic.domain.SearchCriteria
|
||||||
import org.moire.ultrasonic.domain.SearchResult
|
import org.moire.ultrasonic.domain.SearchResult
|
||||||
import org.moire.ultrasonic.fragment.SearchFragment
|
import org.moire.ultrasonic.fragment.SearchFragment
|
||||||
import org.moire.ultrasonic.service.MusicService
|
import org.moire.ultrasonic.service.MusicService
|
||||||
import org.moire.ultrasonic.service.MusicServiceFactory
|
import org.moire.ultrasonic.service.MusicServiceFactory
|
||||||
import org.moire.ultrasonic.util.BackgroundTask
|
|
||||||
import org.moire.ultrasonic.util.Constants
|
|
||||||
import org.moire.ultrasonic.util.FragmentBackgroundTask
|
|
||||||
import org.moire.ultrasonic.util.MergeAdapter
|
|
||||||
import org.moire.ultrasonic.util.Settings
|
import org.moire.ultrasonic.util.Settings
|
||||||
import org.moire.ultrasonic.view.ArtistAdapter
|
|
||||||
import org.moire.ultrasonic.view.EntryAdapter
|
|
||||||
import java.util.ArrayList
|
|
||||||
|
|
||||||
class SearchListModel(application: Application) : GenericListModel(application) {
|
class SearchListModel(application: Application) : GenericListModel(application) {
|
||||||
|
|
||||||
@ -35,11 +24,8 @@ class SearchListModel(application: Application) : GenericListModel(application)
|
|||||||
args: Bundle
|
args: Bundle
|
||||||
) {
|
) {
|
||||||
super.load(isOffline, useId3Tags, musicService, refresh, args)
|
super.load(isOffline, useId3Tags, musicService, refresh, args)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
suspend fun search(query: String) {
|
suspend fun search(query: String) {
|
||||||
val maxArtists = Settings.maxArtists
|
val maxArtists = Settings.maxArtists
|
||||||
val maxAlbums = Settings.maxAlbums
|
val maxAlbums = Settings.maxAlbums
|
||||||
@ -69,5 +55,4 @@ class SearchListModel(application: Application) : GenericListModel(application)
|
|||||||
// list.add(result.songs)
|
// list.add(result.songs)
|
||||||
// return list
|
// return list
|
||||||
// }
|
// }
|
||||||
|
|
||||||
}
|
}
|
@ -8,14 +8,12 @@
|
|||||||
package org.moire.ultrasonic.model
|
package org.moire.ultrasonic.model
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import java.util.LinkedList
|
import java.util.LinkedList
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.moire.ultrasonic.R
|
import org.moire.ultrasonic.R
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory
|
import org.moire.ultrasonic.domain.MusicDirectory
|
||||||
import org.moire.ultrasonic.service.MusicService
|
|
||||||
import org.moire.ultrasonic.service.MusicServiceFactory
|
import org.moire.ultrasonic.service.MusicServiceFactory
|
||||||
import org.moire.ultrasonic.util.Settings
|
import org.moire.ultrasonic.util.Settings
|
||||||
import org.moire.ultrasonic.util.Util
|
import org.moire.ultrasonic.util.Util
|
||||||
@ -82,7 +80,6 @@ class TrackCollectionModel(application: Application) : GenericListModel(applicat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Given a Music directory "songs" it recursively adds all children to "songs"
|
// Given a Music directory "songs" it recursively adds all children to "songs"
|
||||||
private fun getSongsRecursively(
|
private fun getSongsRecursively(
|
||||||
parent: MusicDirectory,
|
parent: MusicDirectory,
|
||||||
@ -257,5 +254,4 @@ class TrackCollectionModel(application: Application) : GenericListModel(applicat
|
|||||||
private fun updateList(root: MusicDirectory) {
|
private fun updateList(root: MusicDirectory) {
|
||||||
currentList.postValue(root.getChildren())
|
currentList.postValue(root.getChildren())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,6 @@ class RxBus {
|
|||||||
val skipToQueueItemCommandObservable: Observable<Long> =
|
val skipToQueueItemCommandObservable: Observable<Long> =
|
||||||
skipToQueueItemCommandPublisher.observeOn(AndroidSchedulers.mainThread())
|
skipToQueueItemCommandPublisher.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
|
||||||
|
|
||||||
fun releaseMediaSessionToken() {
|
fun releaseMediaSessionToken() {
|
||||||
mediaSessionTokenPublisher = PublishSubject.create()
|
mediaSessionTokenPublisher = PublishSubject.create()
|
||||||
}
|
}
|
||||||
|
@ -1,87 +0,0 @@
|
|||||||
package org.moire.ultrasonic.view
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.LinearLayout
|
|
||||||
import android.widget.PopupMenu
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import org.moire.ultrasonic.R
|
|
||||||
import org.moire.ultrasonic.domain.MusicFolder
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This little view shows the currently selected Folder (or catalog) on the music server.
|
|
||||||
* When clicked it will drop down a list of all available Folders and allow you to
|
|
||||||
* select one. The intended usage is to supply a filter to lists of artists, albums, etc
|
|
||||||
*/
|
|
||||||
class SelectMusicFolderView(
|
|
||||||
private val context: Context,
|
|
||||||
view: View,
|
|
||||||
private val onUpdate: (String?) -> Unit
|
|
||||||
) : RecyclerView.ViewHolder(view) {
|
|
||||||
private var musicFolders: List<MusicFolder> = mutableListOf()
|
|
||||||
private var selectedFolderId: String? = null
|
|
||||||
private val folderName: TextView = itemView.findViewById(R.id.select_folder_name)
|
|
||||||
private val layout: LinearLayout = itemView.findViewById(R.id.select_folder_header)
|
|
||||||
|
|
||||||
init {
|
|
||||||
folderName.text = context.getString(R.string.select_artist_all_folders)
|
|
||||||
layout.setOnClickListener { onFolderClick() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setData(selectedId: String?, folders: List<MusicFolder>) {
|
|
||||||
selectedFolderId = selectedId
|
|
||||||
musicFolders = folders
|
|
||||||
if (selectedFolderId != null) {
|
|
||||||
for ((id, name) in musicFolders) {
|
|
||||||
if (id == selectedFolderId) {
|
|
||||||
folderName.text = name
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
folderName.text = context.getString(R.string.select_artist_all_folders)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onFolderClick() {
|
|
||||||
val popup = PopupMenu(context, layout)
|
|
||||||
|
|
||||||
var menuItem = popup.menu.add(
|
|
||||||
MENU_GROUP_MUSIC_FOLDER, -1, 0, R.string.select_artist_all_folders
|
|
||||||
)
|
|
||||||
if (selectedFolderId == null || selectedFolderId!!.isEmpty()) {
|
|
||||||
menuItem.isChecked = true
|
|
||||||
}
|
|
||||||
musicFolders.forEachIndexed { i, musicFolder ->
|
|
||||||
val (id, name) = musicFolder
|
|
||||||
menuItem = popup.menu.add(MENU_GROUP_MUSIC_FOLDER, i, i + 1, name)
|
|
||||||
if (id == selectedFolderId) {
|
|
||||||
menuItem.isChecked = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
popup.menu.setGroupCheckable(MENU_GROUP_MUSIC_FOLDER, true, true)
|
|
||||||
|
|
||||||
popup.setOnMenuItemClickListener { item -> onFolderMenuItemSelected(item) }
|
|
||||||
popup.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onFolderMenuItemSelected(menuItem: MenuItem): Boolean {
|
|
||||||
val selectedFolder = if (menuItem.itemId == -1) null else musicFolders[menuItem.itemId]
|
|
||||||
val musicFolderName = selectedFolder?.name
|
|
||||||
?: context.getString(R.string.select_artist_all_folders)
|
|
||||||
selectedFolderId = selectedFolder?.id
|
|
||||||
|
|
||||||
menuItem.isChecked = true
|
|
||||||
folderName.text = musicFolderName
|
|
||||||
onUpdate(selectedFolderId)
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val MENU_GROUP_MUSIC_FOLDER = 10
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,393 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of Subsonic.
|
|
||||||
|
|
||||||
Subsonic is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Subsonic is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Copyright 2020 (C) Jozsef Varga
|
|
||||||
*/
|
|
||||||
package org.moire.ultrasonic.view
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.drawable.AnimationDrawable
|
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import android.text.TextUtils
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.widget.Checkable
|
|
||||||
import org.koin.core.component.KoinComponent
|
|
||||||
import org.koin.core.component.get
|
|
||||||
import org.koin.core.component.inject
|
|
||||||
import org.moire.ultrasonic.R
|
|
||||||
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
|
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory
|
|
||||||
import org.moire.ultrasonic.featureflags.Feature
|
|
||||||
import org.moire.ultrasonic.featureflags.FeatureStorage
|
|
||||||
import org.moire.ultrasonic.service.DownloadFile
|
|
||||||
import org.moire.ultrasonic.service.MediaPlayerController
|
|
||||||
import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
|
|
||||||
import org.moire.ultrasonic.util.Settings
|
|
||||||
import org.moire.ultrasonic.util.Util
|
|
||||||
import org.moire.ultrasonic.view.EntryAdapter.SongViewHolder
|
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to display songs and videos in a `ListView`.
|
|
||||||
*/
|
|
||||||
class SongView(context: Context) : UpdateView(context), Checkable, KoinComponent {
|
|
||||||
|
|
||||||
var entry: MusicDirectory.Entry? = null
|
|
||||||
private set
|
|
||||||
|
|
||||||
private var isMaximized = false
|
|
||||||
private var leftImage: Drawable? = null
|
|
||||||
private var previousLeftImageType: ImageType? = null
|
|
||||||
private var previousRightImageType: ImageType? = null
|
|
||||||
private var leftImageType: ImageType? = null
|
|
||||||
private var downloadFile: DownloadFile? = null
|
|
||||||
private var playing = false
|
|
||||||
private var viewHolder: SongViewHolder? = null
|
|
||||||
private val features: FeatureStorage = get()
|
|
||||||
private val useFiveStarRating: Boolean = features.isFeatureEnabled(Feature.FIVE_STAR_RATING)
|
|
||||||
private val mediaPlayerController: MediaPlayerController by inject()
|
|
||||||
|
|
||||||
fun setLayout(song: MusicDirectory.Entry) {
|
|
||||||
|
|
||||||
inflater?.inflate(
|
|
||||||
if (song.isVideo) R.layout.video_list_item
|
|
||||||
else R.layout.song_list_item,
|
|
||||||
this,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
|
|
||||||
viewHolder = SongViewHolder()
|
|
||||||
viewHolder!!.check = findViewById(R.id.song_check)
|
|
||||||
viewHolder!!.rating = findViewById(R.id.song_rating)
|
|
||||||
viewHolder!!.fiveStar1 = findViewById(R.id.song_five_star_1)
|
|
||||||
viewHolder!!.fiveStar2 = findViewById(R.id.song_five_star_2)
|
|
||||||
viewHolder!!.fiveStar3 = findViewById(R.id.song_five_star_3)
|
|
||||||
viewHolder!!.fiveStar4 = findViewById(R.id.song_five_star_4)
|
|
||||||
viewHolder!!.fiveStar5 = findViewById(R.id.song_five_star_5)
|
|
||||||
viewHolder!!.star = findViewById(R.id.song_star)
|
|
||||||
viewHolder!!.drag = findViewById(R.id.song_drag)
|
|
||||||
viewHolder!!.track = findViewById(R.id.song_track)
|
|
||||||
viewHolder!!.title = findViewById(R.id.song_title)
|
|
||||||
viewHolder!!.artist = findViewById(R.id.song_artist)
|
|
||||||
viewHolder!!.duration = findViewById(R.id.song_duration)
|
|
||||||
viewHolder!!.status = findViewById(R.id.song_status)
|
|
||||||
tag = viewHolder
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setViewHolder(viewHolder: SongViewHolder?) {
|
|
||||||
this.viewHolder = viewHolder
|
|
||||||
tag = this.viewHolder
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setSong(song: MusicDirectory.Entry, checkable: Boolean, draggable: Boolean) {
|
|
||||||
updateBackground()
|
|
||||||
|
|
||||||
entry = song
|
|
||||||
downloadFile = mediaPlayerController.getDownloadFileForSong(song)
|
|
||||||
|
|
||||||
val artist = StringBuilder(60)
|
|
||||||
var bitRate: String? = null
|
|
||||||
|
|
||||||
if (song.bitRate != null)
|
|
||||||
bitRate = String.format(
|
|
||||||
this.context.getString(R.string.song_details_kbps), song.bitRate
|
|
||||||
)
|
|
||||||
|
|
||||||
val fileFormat: String?
|
|
||||||
val suffix = song.suffix
|
|
||||||
val transcodedSuffix = song.transcodedSuffix
|
|
||||||
|
|
||||||
fileFormat = if (
|
|
||||||
TextUtils.isEmpty(transcodedSuffix) || transcodedSuffix == suffix || song.isVideo
|
|
||||||
) suffix else String.format("%s > %s", suffix, transcodedSuffix)
|
|
||||||
|
|
||||||
val artistName = song.artist
|
|
||||||
|
|
||||||
if (artistName != null) {
|
|
||||||
if (Settings.shouldDisplayBitrateWithArtist) {
|
|
||||||
artist.append(artistName).append(" (").append(
|
|
||||||
String.format(
|
|
||||||
this.context.getString(R.string.song_details_all),
|
|
||||||
if (bitRate == null) "" else String.format("%s ", bitRate), fileFormat
|
|
||||||
)
|
|
||||||
).append(')')
|
|
||||||
} else {
|
|
||||||
artist.append(artistName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val trackNumber = song.track ?: 0
|
|
||||||
|
|
||||||
if (Settings.shouldShowTrackNumber && trackNumber != 0) {
|
|
||||||
viewHolder?.track?.text = String.format("%02d.", trackNumber)
|
|
||||||
} else {
|
|
||||||
viewHolder?.track?.visibility = GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
val title = StringBuilder(60)
|
|
||||||
title.append(song.title)
|
|
||||||
|
|
||||||
if (song.isVideo && Settings.shouldDisplayBitrateWithArtist) {
|
|
||||||
title.append(" (").append(
|
|
||||||
String.format(
|
|
||||||
this.context.getString(R.string.song_details_all),
|
|
||||||
if (bitRate == null) "" else String.format("%s ", bitRate), fileFormat
|
|
||||||
)
|
|
||||||
).append(')')
|
|
||||||
}
|
|
||||||
|
|
||||||
viewHolder?.title?.text = title
|
|
||||||
viewHolder?.artist?.text = artist
|
|
||||||
|
|
||||||
val duration = song.duration
|
|
||||||
if (duration != null) {
|
|
||||||
viewHolder?.duration?.text = Util.formatTotalDuration(duration.toLong())
|
|
||||||
}
|
|
||||||
|
|
||||||
viewHolder?.check?.visibility = if (checkable && !song.isVideo) VISIBLE else GONE
|
|
||||||
viewHolder?.drag?.visibility = if (draggable) VISIBLE else GONE
|
|
||||||
|
|
||||||
if (isOffline()) {
|
|
||||||
viewHolder?.star?.visibility = GONE
|
|
||||||
viewHolder?.rating?.visibility = GONE
|
|
||||||
} else {
|
|
||||||
if (useFiveStarRating) {
|
|
||||||
viewHolder?.star?.visibility = GONE
|
|
||||||
val rating = if (song.userRating == null) 0 else song.userRating!!
|
|
||||||
viewHolder?.fiveStar1?.setImageDrawable(
|
|
||||||
if (rating > 0) starDrawable else starHollowDrawable
|
|
||||||
)
|
|
||||||
viewHolder?.fiveStar2?.setImageDrawable(
|
|
||||||
if (rating > 1) starDrawable else starHollowDrawable
|
|
||||||
)
|
|
||||||
viewHolder?.fiveStar3?.setImageDrawable(
|
|
||||||
if (rating > 2) starDrawable else starHollowDrawable
|
|
||||||
)
|
|
||||||
viewHolder?.fiveStar4?.setImageDrawable(
|
|
||||||
if (rating > 3) starDrawable else starHollowDrawable
|
|
||||||
)
|
|
||||||
viewHolder?.fiveStar5?.setImageDrawable(
|
|
||||||
if (rating > 4) starDrawable else starHollowDrawable
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
viewHolder?.rating?.visibility = GONE
|
|
||||||
viewHolder?.star?.setImageDrawable(
|
|
||||||
if (song.starred) starDrawable else starHollowDrawable
|
|
||||||
)
|
|
||||||
|
|
||||||
viewHolder?.star?.setOnClickListener {
|
|
||||||
val isStarred = song.starred
|
|
||||||
val id = song.id
|
|
||||||
|
|
||||||
if (!isStarred) {
|
|
||||||
viewHolder?.star?.setImageDrawable(starDrawable)
|
|
||||||
song.starred = true
|
|
||||||
} else {
|
|
||||||
viewHolder?.star?.setImageDrawable(starHollowDrawable)
|
|
||||||
song.starred = false
|
|
||||||
}
|
|
||||||
Thread {
|
|
||||||
val musicService = getMusicService()
|
|
||||||
try {
|
|
||||||
if (!isStarred) {
|
|
||||||
musicService.star(id, null, null)
|
|
||||||
} else {
|
|
||||||
musicService.unstar(id, null, null)
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Timber.e(e)
|
|
||||||
}
|
|
||||||
}.start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
update()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun updateBackground() {}
|
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
public override fun update() {
|
|
||||||
updateBackground()
|
|
||||||
|
|
||||||
val song = entry ?: return
|
|
||||||
|
|
||||||
downloadFile = mediaPlayerController.getDownloadFileForSong(song)
|
|
||||||
|
|
||||||
updateDownloadStatus(downloadFile!!)
|
|
||||||
|
|
||||||
if (entry?.starred != true) {
|
|
||||||
if (viewHolder?.star?.drawable !== starHollowDrawable) {
|
|
||||||
viewHolder?.star?.setImageDrawable(starHollowDrawable)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (viewHolder?.star?.drawable !== starDrawable) {
|
|
||||||
viewHolder?.star?.setImageDrawable(starDrawable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val rating = entry?.userRating ?: 0
|
|
||||||
viewHolder?.fiveStar1?.setImageDrawable(
|
|
||||||
if (rating > 0) starDrawable else starHollowDrawable
|
|
||||||
)
|
|
||||||
viewHolder?.fiveStar2?.setImageDrawable(
|
|
||||||
if (rating > 1) starDrawable else starHollowDrawable
|
|
||||||
)
|
|
||||||
viewHolder?.fiveStar3?.setImageDrawable(
|
|
||||||
if (rating > 2) starDrawable else starHollowDrawable
|
|
||||||
)
|
|
||||||
viewHolder?.fiveStar4?.setImageDrawable(
|
|
||||||
if (rating > 3) starDrawable else starHollowDrawable
|
|
||||||
)
|
|
||||||
viewHolder?.fiveStar5?.setImageDrawable(
|
|
||||||
if (rating > 4) starDrawable else starHollowDrawable
|
|
||||||
)
|
|
||||||
|
|
||||||
val playing = mediaPlayerController.currentPlaying === downloadFile
|
|
||||||
|
|
||||||
if (playing) {
|
|
||||||
if (!this.playing) {
|
|
||||||
this.playing = true
|
|
||||||
viewHolder?.title?.setCompoundDrawablesWithIntrinsicBounds(
|
|
||||||
playingImage, null, null, null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.playing) {
|
|
||||||
this.playing = false
|
|
||||||
viewHolder?.title?.setCompoundDrawablesWithIntrinsicBounds(
|
|
||||||
0, 0, 0, 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateDownloadStatus(downloadFile: DownloadFile) {
|
|
||||||
|
|
||||||
if (downloadFile.isWorkDone) {
|
|
||||||
val newLeftImageType =
|
|
||||||
if (downloadFile.isSaved) ImageType.Pin else ImageType.Downloaded
|
|
||||||
|
|
||||||
if (leftImageType != newLeftImageType) {
|
|
||||||
leftImage = if (downloadFile.isSaved) pinImage else downloadedImage
|
|
||||||
leftImageType = newLeftImageType
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
leftImageType = ImageType.None
|
|
||||||
leftImage = null
|
|
||||||
}
|
|
||||||
|
|
||||||
val rightImageType: ImageType
|
|
||||||
val rightImage: Drawable?
|
|
||||||
|
|
||||||
if (downloadFile.isDownloading && !downloadFile.isDownloadCancelled) {
|
|
||||||
viewHolder?.status?.text = Util.formatPercentage(downloadFile.progress.value!!)
|
|
||||||
|
|
||||||
rightImageType = ImageType.Downloading
|
|
||||||
rightImage = downloadingImage
|
|
||||||
} else {
|
|
||||||
rightImageType = ImageType.None
|
|
||||||
rightImage = null
|
|
||||||
|
|
||||||
val statusText = viewHolder?.status?.text
|
|
||||||
if (!statusText.isNullOrEmpty()) viewHolder?.status?.text = null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (previousLeftImageType != leftImageType || previousRightImageType != rightImageType) {
|
|
||||||
previousLeftImageType = leftImageType
|
|
||||||
previousRightImageType = rightImageType
|
|
||||||
|
|
||||||
if (viewHolder?.status != null) {
|
|
||||||
viewHolder?.status?.setCompoundDrawablesWithIntrinsicBounds(
|
|
||||||
leftImage, null, rightImage, null
|
|
||||||
)
|
|
||||||
|
|
||||||
if (rightImage === downloadingImage) {
|
|
||||||
val frameAnimation = rightImage as AnimationDrawable?
|
|
||||||
|
|
||||||
frameAnimation!!.setVisible(true, true)
|
|
||||||
frameAnimation.start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setChecked(b: Boolean) {
|
|
||||||
viewHolder?.check?.isChecked = b
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isChecked(): Boolean {
|
|
||||||
return viewHolder?.check?.isChecked ?: false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toggle() {
|
|
||||||
viewHolder?.check?.toggle()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun maximizeOrMinimize() {
|
|
||||||
isMaximized = !isMaximized
|
|
||||||
|
|
||||||
viewHolder?.title?.isSingleLine = !isMaximized
|
|
||||||
viewHolder?.artist?.isSingleLine = !isMaximized
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class ImageType {
|
|
||||||
None, Pin, Downloaded, Downloading
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private var starHollowDrawable: Drawable? = null
|
|
||||||
private var starDrawable: Drawable? = null
|
|
||||||
var pinImage: Drawable? = null
|
|
||||||
var downloadedImage: Drawable? = null
|
|
||||||
var downloadingImage: Drawable? = null
|
|
||||||
private var playingImage: Drawable? = null
|
|
||||||
private var theme: String? = null
|
|
||||||
private var inflater: LayoutInflater? = null
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
val theme = Settings.theme
|
|
||||||
val themesMatch = theme == Companion.theme
|
|
||||||
inflater = LayoutInflater.from(this.context)
|
|
||||||
|
|
||||||
if (!themesMatch) Companion.theme = theme
|
|
||||||
|
|
||||||
if (starHollowDrawable == null || !themesMatch) {
|
|
||||||
starHollowDrawable = Util.getDrawableFromAttribute(context, R.attr.star_hollow)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (starDrawable == null || !themesMatch) {
|
|
||||||
starDrawable = Util.getDrawableFromAttribute(context, R.attr.star_full)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pinImage == null || !themesMatch) {
|
|
||||||
pinImage = Util.getDrawableFromAttribute(context, R.attr.pin)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (downloadedImage == null || !themesMatch) {
|
|
||||||
downloadedImage = Util.getDrawableFromAttribute(context, R.attr.downloaded)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (downloadingImage == null || !themesMatch) {
|
|
||||||
downloadingImage = Util.getDrawableFromAttribute(context, R.attr.downloading)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playingImage == null || !themesMatch) {
|
|
||||||
playingImage = Util.getDrawableFromAttribute(context, R.attr.media_play_small)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,316 +0,0 @@
|
|||||||
// package org.moire.ultrasonic.view
|
|
||||||
//
|
|
||||||
// import android.content.Context
|
|
||||||
// import android.graphics.drawable.AnimationDrawable
|
|
||||||
// import android.graphics.drawable.Drawable
|
|
||||||
// import android.view.View
|
|
||||||
// import android.widget.Checkable
|
|
||||||
// import android.widget.CheckedTextView
|
|
||||||
// import android.widget.ImageView
|
|
||||||
// import android.widget.LinearLayout
|
|
||||||
// import android.widget.TextView
|
|
||||||
// import androidx.core.view.isVisible
|
|
||||||
// import androidx.recyclerview.widget.RecyclerView
|
|
||||||
// import org.koin.core.component.KoinComponent
|
|
||||||
// import org.koin.core.component.get
|
|
||||||
// import org.koin.core.component.inject
|
|
||||||
// import org.moire.ultrasonic.R
|
|
||||||
// import org.moire.ultrasonic.data.ActiveServerProvider
|
|
||||||
// import org.moire.ultrasonic.domain.MusicDirectory
|
|
||||||
// import org.moire.ultrasonic.featureflags.Feature
|
|
||||||
// import org.moire.ultrasonic.featureflags.FeatureStorage
|
|
||||||
// import org.moire.ultrasonic.fragment.DownloadRowAdapter
|
|
||||||
// import org.moire.ultrasonic.service.DownloadFile
|
|
||||||
// import org.moire.ultrasonic.service.MediaPlayerController
|
|
||||||
// import org.moire.ultrasonic.service.MusicServiceFactory
|
|
||||||
// import org.moire.ultrasonic.util.Settings
|
|
||||||
// import org.moire.ultrasonic.util.Util
|
|
||||||
// import timber.log.Timber
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Used to display songs and videos in a `ListView`.
|
|
||||||
// * TODO: Video List item
|
|
||||||
// */
|
|
||||||
// class SongViewHolder(view: View, context: Context) : RecyclerView.ViewHolder(view), Checkable, KoinComponent {
|
|
||||||
// var check: CheckedTextView = view.findViewById(R.id.song_check)
|
|
||||||
// var rating: LinearLayout = view.findViewById(R.id.song_rating)
|
|
||||||
// var fiveStar1: ImageView = view.findViewById(R.id.song_five_star_1)
|
|
||||||
// var fiveStar2: ImageView = view.findViewById(R.id.song_five_star_2)
|
|
||||||
// var fiveStar3: ImageView = view.findViewById(R.id.song_five_star_3)
|
|
||||||
// var fiveStar4: ImageView = view.findViewById(R.id.song_five_star_4)
|
|
||||||
// var fiveStar5: ImageView = view.findViewById(R.id.song_five_star_5)
|
|
||||||
// var star: ImageView = view.findViewById(R.id.song_star)
|
|
||||||
// var drag: ImageView = view.findViewById(R.id.song_drag)
|
|
||||||
// var track: TextView = view.findViewById(R.id.song_track)
|
|
||||||
// var title: TextView = view.findViewById(R.id.song_title)
|
|
||||||
// var artist: TextView = view.findViewById(R.id.song_artist)
|
|
||||||
// var duration: TextView = view.findViewById(R.id.song_duration)
|
|
||||||
// var status: TextView = view.findViewById(R.id.song_status)
|
|
||||||
//
|
|
||||||
// var entry: MusicDirectory.Entry? = null
|
|
||||||
// private set
|
|
||||||
// var downloadFile: DownloadFile? = null
|
|
||||||
// private set
|
|
||||||
//
|
|
||||||
// private var isMaximized = false
|
|
||||||
// private var leftImage: Drawable? = null
|
|
||||||
// private var previousLeftImageType: ImageType? = null
|
|
||||||
// private var previousRightImageType: ImageType? = null
|
|
||||||
// private var leftImageType: ImageType? = null
|
|
||||||
// private var playing = false
|
|
||||||
//
|
|
||||||
// private val features: FeatureStorage = get()
|
|
||||||
// private val useFiveStarRating: Boolean = features.isFeatureEnabled(Feature.FIVE_STAR_RATING)
|
|
||||||
// private val mediaPlayerController: MediaPlayerController by inject()
|
|
||||||
//
|
|
||||||
// fun setSong(file: DownloadFile, checkable: Boolean, draggable: Boolean) {
|
|
||||||
// val song = file.song
|
|
||||||
// downloadFile = file
|
|
||||||
// entry = song
|
|
||||||
//
|
|
||||||
// val entryDescription = Util.readableEntryDescription(song)
|
|
||||||
//
|
|
||||||
// artist.text = entryDescription.artist
|
|
||||||
// title.text = entryDescription.title
|
|
||||||
// duration.text = entryDescription.duration
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// if (Settings.shouldShowTrackNumber && song.track != null && song.track!! > 0) {
|
|
||||||
// track.text = entryDescription.trackNumber
|
|
||||||
// } else {
|
|
||||||
// track.isVisible = false
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// check.isVisible = (checkable && !song.isVideo)
|
|
||||||
// drag.isVisible = draggable
|
|
||||||
//
|
|
||||||
// if (ActiveServerProvider.isOffline()) {
|
|
||||||
// star.isVisible = false
|
|
||||||
// rating.isVisible = false
|
|
||||||
// } else {
|
|
||||||
// setupStarButtons(song)
|
|
||||||
// }
|
|
||||||
// update()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private fun setupStarButtons(song: MusicDirectory.Entry) {
|
|
||||||
// if (useFiveStarRating) {
|
|
||||||
// star.isVisible = false
|
|
||||||
// val rating = if (song.userRating == null) 0 else song.userRating!!
|
|
||||||
// fiveStar1.setImageDrawable(
|
|
||||||
// if (rating > 0) DownloadRowAdapter.starDrawable else DownloadRowAdapter.starHollowDrawable
|
|
||||||
// )
|
|
||||||
// fiveStar2.setImageDrawable(
|
|
||||||
// if (rating > 1) DownloadRowAdapter.starDrawable else DownloadRowAdapter.starHollowDrawable
|
|
||||||
// )
|
|
||||||
// fiveStar3.setImageDrawable(
|
|
||||||
// if (rating > 2) DownloadRowAdapter.starDrawable else DownloadRowAdapter.starHollowDrawable
|
|
||||||
// )
|
|
||||||
// fiveStar4.setImageDrawable(
|
|
||||||
// if (rating > 3) DownloadRowAdapter.starDrawable else DownloadRowAdapter.starHollowDrawable
|
|
||||||
// )
|
|
||||||
// fiveStar5.setImageDrawable(
|
|
||||||
// if (rating > 4) DownloadRowAdapter.starDrawable else DownloadRowAdapter.starHollowDrawable
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// rating.isVisible = false
|
|
||||||
// star.setImageDrawable(
|
|
||||||
// if (song.starred) DownloadRowAdapter.starDrawable else DownloadRowAdapter.starHollowDrawable
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// star.setOnClickListener {
|
|
||||||
// val isStarred = song.starred
|
|
||||||
// val id = song.id
|
|
||||||
//
|
|
||||||
// if (!isStarred) {
|
|
||||||
// star.setImageDrawable(DownloadRowAdapter.starDrawable)
|
|
||||||
// song.starred = true
|
|
||||||
// } else {
|
|
||||||
// star.setImageDrawable(DownloadRowAdapter.starHollowDrawable)
|
|
||||||
// song.starred = false
|
|
||||||
// }
|
|
||||||
// Thread {
|
|
||||||
// val musicService = MusicServiceFactory.getMusicService()
|
|
||||||
// try {
|
|
||||||
// if (!isStarred) {
|
|
||||||
// musicService.star(id, null, null)
|
|
||||||
// } else {
|
|
||||||
// musicService.unstar(id, null, null)
|
|
||||||
// }
|
|
||||||
// } catch (all: Exception) {
|
|
||||||
// Timber.e(all)
|
|
||||||
// }
|
|
||||||
// }.start()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// @Synchronized
|
|
||||||
// // TDOD: Should be removed
|
|
||||||
// fun update() {
|
|
||||||
// val song = entry ?: return
|
|
||||||
//
|
|
||||||
// updateDownloadStatus(downloadFile!!)
|
|
||||||
//
|
|
||||||
// if (entry?.starred != true) {
|
|
||||||
// if (star.drawable !== DownloadRowAdapter.starHollowDrawable) {
|
|
||||||
// star.setImageDrawable(DownloadRowAdapter.starHollowDrawable)
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// if (star.drawable !== DownloadRowAdapter.starDrawable) {
|
|
||||||
// star.setImageDrawable(DownloadRowAdapter.starDrawable)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// val rating = entry?.userRating ?: 0
|
|
||||||
// fiveStar1.setImageDrawable(
|
|
||||||
// if (rating > 0) DownloadRowAdapter.starDrawable else DownloadRowAdapter.starHollowDrawable
|
|
||||||
// )
|
|
||||||
// fiveStar2.setImageDrawable(
|
|
||||||
// if (rating > 1) DownloadRowAdapter.starDrawable else DownloadRowAdapter.starHollowDrawable
|
|
||||||
// )
|
|
||||||
// fiveStar3.setImageDrawable(
|
|
||||||
// if (rating > 2) DownloadRowAdapter.starDrawable else DownloadRowAdapter.starHollowDrawable
|
|
||||||
// )
|
|
||||||
// fiveStar4.setImageDrawable(
|
|
||||||
// if (rating > 3) DownloadRowAdapter.starDrawable else DownloadRowAdapter.starHollowDrawable
|
|
||||||
// )
|
|
||||||
// fiveStar5.setImageDrawable(
|
|
||||||
// if (rating > 4) DownloadRowAdapter.starDrawable else DownloadRowAdapter.starHollowDrawable
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// val playing = mediaPlayerController.currentPlaying === downloadFile
|
|
||||||
//
|
|
||||||
// if (playing) {
|
|
||||||
// if (!this.playing) {
|
|
||||||
// this.playing = true
|
|
||||||
// title.setCompoundDrawablesWithIntrinsicBounds(
|
|
||||||
// DownloadRowAdapter.playingImage, null, null, null
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// if (this.playing) {
|
|
||||||
// this.playing = false
|
|
||||||
// title.setCompoundDrawablesWithIntrinsicBounds(
|
|
||||||
// 0, 0, 0, 0
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fun updateDownloadStatus(downloadFile: DownloadFile) {
|
|
||||||
//
|
|
||||||
// if (downloadFile.isWorkDone) {
|
|
||||||
// val newLeftImageType =
|
|
||||||
// if (downloadFile.isSaved) ImageType.Pin else ImageType.Downloaded
|
|
||||||
//
|
|
||||||
// if (leftImageType != newLeftImageType) {
|
|
||||||
// leftImage = if (downloadFile.isSaved) {
|
|
||||||
// DownloadRowAdapter.pinImage
|
|
||||||
// } else {
|
|
||||||
// DownloadRowAdapter.downloadedImage
|
|
||||||
// }
|
|
||||||
// leftImageType = newLeftImageType
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// leftImageType = ImageType.None
|
|
||||||
// leftImage = null
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// val rightImageType: ImageType
|
|
||||||
// val rightImage: Drawable?
|
|
||||||
//
|
|
||||||
// if (downloadFile.isDownloading && !downloadFile.isDownloadCancelled) {
|
|
||||||
// status.text = Util.formatPercentage(downloadFile.progress.value!!)
|
|
||||||
//
|
|
||||||
// rightImageType = ImageType.Downloading
|
|
||||||
// rightImage = DownloadRowAdapter.downloadingImage
|
|
||||||
// } else {
|
|
||||||
// rightImageType = ImageType.None
|
|
||||||
// rightImage = null
|
|
||||||
//
|
|
||||||
// val statusText = status.text
|
|
||||||
// if (!statusText.isNullOrEmpty()) status.text = null
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (previousLeftImageType != leftImageType || previousRightImageType != rightImageType) {
|
|
||||||
// previousLeftImageType = leftImageType
|
|
||||||
// previousRightImageType = rightImageType
|
|
||||||
//
|
|
||||||
// status.setCompoundDrawablesWithIntrinsicBounds(
|
|
||||||
// leftImage, null, rightImage, null
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// if (rightImage === DownloadRowAdapter.downloadingImage) {
|
|
||||||
// // FIXME
|
|
||||||
// val frameAnimation = rightImage as AnimationDrawable?
|
|
||||||
//
|
|
||||||
// frameAnimation?.setVisible(true, true)
|
|
||||||
// frameAnimation?.start()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // fun updateDownloadStatus2(
|
|
||||||
// // downloadFile: DownloadFile,
|
|
||||||
// // ) {
|
|
||||||
// //
|
|
||||||
// // var image: Drawable? = null
|
|
||||||
// //
|
|
||||||
// // when (downloadFile.status.value) {
|
|
||||||
// // DownloadStatus.DONE -> {
|
|
||||||
// // image = if (downloadFile.isSaved) DownloadRowAdapter.pinImage else DownloadRowAdapter.downloadedImage
|
|
||||||
// // status.text = null
|
|
||||||
// // }
|
|
||||||
// // DownloadStatus.DOWNLOADING -> {
|
|
||||||
// // status.text = Util.formatPercentage(downloadFile.progress.value!!)
|
|
||||||
// // image = DownloadRowAdapter.downloadingImage
|
|
||||||
// // }
|
|
||||||
// // else -> {
|
|
||||||
// // status.text = null
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// //
|
|
||||||
// // // TODO: Migrate the image animation stuff from SongView into this class
|
|
||||||
// //
|
|
||||||
// // if (image != null) {
|
|
||||||
// // status.setCompoundDrawablesWithIntrinsicBounds(
|
|
||||||
// // image, null, null, null
|
|
||||||
// // )
|
|
||||||
// // }
|
|
||||||
// //
|
|
||||||
// // if (image === DownloadRowAdapter.downloadingImage) {
|
|
||||||
// // // FIXME
|
|
||||||
// //// val frameAnimation = image as AnimationDrawable
|
|
||||||
// ////
|
|
||||||
// //// frameAnimation.setVisible(true, true)
|
|
||||||
// //// frameAnimation.start()
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
//
|
|
||||||
// override fun setChecked(newStatus: Boolean) {
|
|
||||||
// check.isChecked = newStatus
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun isChecked(): Boolean {
|
|
||||||
// return check.isChecked
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun toggle() {
|
|
||||||
// check.toggle()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fun maximizeOrMinimize() {
|
|
||||||
// isMaximized = !isMaximized
|
|
||||||
//
|
|
||||||
// title.isSingleLine = !isMaximized
|
|
||||||
// artist.isSingleLine = !isMaximized
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// enum class ImageType {
|
|
||||||
// None, Pin, Downloaded, Downloading
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// }
|
|
Loading…
x
Reference in New Issue
Block a user