Fixed search, put compareTo method into Interface
This commit is contained in:
parent
bdac092eff
commit
f1e789ea9b
|
@ -11,21 +11,4 @@ data class Artist(
|
|||
override var coverArt: String? = null,
|
||||
override var albumCount: Long? = null,
|
||||
override var closeness: Int = 0
|
||||
) : ArtistOrIndex(id) {
|
||||
|
||||
fun compareTo(other: Artist): Int {
|
||||
when {
|
||||
this.closeness == other.closeness -> {
|
||||
return 0
|
||||
}
|
||||
this.closeness > other.closeness -> {
|
||||
return -1
|
||||
}
|
||||
else -> {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun compareTo(other: Identifiable) = compareTo(other as Artist)
|
||||
}
|
||||
) : ArtistOrIndex(id)
|
||||
|
|
|
@ -15,4 +15,21 @@ abstract class ArtistOrIndex(
|
|||
open var albumCount: Long? = null,
|
||||
@Ignore
|
||||
open var closeness: Int = 0
|
||||
) : GenericEntry()
|
||||
) : GenericEntry() {
|
||||
|
||||
fun compareTo(other: ArtistOrIndex): Int {
|
||||
when {
|
||||
this.closeness == other.closeness -> {
|
||||
return 0
|
||||
}
|
||||
this.closeness > other.closeness -> {
|
||||
return -1
|
||||
}
|
||||
else -> {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun compareTo(other: Identifiable) = compareTo(other as ArtistOrIndex)
|
||||
}
|
||||
|
|
|
@ -3,19 +3,17 @@ package org.moire.ultrasonic.domain
|
|||
import androidx.room.Ignore
|
||||
|
||||
abstract class GenericEntry : Identifiable {
|
||||
abstract override val id: String
|
||||
@Ignore
|
||||
open val name: String? = null
|
||||
override fun compareTo(other: Identifiable): Int {
|
||||
return this.id.toInt().compareTo(other.id.toInt())
|
||||
}
|
||||
@delegate:Ignore
|
||||
override val longId: Long by lazy {
|
||||
id.hashCode().toLong()
|
||||
}
|
||||
}
|
||||
|
||||
interface Identifiable : Comparable<Identifiable> {
|
||||
val id: String
|
||||
|
||||
val longId: Long
|
||||
get() = id.hashCode().toLong()
|
||||
|
||||
override fun compareTo(other: Identifiable): Int {
|
||||
return longId.compareTo(other.longId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ class MusicDirectory : ArrayList<MusicDirectory.Child>() {
|
|||
}
|
||||
}
|
||||
|
||||
abstract class Child : Identifiable, GenericEntry() {
|
||||
abstract class Child : GenericEntry() {
|
||||
abstract override var id: String
|
||||
abstract var parent: String?
|
||||
abstract var isDirectory: Boolean
|
||||
|
|
|
@ -7,7 +7,7 @@ import org.moire.ultrasonic.domain.MusicDirectory.Entry
|
|||
* The result of a search. Contains matching artists, albums and songs.
|
||||
*/
|
||||
data class SearchResult(
|
||||
val artists: List<Artist> = listOf(),
|
||||
val artists: List<ArtistOrIndex> = listOf(),
|
||||
val albums: List<Album> = listOf(),
|
||||
val songs: List<Entry> = listOf()
|
||||
)
|
||||
|
|
|
@ -7,8 +7,8 @@ data class Album(
|
|||
val id: String = "",
|
||||
val parent: String = "",
|
||||
val album: String = "",
|
||||
val title: String = "",
|
||||
val name: String = "",
|
||||
val title: String? = null,
|
||||
val name: String? = null,
|
||||
val discNumber: Int = 0,
|
||||
val coverArt: String = "",
|
||||
val songCount: Int = 0,
|
||||
|
|
|
@ -2,7 +2,8 @@ org.gradle.parallel=true
|
|||
org.gradle.daemon=true
|
||||
org.gradle.configureondemand=true
|
||||
org.gradle.caching=true
|
||||
org.gradle.jvmargs=-Xmx2g
|
||||
org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC
|
||||
|
||||
|
||||
kotlin.incremental=true
|
||||
kotlin.caching.enabled=true
|
||||
|
|
|
@ -1,117 +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.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.SectionIndexer;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.moire.ultrasonic.R;
|
||||
import org.moire.ultrasonic.domain.Artist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Sindre Mehus
|
||||
*/
|
||||
public class ArtistAdapter extends ArrayAdapter<Artist> implements SectionIndexer
|
||||
{
|
||||
private final LayoutInflater layoutInflater;
|
||||
|
||||
// Both arrays are indexed by section ID.
|
||||
private final Object[] sections;
|
||||
private final Integer[] positions;
|
||||
|
||||
public ArtistAdapter(Context context, List<Artist> artists)
|
||||
{
|
||||
super(context, R.layout.list_item_generic, artists);
|
||||
|
||||
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
Collection<String> sectionSet = new LinkedHashSet<String>(30);
|
||||
List<Integer> positionList = new ArrayList<Integer>(30);
|
||||
|
||||
for (int i = 0; i < artists.size(); i++)
|
||||
{
|
||||
Artist artist = artists.get(i);
|
||||
String index = artist.getIndex();
|
||||
|
||||
if (!sectionSet.contains(index))
|
||||
{
|
||||
sectionSet.add(index);
|
||||
positionList.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
sections = sectionSet.toArray(new Object[0]);
|
||||
positions = positionList.toArray(new Integer[0]);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(
|
||||
int position,
|
||||
@Nullable View convertView,
|
||||
@NonNull ViewGroup parent
|
||||
) {
|
||||
View rowView = convertView;
|
||||
if (rowView == null) {
|
||||
rowView = layoutInflater.inflate(R.layout.list_item_generic, parent, false);
|
||||
}
|
||||
((TextView) rowView).setText(getItem(position).getName());
|
||||
|
||||
return rowView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getSections()
|
||||
{
|
||||
return sections;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPositionForSection(int section)
|
||||
{
|
||||
return positions.length > section ? positions[section] : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSectionForPosition(int pos)
|
||||
{
|
||||
for (int i = 0; i < sections.length - 1; i++)
|
||||
{
|
||||
if (pos < positions[i + 1])
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return sections.length - 1;
|
||||
}
|
||||
}
|
|
@ -88,8 +88,4 @@ class AlbumHeader(
|
|||
|
||||
override val longId: Long
|
||||
get() = -1L
|
||||
|
||||
override fun compareTo(other: Identifiable): Int {
|
||||
return this.longId.compareTo(other.longId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,8 +52,6 @@ class BaseAdapter<T : Identifiable> : MultiTypeAdapter() {
|
|||
return mDiffer.currentList[position]
|
||||
}
|
||||
|
||||
// override getIt
|
||||
|
||||
override var items: List<Any>
|
||||
get() = getCurrentList()
|
||||
set(value) {
|
||||
|
|
|
@ -41,9 +41,5 @@ class DividerBinder : ItemViewBinder<DividerBinder.Divider, DividerBinder.ViewHo
|
|||
data class Divider(val stringId: Int) : Identifiable {
|
||||
override val id: String
|
||||
get() = stringId.toString()
|
||||
override val longId: Long
|
||||
get() = stringId.toLong()
|
||||
|
||||
override fun compareTo(other: Identifiable): Int = longId.compareTo(other.longId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,9 +128,5 @@ class FolderSelectorBinder(context: Context) :
|
|||
|
||||
override val longId: Long
|
||||
get() = -1L
|
||||
|
||||
override fun compareTo(other: Identifiable): Int {
|
||||
return longId.compareTo(other.longId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.moire.ultrasonic.adapters
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.drakeet.multitype.ItemViewBinder
|
||||
import org.moire.ultrasonic.R
|
||||
|
@ -37,14 +36,9 @@ class MoreButtonBinder : ItemViewBinder<MoreButtonBinder.MoreButton, RecyclerVie
|
|||
data class MoreButton(
|
||||
val stringId: Int,
|
||||
val onClick: (() -> Unit)
|
||||
): Identifiable {
|
||||
) : Identifiable {
|
||||
|
||||
override val id: String
|
||||
get() = stringId.toString()
|
||||
override val longId: Long
|
||||
get() = stringId.toLong()
|
||||
|
||||
override fun compareTo(other: Identifiable): Int = longId.compareTo(other.longId)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import org.moire.ultrasonic.api.subsonic.models.Album
|
|||
|
||||
fun Album.toDomainEntity(): MusicDirectory.Album = MusicDirectory.Album(
|
||||
id = this@toDomainEntity.id,
|
||||
title = this@toDomainEntity.title,
|
||||
title = this@toDomainEntity.name ?: this@toDomainEntity.title,
|
||||
album = this@toDomainEntity.album,
|
||||
coverArt = this@toDomainEntity.coverArt,
|
||||
artist = this@toDomainEntity.artist,
|
||||
|
|
|
@ -9,15 +9,12 @@ package org.moire.ultrasonic.fragment
|
|||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.adapters.AlbumRowBinder
|
||||
import org.moire.ultrasonic.adapters.FolderSelectorBinder
|
||||
import org.moire.ultrasonic.domain.Identifiable
|
||||
import org.moire.ultrasonic.domain.MusicDirectory
|
||||
import org.moire.ultrasonic.model.AlbumListModel
|
||||
import org.moire.ultrasonic.util.Constants
|
||||
|
@ -40,7 +37,10 @@ class AlbumListFragment : EntryListFragment<MusicDirectory.Album>() {
|
|||
/**
|
||||
* The central function to pass a query to the model and return a LiveData object
|
||||
*/
|
||||
override fun getLiveData(args: Bundle?, refresh: Boolean): LiveData<List<MusicDirectory.Album>> {
|
||||
override fun getLiveData(
|
||||
args: Bundle?,
|
||||
refresh: Boolean
|
||||
): LiveData<List<MusicDirectory.Album>> {
|
||||
if (args == null) throw IllegalArgumentException("Required arguments are missing")
|
||||
|
||||
val refresh = args.getBoolean(Constants.INTENT_EXTRA_NAME_REFRESH) || refresh
|
||||
|
|
|
@ -2,25 +2,20 @@ package org.moire.ultrasonic.fragment
|
|||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.adapters.ArtistRowBinder
|
||||
import org.moire.ultrasonic.adapters.FolderSelectorBinder
|
||||
import org.moire.ultrasonic.domain.Artist
|
||||
import org.moire.ultrasonic.domain.ArtistOrIndex
|
||||
import org.moire.ultrasonic.domain.Identifiable
|
||||
import org.moire.ultrasonic.domain.Index
|
||||
import org.moire.ultrasonic.domain.MusicDirectory
|
||||
import org.moire.ultrasonic.model.ArtistListModel
|
||||
import org.moire.ultrasonic.util.Constants
|
||||
|
||||
/**
|
||||
* Displays the list of Artists from the media library
|
||||
*
|
||||
* FIXME: FOLDER HEADER NOT POPULATED ON FIST LOAD
|
||||
* Displays the list of Artists or Indexes (folders) from the media library
|
||||
*/
|
||||
class ArtistListFragment : EntryListFragment<ArtistOrIndex>() {
|
||||
|
||||
|
@ -60,23 +55,32 @@ class ArtistListFragment : EntryListFragment<ArtistOrIndex>() {
|
|||
* If we are showing artists, we need to go to AlbumList
|
||||
*/
|
||||
override fun onItemClick(item: ArtistOrIndex) {
|
||||
val bundle = Bundle()
|
||||
Companion.onItemClick(item, findNavController())
|
||||
}
|
||||
|
||||
// Common arguments
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ID, item.id)
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_NAME, item.name)
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_PARENT_ID, item.id)
|
||||
bundle.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, (item is Artist))
|
||||
companion object {
|
||||
fun onItemClick(item: ArtistOrIndex, navController: NavController) {
|
||||
val bundle = Bundle()
|
||||
|
||||
// Check type
|
||||
if (item is Index) {
|
||||
findNavController().navigate(R.id.artistsListToTrackCollection, bundle)
|
||||
} else {
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, Constants.ALBUMS_OF_ARTIST)
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE, item.name)
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 1000)
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0)
|
||||
findNavController().navigate(R.id.artistsListToAlbumsList, bundle)
|
||||
// Common arguments
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ID, item.id)
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_NAME, item.name)
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_PARENT_ID, item.id)
|
||||
bundle.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, (item is Artist))
|
||||
|
||||
// Check type
|
||||
if (item is Index) {
|
||||
navController.navigate(R.id.artistsListToTrackCollection, bundle)
|
||||
} else {
|
||||
bundle.putString(
|
||||
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE,
|
||||
Constants.ALBUMS_OF_ARTIST
|
||||
)
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE, item.name)
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 1000)
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0)
|
||||
navController.navigate(R.id.artistsListToAlbumsList, bundle)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import androidx.navigation.fragment.findNavController
|
|||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.adapters.FolderSelectorBinder
|
||||
import org.moire.ultrasonic.domain.Artist
|
||||
import org.moire.ultrasonic.domain.ArtistOrIndex
|
||||
import org.moire.ultrasonic.domain.GenericEntry
|
||||
import org.moire.ultrasonic.domain.Identifiable
|
||||
import org.moire.ultrasonic.service.RxBus
|
||||
|
@ -50,6 +49,10 @@ abstract class EntryListFragment<T : GenericEntry> : MultiListFragment<T>() {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// Call a cheap function on ServerSettingsModel to make sure it is initialized by Koin,
|
||||
// because it can't be initialized from inside the callback
|
||||
serverSettingsModel.toString()
|
||||
|
||||
RxBus.musicFolderChangedEventObservable.subscribe {
|
||||
if (!listModel.isOffline()) {
|
||||
val currentSetting = listModel.activeServer
|
||||
|
|
|
@ -3,17 +3,16 @@ package org.moire.ultrasonic.fragment
|
|||
import android.app.SearchManager
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.ListAdapter
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.navigation.Navigation
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.component.KoinComponent
|
||||
|
@ -26,7 +25,9 @@ import org.moire.ultrasonic.adapters.MoreButtonBinder
|
|||
import org.moire.ultrasonic.adapters.MoreButtonBinder.MoreButton
|
||||
import org.moire.ultrasonic.adapters.TrackViewBinder
|
||||
import org.moire.ultrasonic.domain.Artist
|
||||
import org.moire.ultrasonic.domain.ArtistOrIndex
|
||||
import org.moire.ultrasonic.domain.Identifiable
|
||||
import org.moire.ultrasonic.domain.Index
|
||||
import org.moire.ultrasonic.domain.MusicDirectory
|
||||
import org.moire.ultrasonic.domain.SearchResult
|
||||
import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle
|
||||
|
@ -41,12 +42,10 @@ import org.moire.ultrasonic.util.CommunicationError
|
|||
import org.moire.ultrasonic.util.Constants
|
||||
import org.moire.ultrasonic.util.Settings
|
||||
import org.moire.ultrasonic.util.Util.toast
|
||||
import org.moire.ultrasonic.view.ArtistAdapter
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Initiates a search on the media library and displays the results
|
||||
* FIXME: Artist click, display
|
||||
*/
|
||||
class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
|
||||
private var searchResult: SearchResult? = null
|
||||
|
@ -265,11 +264,28 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
|
|||
populateList(listModel.trimResultLength(searchResult!!, maxSongs = Int.MAX_VALUE))
|
||||
}
|
||||
|
||||
private fun onArtistSelected(artist: Artist) {
|
||||
private fun onArtistSelected(item: ArtistOrIndex) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ID, artist.id)
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_NAME, artist.id)
|
||||
Navigation.findNavController(requireView()).navigate(R.id.searchToSelectAlbum, bundle)
|
||||
|
||||
// Common arguments
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ID, item.id)
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_NAME, item.name)
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_PARENT_ID, item.id)
|
||||
bundle.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, (item is Artist))
|
||||
|
||||
// Check type
|
||||
if (item is Index) {
|
||||
findNavController().navigate(R.id.searchToTrackCollection, bundle)
|
||||
} else {
|
||||
bundle.putString(
|
||||
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE,
|
||||
Constants.ALBUMS_OF_ARTIST
|
||||
)
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE, item.name)
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 1000)
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0)
|
||||
findNavController().navigate(R.id.searchToAlbumsList, bundle)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onAlbumSelected(album: MusicDirectory.Album, autoplay: Boolean) {
|
||||
|
@ -278,14 +294,21 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
|
|||
bundle.putString(Constants.INTENT_EXTRA_NAME_NAME, album.title)
|
||||
bundle.putBoolean(Constants.INTENT_EXTRA_NAME_IS_ALBUM, album.isDirectory)
|
||||
bundle.putBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, autoplay)
|
||||
Navigation.findNavController(requireView()).navigate(R.id.searchToSelectAlbum, bundle)
|
||||
Navigation.findNavController(requireView()).navigate(R.id.searchToTrackCollection, bundle)
|
||||
}
|
||||
|
||||
private fun onSongSelected(song: MusicDirectory.Entry, append: Boolean) {
|
||||
if (!append) {
|
||||
mediaPlayerController.clear()
|
||||
}
|
||||
mediaPlayerController.addToPlaylist(listOf(song), false, false, false, false, false)
|
||||
mediaPlayerController.addToPlaylist(
|
||||
listOf(song),
|
||||
save = false,
|
||||
autoPlay = false,
|
||||
playNext = false,
|
||||
shuffle = false,
|
||||
newPlaylist = false
|
||||
)
|
||||
mediaPlayerController.play(mediaPlayerController.playlistSize - 1)
|
||||
toast(context, resources.getQuantityString(R.plurals.select_album_n_songs_added, 1, 1))
|
||||
}
|
||||
|
@ -304,7 +327,7 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
|
|||
|
||||
override fun onItemClick(item: Identifiable) {
|
||||
when (item) {
|
||||
is Artist -> {
|
||||
is ArtistOrIndex -> {
|
||||
onArtistSelected(item)
|
||||
}
|
||||
is MusicDirectory.Entry -> {
|
||||
|
|
|
@ -49,13 +49,11 @@ import org.moire.ultrasonic.util.Settings
|
|||
import org.moire.ultrasonic.util.Util
|
||||
|
||||
/**
|
||||
*
|
||||
* Displays a group of tracks, eg. the songs of an album, of a playlist etc.
|
||||
*
|
||||
* In most cases the data should be just a list of Entries, but there are some cases
|
||||
* where the list can contain Albums as well. This happens especially when having ID3 tags disabled,
|
||||
* or using Offline mode, both in which Indexes instead of Artists are being used.
|
||||
*
|
||||
*/
|
||||
@Suppress("TooManyFunctions")
|
||||
open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
||||
|
@ -96,7 +94,7 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
|||
// Setup refresh handler
|
||||
refreshListView = view.findViewById(refreshListId)
|
||||
refreshListView?.setOnRefreshListener {
|
||||
refreshData(true)
|
||||
getLiveData(arguments, true)
|
||||
}
|
||||
|
||||
// TODO: remove special casing for songsForGenre
|
||||
|
@ -209,12 +207,6 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
|||
refreshListView?.isRefreshing = false
|
||||
}
|
||||
|
||||
private fun refreshData(refresh: Boolean = false) {
|
||||
val args = getArgumentsClone()
|
||||
args.putBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, refresh)
|
||||
getLiveData(args)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
super.onPrepareOptionsMenu(menu)
|
||||
playAllButton = menu.findItem(R.id.select_album_play_all)
|
||||
|
@ -293,8 +285,6 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
|||
}
|
||||
|
||||
val isArtist = arguments?.getBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, false) ?: false
|
||||
|
||||
// FIXME WHICH id if no arguments?
|
||||
val id = arguments?.getString(Constants.INTENT_EXTRA_NAME_ID)
|
||||
|
||||
if (hasSubFolders && id != null) {
|
||||
|
@ -565,7 +555,10 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
|||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
override fun getLiveData(args: Bundle?, refresh: Boolean): LiveData<List<MusicDirectory.Child>> {
|
||||
override fun getLiveData(
|
||||
args: Bundle?,
|
||||
refresh: Boolean
|
||||
): LiveData<List<MusicDirectory.Child>> {
|
||||
if (args == null) return listModel.currentList
|
||||
val id = args.getString(Constants.INTENT_EXTRA_NAME_ID)
|
||||
val isAlbum = args.getBoolean(Constants.INTENT_EXTRA_NAME_IS_ALBUM, false)
|
||||
|
@ -588,7 +581,7 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
|||
val albumListOffset = args.getInt(
|
||||
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0
|
||||
)
|
||||
val refresh = args.getBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, true) || refresh
|
||||
val refresh2 = args.getBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, true) || refresh
|
||||
|
||||
listModel.viewModelScope.launch(handler) {
|
||||
refreshListView?.isRefreshing = true
|
||||
|
@ -610,7 +603,7 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
|||
listModel.getStarred()
|
||||
} else if (getVideos != 0) {
|
||||
setTitle(R.string.main_videos)
|
||||
listModel.getVideos(refresh)
|
||||
listModel.getVideos(refresh2)
|
||||
} else if (getRandomTracks != 0) {
|
||||
setTitle(R.string.main_songs_random)
|
||||
listModel.getRandom(albumListSize)
|
||||
|
@ -618,12 +611,12 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
|||
setTitle(name)
|
||||
if (!isOffline() && Settings.shouldUseId3Tags) {
|
||||
if (isAlbum) {
|
||||
listModel.getAlbum(refresh, id!!, name)
|
||||
listModel.getAlbum(refresh2, id!!, name)
|
||||
} else {
|
||||
throw IllegalAccessException("Use AlbumFragment instead!")
|
||||
}
|
||||
} else {
|
||||
listModel.getMusicDirectory(refresh, id!!, name)
|
||||
listModel.getMusicDirectory(refresh2, id!!, name)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -436,10 +436,6 @@ class DownloadFile(
|
|||
override val id: String
|
||||
get() = song.id
|
||||
|
||||
override val longId: Long by lazy {
|
||||
id.hashCode().toLong()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MAX_RETRIES = 5
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.koin.core.component.KoinComponent
|
|||
import org.koin.core.component.inject
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||
import org.moire.ultrasonic.domain.Artist
|
||||
import org.moire.ultrasonic.domain.ArtistOrIndex
|
||||
import org.moire.ultrasonic.domain.Bookmark
|
||||
import org.moire.ultrasonic.domain.ChatMessage
|
||||
import org.moire.ultrasonic.domain.Genre
|
||||
|
@ -122,7 +123,7 @@ class OfflineMusicService : MusicService, KoinComponent {
|
|||
}
|
||||
|
||||
override fun search(criteria: SearchCriteria): SearchResult {
|
||||
val artists: MutableList<Artist> = ArrayList()
|
||||
val artists: MutableList<ArtistOrIndex> = ArrayList()
|
||||
val albums: MutableList<MusicDirectory.Album> = ArrayList()
|
||||
val songs: MutableList<MusicDirectory.Entry> = ArrayList()
|
||||
val root = FileUtil.musicDirectory
|
||||
|
@ -131,7 +132,7 @@ class OfflineMusicService : MusicService, KoinComponent {
|
|||
val artistName = artistFile.name
|
||||
if (artistFile.isDirectory) {
|
||||
if (matchCriteria(criteria, artistName).also { closeness = it } > 0) {
|
||||
val artist = Artist(artistFile.path)
|
||||
val artist = Index(artistFile.path)
|
||||
artist.index = artistFile.name.substring(0, 1)
|
||||
artist.name = artistName
|
||||
artist.closeness = closeness
|
||||
|
|
|
@ -361,7 +361,6 @@ open class RESTMusicService(
|
|||
musicFolderId
|
||||
).execute().throwOnFailure()
|
||||
|
||||
|
||||
return response.body()!!.albumList.toDomainEntityList()
|
||||
}
|
||||
|
||||
|
|
|
@ -60,8 +60,11 @@
|
|||
android:id="@+id/searchFragment"
|
||||
android:name="org.moire.ultrasonic.fragment.SearchFragment" >
|
||||
<action
|
||||
android:id="@+id/searchToSelectAlbum"
|
||||
android:id="@+id/searchToTrackCollection"
|
||||
app:destination="@id/trackCollectionFragment" />
|
||||
<action
|
||||
android:id="@+id/searchToAlbumsList"
|
||||
app:destination="@id/albumListFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/playlistsFragment"
|
||||
|
|
Loading…
Reference in New Issue