Move Track and Album to their own files

This commit is contained in:
tzugen 2022-03-27 14:57:07 +02:00
parent e53da92dac
commit 892b441c0d
No known key found for this signature in database
GPG Key ID: 61E9C34BC10EC930
41 changed files with 258 additions and 238 deletions

View File

@ -0,0 +1,27 @@
package org.moire.ultrasonic.domain
import androidx.room.PrimaryKey
import java.util.Date
data class Album(
@PrimaryKey override var id: String,
override var parent: String? = null,
override var album: String? = null,
override var title: String? = null,
override val name: String? = null,
override var discNumber: Int? = 0,
override var coverArt: String? = null,
override var songCount: Long? = null,
override var created: Date? = null,
override var artist: String? = null,
override var artistId: String? = null,
override var duration: Int? = 0,
override var year: Int? = 0,
override var genre: String? = null,
override var starred: Boolean = false,
override var path: String? = null,
override var closeness: Int = 0,
) : MusicDirectory.Child() {
override var isDirectory = true
override var isVideo = false
}

View File

@ -2,7 +2,6 @@ package org.moire.ultrasonic.domain
import java.io.Serializable
import java.util.Date
import org.moire.ultrasonic.domain.MusicDirectory.Track
data class Bookmark(
val position: Int = 0,

View File

@ -1,8 +1,5 @@
package org.moire.ultrasonic.domain
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
import java.util.Date
class MusicDirectory : ArrayList<MusicDirectory.Child>() {
@ -53,86 +50,4 @@ class MusicDirectory : ArrayList<MusicDirectory.Child>() {
abstract var closeness: Int
abstract var isVideo: Boolean
}
@Entity
data class Track(
@PrimaryKey override var id: String,
override var parent: String? = null,
override var isDirectory: Boolean = false,
override var title: String? = null,
override var album: String? = null,
var albumId: String? = null,
override var artist: String? = null,
override var artistId: String? = null,
var track: Int? = null,
override var year: Int? = null,
override var genre: String? = null,
var contentType: String? = null,
var suffix: String? = null,
var transcodedContentType: String? = null,
var transcodedSuffix: String? = null,
override var coverArt: String? = null,
var size: Long? = null,
override var songCount: Long? = null,
override var duration: Int? = null,
var bitRate: Int? = null,
override var path: String? = null,
override var isVideo: Boolean = false,
override var starred: Boolean = false,
override var discNumber: Int? = null,
var type: String? = null,
override var created: Date? = null,
override var closeness: Int = 0,
var bookmarkPosition: Int = 0,
var userRating: Int? = null,
var averageRating: Float? = null,
override var name: String? = null
) : Serializable, Child() {
fun setDuration(duration: Long) {
this.duration = duration.toInt()
}
companion object {
private const val serialVersionUID = -3339106650010798108L
}
fun compareTo(other: Track): 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 Track)
}
data class Album(
@PrimaryKey override var id: String,
override var parent: String? = null,
override var album: String? = null,
override var title: String? = null,
override val name: String? = null,
override var discNumber: Int? = 0,
override var coverArt: String? = null,
override var songCount: Long? = null,
override var created: Date? = null,
override var artist: String? = null,
override var artistId: String? = null,
override var duration: Int? = 0,
override var year: Int? = 0,
override var genre: String? = null,
override var starred: Boolean = false,
override var path: String? = null,
override var closeness: Int = 0,
) : Child() {
override var isDirectory = true
override var isVideo = false
}
}

View File

@ -1,8 +1,5 @@
package org.moire.ultrasonic.domain
import org.moire.ultrasonic.domain.MusicDirectory.Album
import org.moire.ultrasonic.domain.MusicDirectory.Track
/**
* The result of a search. Contains matching artists, albums and songs.
*/

View File

@ -1,7 +1,6 @@
package org.moire.ultrasonic.domain
import java.io.Serializable
import org.moire.ultrasonic.domain.MusicDirectory.Track
data class Share(
override var id: String,

View File

@ -0,0 +1,65 @@
package org.moire.ultrasonic.domain
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
import java.util.Date
@Entity
data class Track(
@PrimaryKey override var id: String,
override var parent: String? = null,
override var isDirectory: Boolean = false,
override var title: String? = null,
override var album: String? = null,
var albumId: String? = null,
override var artist: String? = null,
override var artistId: String? = null,
var track: Int? = null,
override var year: Int? = null,
override var genre: String? = null,
var contentType: String? = null,
var suffix: String? = null,
var transcodedContentType: String? = null,
var transcodedSuffix: String? = null,
override var coverArt: String? = null,
var size: Long? = null,
override var songCount: Long? = null,
override var duration: Int? = null,
var bitRate: Int? = null,
override var path: String? = null,
override var isVideo: Boolean = false,
override var starred: Boolean = false,
override var discNumber: Int? = null,
var type: String? = null,
override var created: Date? = null,
override var closeness: Int = 0,
var bookmarkPosition: Int = 0,
var userRating: Int? = null,
var averageRating: Float? = null,
override var name: String? = null
) : Serializable, MusicDirectory.Child() {
fun setDuration(duration: Long) {
this.duration = duration.toInt()
}
companion object {
private const val serialVersionUID = -3339106650010798108L
}
fun compareTo(other: Track): 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 Track)
}

View File

@ -14,7 +14,7 @@ import android.widget.RemoteViews;
import org.moire.ultrasonic.R;
import org.moire.ultrasonic.activity.NavigationActivity;
import org.moire.ultrasonic.domain.MusicDirectory;
import org.moire.ultrasonic.domain.Track;
import org.moire.ultrasonic.imageloader.BitmapUtils;
import org.moire.ultrasonic.receiver.MediaButtonIntentReceiver;
import org.moire.ultrasonic.service.MediaPlayerController;
@ -73,7 +73,7 @@ public class UltrasonicAppWidgetProvider extends AppWidgetProvider
/**
* Handle a change notification coming over from {@link MediaPlayerController}
*/
public void notifyChange(Context context, MusicDirectory.Track currentSong, boolean playing, boolean setAlbum)
public void notifyChange(Context context, Track currentSong, boolean playing, boolean setAlbum)
{
if (hasInstances(context))
{
@ -100,7 +100,7 @@ public class UltrasonicAppWidgetProvider extends AppWidgetProvider
/**
* Update all active widget instances by pushing changes
*/
private void performUpdate(Context context, MusicDirectory.Track currentSong, boolean playing, boolean setAlbum)
private void performUpdate(Context context, Track currentSong, boolean playing, boolean setAlbum)
{
final Resources res = context.getResources();
final RemoteViews views = new RemoteViews(context.getPackageName(), this.layoutId);

View File

@ -6,7 +6,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import org.moire.ultrasonic.domain.MusicDirectory.Track;
import org.moire.ultrasonic.domain.Track;
import org.moire.ultrasonic.service.MediaPlayerController;
import kotlin.Lazy;

View File

@ -1,6 +1,6 @@
package org.moire.ultrasonic.service;
import org.moire.ultrasonic.domain.MusicDirectory;
import org.moire.ultrasonic.domain.Track;
import java.io.Serializable;
import java.util.ArrayList;
@ -13,7 +13,7 @@ public class State implements Serializable
{
public static final long serialVersionUID = -6346438781062572270L;
public List<MusicDirectory.Track> songs = new ArrayList<>();
public List<Track> songs = new ArrayList<>();
public int currentPlayingIndex;
public int currentPlayingPosition;
}

View File

@ -1,6 +1,6 @@
package org.moire.ultrasonic.util;
import org.moire.ultrasonic.domain.MusicDirectory;
import org.moire.ultrasonic.domain.Track;
import java.util.List;
@ -12,5 +12,5 @@ public class ShareDetails
public String Description;
public boolean ShareOnServer;
public long Expiration;
public List<MusicDirectory.Track> Entries;
public List<Track> Entries;
}

View File

@ -20,6 +20,7 @@ package org.moire.ultrasonic.util;
import org.moire.ultrasonic.data.ActiveServerProvider;
import org.moire.ultrasonic.domain.MusicDirectory;
import org.moire.ultrasonic.domain.Track;
import org.moire.ultrasonic.service.MusicService;
import org.moire.ultrasonic.service.MusicServiceFactory;
@ -40,7 +41,7 @@ public class ShufflePlayBuffer
private static final int CAPACITY = 50;
private static final int REFILL_THRESHOLD = 40;
private final List<MusicDirectory.Track> buffer = new ArrayList<>();
private final List<Track> buffer = new ArrayList<>();
private ScheduledExecutorService executorService;
private int currentServer;
@ -64,11 +65,11 @@ public class ShufflePlayBuffer
Timber.i("ShufflePlayBuffer destroyed");
}
public List<MusicDirectory.Track> get(int size)
public List<Track> get(int size)
{
clearBufferIfNecessary();
List<MusicDirectory.Track> result = new ArrayList<>(size);
List<Track> result = new ArrayList<>(size);
synchronized (buffer)
{
while (!buffer.isEmpty() && result.size() < size)

View File

@ -1,6 +1,6 @@
package org.moire.ultrasonic.util;
import org.moire.ultrasonic.domain.MusicDirectory;
import org.moire.ultrasonic.domain.Track;
import org.moire.ultrasonic.service.DownloadFile;
import org.moire.ultrasonic.service.Supplier;
@ -180,7 +180,7 @@ public class StreamProxy implements Runnable
{
Timber.i("Streaming song in background");
DownloadFile downloadFile = currentPlaying == null? null : currentPlaying.get();
MusicDirectory.Track song = downloadFile.getTrack();
Track song = downloadFile.getTrack();
long fileSize = downloadFile.getBitRate() * ((song.getDuration() != null) ? song.getDuration() : 0) * 1000 / 8;
Timber.i("Streaming fileSize: %d", fileSize);

View File

@ -20,7 +20,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.drakeet.multitype.ItemViewBinder
import org.koin.core.component.KoinComponent
import org.moire.ultrasonic.R
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Album
import org.moire.ultrasonic.imageloader.ImageLoader
import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
import org.moire.ultrasonic.util.Settings.shouldUseId3Tags
@ -31,11 +31,11 @@ import timber.log.Timber
* Creates a Row in a RecyclerView which contains the details of an Album
*/
class AlbumRowBinder(
val onItemClick: (MusicDirectory.Album) -> Unit,
val onContextMenuClick: (MenuItem, MusicDirectory.Album) -> Boolean,
val onItemClick: (Album) -> Unit,
val onContextMenuClick: (MenuItem, Album) -> Boolean,
private val imageLoader: ImageLoader,
context: Context
) : ItemViewBinder<MusicDirectory.Album, AlbumRowBinder.ViewHolder>(), KoinComponent {
) : ItemViewBinder<Album, AlbumRowBinder.ViewHolder>(), KoinComponent {
private val starDrawable: Drawable =
Util.getDrawableFromAttribute(context, R.attr.star_full)
@ -46,7 +46,7 @@ class AlbumRowBinder(
val layout = R.layout.list_item_album
val contextMenuLayout = R.menu.context_menu_artist
override fun onBindViewHolder(holder: ViewHolder, item: MusicDirectory.Album) {
override fun onBindViewHolder(holder: ViewHolder, item: Album) {
holder.album.text = item.title
holder.artist.text = item.artist
holder.details.setOnClickListener { onItemClick(item) }
@ -86,7 +86,7 @@ class AlbumRowBinder(
/**
* Handles the star / unstar action for an album
*/
private fun onStarClick(entry: MusicDirectory.Album, star: ImageView) {
private fun onStarClick(entry: Album, star: ImageView) {
entry.starred = !entry.starred
star.setImageDrawable(if (entry.starred) starDrawable else starHollowDrawable)
val musicService = getMusicService()

View File

@ -12,7 +12,7 @@ import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.moire.ultrasonic.R
import org.moire.ultrasonic.domain.Identifiable
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.service.DownloadFile
import org.moire.ultrasonic.service.Downloader
@ -45,7 +45,7 @@ class TrackViewBinder(
val diffAdapter = adapter as BaseAdapter<*>
when (item) {
is MusicDirectory.Track -> {
is Track -> {
downloadFile = downloader.getDownloadFileForSong(item)
}
is DownloadFile -> {

View File

@ -15,7 +15,7 @@ import io.reactivex.rxjava3.disposables.Disposable
import org.koin.core.component.KoinComponent
import org.moire.ultrasonic.R
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.service.DownloadFile
import org.moire.ultrasonic.service.DownloadStatus
import org.moire.ultrasonic.service.MusicServiceFactory
@ -44,7 +44,7 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
var duration: TextView = view.findViewById(R.id.song_duration)
var progress: TextView = view.findViewById(R.id.song_status)
var entry: MusicDirectory.Track? = null
var entry: Track? = null
private set
var downloadFile: DownloadFile? = null
private set
@ -131,7 +131,7 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
}
}
private fun setupStarButtons(song: MusicDirectory.Track, useFiveStarRating: Boolean) {
private fun setupStarButtons(song: Track, useFiveStarRating: Boolean) {
if (useFiveStarRating) {
// Hide single star
star.isVisible = false

View File

@ -4,8 +4,9 @@
package org.moire.ultrasonic.domain
import org.moire.ultrasonic.api.subsonic.models.Album
typealias DomainAlbum = org.moire.ultrasonic.domain.Album
fun Album.toDomainEntity(): MusicDirectory.Album = MusicDirectory.Album(
fun Album.toDomainEntity(): DomainAlbum = Album(
id = this@toDomainEntity.id,
title = this@toDomainEntity.name ?: this@toDomainEntity.title,
album = this@toDomainEntity.album,
@ -24,4 +25,4 @@ fun Album.toMusicDirectoryDomainEntity(): MusicDirectory = MusicDirectory().appl
addAll(this@toMusicDirectoryDomainEntity.songList.map { it.toTrackEntity() })
}
fun List<Album>.toDomainEntityList(): List<MusicDirectory.Album> = this.map { it.toDomainEntity() }
fun List<Album>.toDomainEntityList(): List<DomainAlbum> = this.map { it.toDomainEntity() }

View File

@ -24,6 +24,6 @@ fun APIArtist.toMusicDirectoryDomainEntity(): MusicDirectory = MusicDirectory().
addAll(this@toMusicDirectoryDomainEntity.albumsList.map { it.toDomainEntity() })
}
fun APIArtist.toDomainEntityList(): List<MusicDirectory.Album> {
fun APIArtist.toDomainEntityList(): List<Album> {
return this.albumsList.map { it.toDomainEntity() }
}

View File

@ -26,12 +26,12 @@ internal val dateFormat: DateFormat by lazy {
SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault())
}
fun MusicDirectoryChild.toTrackEntity(): MusicDirectory.Track = MusicDirectory.Track(id).apply {
fun MusicDirectoryChild.toTrackEntity(): Track = Track(id).apply {
populateCommonProps(this, this@toTrackEntity)
populateTrackProps(this, this@toTrackEntity)
}
fun MusicDirectoryChild.toAlbumEntity(): MusicDirectory.Album = MusicDirectory.Album(id).apply {
fun MusicDirectoryChild.toAlbumEntity(): Album = Album(id).apply {
populateCommonProps(this, this@toAlbumEntity)
}
@ -64,7 +64,7 @@ private fun populateCommonProps(
}
private fun populateTrackProps(
track: MusicDirectory.Track,
track: Track,
source: MusicDirectoryChild
) {
track.size = source.size
@ -93,7 +93,7 @@ fun List<MusicDirectoryChild>.toDomainEntityList(): List<MusicDirectory.Child> {
return newList
}
fun List<MusicDirectoryChild>.toTrackList(): List<MusicDirectory.Track> = this.map {
fun List<MusicDirectoryChild>.toTrackList(): List<Track> = this.map {
it.toTrackEntity()
}

View File

@ -15,14 +15,14 @@ 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.domain.MusicDirectory
import org.moire.ultrasonic.domain.Album
import org.moire.ultrasonic.model.AlbumListModel
import org.moire.ultrasonic.util.Constants
/**
* Displays a list of Albums from the media library
*/
class AlbumListFragment : EntryListFragment<MusicDirectory.Album>() {
class AlbumListFragment : EntryListFragment<Album>() {
/**
* The ViewModel to use to get the data
@ -45,7 +45,7 @@ class AlbumListFragment : EntryListFragment<MusicDirectory.Album>() {
override fun getLiveData(
args: Bundle?,
refresh: Boolean
): LiveData<List<MusicDirectory.Album>> {
): LiveData<List<Album>> {
if (args == null) throw IllegalArgumentException("Required arguments are missing")
val refresh2 = args.getBoolean(Constants.INTENT_REFRESH) || refresh
@ -83,7 +83,7 @@ class AlbumListFragment : EntryListFragment<MusicDirectory.Album>() {
emptyTextView.setText(R.string.select_album_empty)
}
override fun onItemClick(item: MusicDirectory.Album) {
override fun onItemClick(item: Album) {
val bundle = Bundle()
bundle.putString(Constants.INTENT_ID, item.id)
bundle.putBoolean(Constants.INTENT_IS_ALBUM, item.isDirectory)

View File

@ -15,6 +15,7 @@ import kotlinx.coroutines.launch
import org.moire.ultrasonic.R
import org.moire.ultrasonic.adapters.BaseAdapter
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle
/**
@ -61,7 +62,7 @@ class BookmarksFragment : TrackCollectionFragment() {
/**
* Custom playback function which uses the restore functionality. A bit of a hack..
*/
private fun playNow(songs: List<MusicDirectory.Track>) {
private fun playNow(songs: List<Track>) {
if (songs.isNotEmpty()) {
val position = songs[0].bookmarkPosition

View File

@ -66,9 +66,9 @@ import org.moire.ultrasonic.audiofx.EqualizerController
import org.moire.ultrasonic.audiofx.VisualizerController
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
import org.moire.ultrasonic.domain.Identifiable
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.PlayerState
import org.moire.ultrasonic.domain.RepeatMode
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle
import org.moire.ultrasonic.service.DownloadFile
import org.moire.ultrasonic.service.LocalMediaPlayer
@ -118,7 +118,7 @@ class PlayerFragment :
private val imageLoaderProvider: ImageLoaderProvider by inject()
private lateinit var executorService: ScheduledExecutorService
private var currentPlaying: DownloadFile? = null
private var currentSong: MusicDirectory.Track? = null
private var currentSong: Track? = null
private lateinit var viewManager: LinearLayoutManager
private var rxBusSubscription: Disposable? = null
private var ioScope = CoroutineScope(Dispatchers.IO)
@ -544,7 +544,7 @@ class PlayerFragment :
val downloadFile = viewAdapter.getCurrentList()[info!!.position] as DownloadFile
val menuInflater = requireActivity().menuInflater
menuInflater.inflate(R.menu.nowplaying_context, menu)
val song: MusicDirectory.Track?
val song: Track?
song = downloadFile.track
@ -571,7 +571,7 @@ class PlayerFragment :
@Suppress("ComplexMethod", "LongMethod", "ReturnCount")
private fun menuItemSelected(menuItemId: Int, song: DownloadFile?): Boolean {
var track: MusicDirectory.Track? = null
var track: Track? = null
val bundle: Bundle
if (song != null) {
track = song.track
@ -746,7 +746,7 @@ class PlayerFragment :
}
R.id.menu_item_share -> {
val mediaPlayerController = mediaPlayerController
val tracks: MutableList<MusicDirectory.Track?> = ArrayList()
val tracks: MutableList<Track?> = ArrayList()
val downloadServiceSongs = mediaPlayerController.playList
for (downloadFile in downloadServiceSongs) {
val playlistEntry = downloadFile.track
@ -758,7 +758,7 @@ class PlayerFragment :
R.id.menu_item_share_song -> {
if (currentSong == null) return true
val tracks: MutableList<MusicDirectory.Track?> = ArrayList()
val tracks: MutableList<Track?> = ArrayList()
tracks.add(currentSong)
shareHandler.createShare(this, tracks, null, cancellationToken)

View File

@ -24,12 +24,13 @@ import org.moire.ultrasonic.adapters.DividerBinder
import org.moire.ultrasonic.adapters.MoreButtonBinder
import org.moire.ultrasonic.adapters.MoreButtonBinder.MoreButton
import org.moire.ultrasonic.adapters.TrackViewBinder
import org.moire.ultrasonic.domain.Album
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.domain.Track
import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle
import org.moire.ultrasonic.model.SearchListModel
import org.moire.ultrasonic.service.DownloadFile
@ -199,7 +200,7 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
super.onDestroyView()
}
private fun downloadBackground(save: Boolean, songs: List<MusicDirectory.Track?>) {
private fun downloadBackground(save: Boolean, songs: List<Track?>) {
val onValid = Runnable {
networkAndStorageChecker.warnIfNetworkOrStorageUnavailable()
mediaPlayerController.downloadBackground(songs, save)
@ -287,7 +288,7 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
}
}
private fun onAlbumSelected(album: MusicDirectory.Album, autoplay: Boolean) {
private fun onAlbumSelected(album: Album, autoplay: Boolean) {
val bundle = Bundle()
bundle.putString(Constants.INTENT_ID, album.id)
bundle.putString(Constants.INTENT_NAME, album.title)
@ -296,7 +297,7 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
Navigation.findNavController(requireView()).navigate(R.id.searchToTrackCollection, bundle)
}
private fun onSongSelected(song: MusicDirectory.Track, append: Boolean) {
private fun onSongSelected(song: Track, append: Boolean) {
if (!append) {
mediaPlayerController.clear()
}
@ -312,7 +313,7 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
toast(context, resources.getQuantityString(R.plurals.select_album_n_songs_added, 1, 1))
}
private fun onVideoSelected(track: MusicDirectory.Track) {
private fun onVideoSelected(track: Track) {
playVideo(requireContext(), track)
}
@ -329,14 +330,14 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
is ArtistOrIndex -> {
onArtistSelected(item)
}
is MusicDirectory.Track -> {
is Track -> {
if (item.isVideo) {
onVideoSelected(item)
} else {
onSongSelected(item, true)
}
}
is MusicDirectory.Album -> {
is Album -> {
onAlbumSelected(item, false)
}
}
@ -356,7 +357,7 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
if (found || item !is DownloadFile) return true
val songs = mutableListOf<MusicDirectory.Track>()
val songs = mutableListOf<Track>()
when (menuItem.itemId) {
R.id.song_menu_play_now -> {

View File

@ -34,6 +34,7 @@ import org.moire.ultrasonic.adapters.TrackViewBinder
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
import org.moire.ultrasonic.domain.Identifiable
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle
import org.moire.ultrasonic.model.TrackCollectionModel
import org.moire.ultrasonic.service.MediaPlayerController
@ -46,7 +47,6 @@ import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.EntryByDiscAndTrackComparator
import org.moire.ultrasonic.util.Settings
import org.moire.ultrasonic.util.Util
import org.moire.ultrasonic.util.Util.toast
/**
* Displays a group of tracks, eg. the songs of an album, of a playlist etc.
@ -249,7 +249,7 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
private fun playNow(
append: Boolean,
selectedSongs: List<MusicDirectory.Track> = getSelectedSongs()
selectedSongs: List<Track> = getSelectedSongs()
) {
if (selectedSongs.isNotEmpty()) {
downloadHandler.download(
@ -314,10 +314,10 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
}
@Suppress("UNCHECKED_CAST")
private fun getAllSongs(): List<MusicDirectory.Track> {
private fun getAllSongs(): List<Track> {
return viewAdapter.getCurrentList().filter {
it is MusicDirectory.Track && !it.isDirectory
} as List<MusicDirectory.Track>
it is Track && !it.isDirectory
} as List<Track>
}
internal fun selectAllOrNone() {
@ -338,7 +338,7 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
}
}
internal open fun enableButtons(selection: List<MusicDirectory.Track> = getSelectedSongs()) {
internal open fun enableButtons(selection: List<Track> = getSelectedSongs()) {
val enabled = selection.isNotEmpty()
var unpinEnabled = false
var deleteEnabled = false
@ -378,7 +378,7 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
private fun downloadBackground(
save: Boolean,
songs: List<MusicDirectory.Track?>
songs: List<Track?>
) {
val onValid = Runnable {
networkAndStorageChecker.warnIfNetworkOrStorageUnavailable()
@ -403,7 +403,7 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
onValid.run()
}
internal fun delete(songs: List<MusicDirectory.Track> = getSelectedSongs()) {
internal fun delete(songs: List<Track> = getSelectedSongs()) {
Util.toast(
context,
resources.getQuantityString(
@ -414,7 +414,7 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
mediaPlayerController.delete(songs)
}
internal fun unpin(songs: List<MusicDirectory.Track> = getSelectedSongs()) {
internal fun unpin(songs: List<Track> = getSelectedSongs()) {
Util.toast(
context,
resources.getQuantityString(
@ -533,10 +533,10 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
}
}
internal fun getSelectedSongs(): List<MusicDirectory.Track> {
internal fun getSelectedSongs(): List<Track> {
// Walk through selected set and get the Entries based on the saved ids.
return viewAdapter.getCurrentList().mapNotNull {
if (it is MusicDirectory.Track && viewAdapter.isSelected(it.longId))
if (it is Track && viewAdapter.isSelected(it.longId))
it
else
null
@ -655,7 +655,7 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
playAll()
}
R.id.song_menu_share -> {
if (item is MusicDirectory.Track) {
if (item is Track) {
shareHandler.createShare(
this, listOf(item), refreshListView,
cancellationToken!!
@ -669,10 +669,10 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
return true
}
internal fun getClickedSong(item: MusicDirectory.Child): List<MusicDirectory.Track> {
internal fun getClickedSong(item: MusicDirectory.Child): List<Track> {
// This can probably be done better
return viewAdapter.getCurrentList().mapNotNull {
if (it is MusicDirectory.Track && (it.id == item.id))
if (it is Track && (it.id == item.id))
it
else
null
@ -692,7 +692,7 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
bundle
)
}
item is MusicDirectory.Track && item.isVideo -> {
item is Track && item.isVideo -> {
VideoPlayer.playVideo(requireContext(), item)
}
else -> {

View File

@ -4,7 +4,7 @@ import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Build
import java.io.File
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.util.FileUtil
import org.moire.ultrasonic.util.Util
import timber.log.Timber
@ -26,7 +26,7 @@ class BitmapUtils {
}
fun getAlbumArtBitmapFromDisk(
track: MusicDirectory.Track?,
track: Track?,
size: Int
): Bitmap? {
if (track == null) return null

View File

@ -20,6 +20,7 @@ import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient
import org.moire.ultrasonic.api.subsonic.throwOnFailure
import org.moire.ultrasonic.api.subsonic.toStreamResponse
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.util.FileUtil
import org.moire.ultrasonic.util.Util.safeClose
import timber.log.Timber
@ -148,7 +149,7 @@ class ImageLoader(
* Download a cover art file and cache it on disk
*/
fun cacheCoverArt(
track: MusicDirectory.Track
track: Track
) {
// Synchronize on the entry so that we don't download concurrently for

View File

@ -6,14 +6,14 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import org.moire.ultrasonic.api.subsonic.models.AlbumListType
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Album
import org.moire.ultrasonic.service.MusicService
import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.Settings
class AlbumListModel(application: Application) : GenericListModel(application) {
val list: MutableLiveData<List<MusicDirectory.Album>> = MutableLiveData()
val list: MutableLiveData<List<Album>> = MutableLiveData()
var lastType: String? = null
private var loadedUntil: Int = 0
@ -21,7 +21,7 @@ class AlbumListModel(application: Application) : GenericListModel(application) {
refresh: Boolean,
swipe: SwipeRefreshLayout,
args: Bundle
): LiveData<List<MusicDirectory.Album>> {
): LiveData<List<Album>> {
// Don't reload the data if navigating back to the view that was active before.
// This way, we keep the scroll position
val albumListType = args.getString(Constants.INTENT_ALBUM_LIST_TYPE)!!
@ -56,7 +56,7 @@ class AlbumListModel(application: Application) : GenericListModel(application) {
var offset = args.getInt(Constants.INTENT_ALBUM_LIST_OFFSET, 0)
val append = args.getBoolean(Constants.INTENT_APPEND, false)
val musicDirectory: List<MusicDirectory.Album>
val musicDirectory: List<Album>
val musicFolderId = if (showSelectFolderHeader(args)) {
activeServerProvider.getActiveServer().musicFolderId
} else {
@ -98,7 +98,7 @@ class AlbumListModel(application: Application) : GenericListModel(application) {
currentListIsSortable = isCollectionSortable(albumListType)
if (append && list.value != null) {
val newList = ArrayList<MusicDirectory.Album>()
val newList = ArrayList<Album>()
newList.addAll(list.value!!)
newList.addAll(musicDirectory)
list.postValue(newList)

View File

@ -25,6 +25,7 @@ import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.SearchCriteria
import org.moire.ultrasonic.domain.SearchResult
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.util.MediaSessionHandler
import org.moire.ultrasonic.util.Settings
import org.moire.ultrasonic.util.Util
@ -80,10 +81,10 @@ class AutoMediaBrowserService : MediaBrowserServiceCompat() {
private val serviceJob = Job()
private val serviceScope = CoroutineScope(Dispatchers.IO + serviceJob)
private var playlistCache: List<MusicDirectory.Track>? = null
private var starredSongsCache: List<MusicDirectory.Track>? = null
private var randomSongsCache: List<MusicDirectory.Track>? = null
private var searchSongsCache: List<MusicDirectory.Track>? = null
private var playlistCache: List<Track>? = null
private var starredSongsCache: List<Track>? = null
private var randomSongsCache: List<Track>? = null
private var searchSongsCache: List<Track>? = null
private val isOffline get() = ActiveServerProvider.isOffline()
private val useId3Tags get() = Settings.shouldUseId3Tags
@ -1070,7 +1071,7 @@ class AutoMediaBrowserService : MediaBrowserServiceCompat() {
return section.toString()
}
private fun playSongs(songs: List<MusicDirectory.Track?>?) {
private fun playSongs(songs: List<Track?>?) {
mediaPlayerController.addToPlaylist(
songs,
save = false,
@ -1081,7 +1082,7 @@ class AutoMediaBrowserService : MediaBrowserServiceCompat() {
)
}
private fun playSong(song: MusicDirectory.Track) {
private fun playSong(song: Track) {
mediaPlayerController.addToPlaylist(
listOf(song),
save = false,

View File

@ -13,6 +13,7 @@ import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.data.MetaDatabase
import org.moire.ultrasonic.domain.Album
import org.moire.ultrasonic.domain.Artist
import org.moire.ultrasonic.domain.Bookmark
import org.moire.ultrasonic.domain.ChatMessage
@ -27,6 +28,7 @@ import org.moire.ultrasonic.domain.PodcastsChannel
import org.moire.ultrasonic.domain.SearchCriteria
import org.moire.ultrasonic.domain.SearchResult
import org.moire.ultrasonic.domain.Share
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.domain.UserInfo
import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.LRUCache
@ -41,7 +43,7 @@ class CachedMusicService(private val musicService: MusicService) : MusicService,
// Old style TimeLimitedCache
private val cachedMusicDirectories: LRUCache<String, TimeLimitedCache<MusicDirectory?>>
private val cachedArtist: LRUCache<String, TimeLimitedCache<List<MusicDirectory.Album>>>
private val cachedArtist: LRUCache<String, TimeLimitedCache<List<Album>>>
private val cachedAlbum: LRUCache<String, TimeLimitedCache<MusicDirectory?>>
private val cachedUserInfo: LRUCache<String, TimeLimitedCache<UserInfo?>>
private val cachedLicenseValid = TimeLimitedCache<Boolean>(120, TimeUnit.SECONDS)
@ -149,7 +151,7 @@ class CachedMusicService(private val musicService: MusicService) : MusicService,
@Throws(Exception::class)
override fun getArtist(id: String, name: String?, refresh: Boolean):
List<MusicDirectory.Album> {
List<Album> {
checkSettingsChanged()
var cache = if (refresh) null else cachedArtist[id]
var dir = cache?.get()
@ -218,7 +220,7 @@ class CachedMusicService(private val musicService: MusicService) : MusicService,
}
@Throws(Exception::class)
override fun createPlaylist(id: String?, name: String?, tracks: List<MusicDirectory.Track>) {
override fun createPlaylist(id: String?, name: String?, tracks: List<Track>) {
cachedPlaylists.clear()
musicService.createPlaylist(id, name, tracks)
}
@ -249,7 +251,7 @@ class CachedMusicService(private val musicService: MusicService) : MusicService,
size: Int,
offset: Int,
musicFolderId: String?
): List<MusicDirectory.Album> {
): List<Album> {
return musicService.getAlbumList(type, size, offset, musicFolderId)
}
@ -259,7 +261,7 @@ class CachedMusicService(private val musicService: MusicService) : MusicService,
size: Int,
offset: Int,
musicFolderId: String?
): List<MusicDirectory.Album> {
): List<Album> {
return musicService.getAlbumList2(type, size, offset, musicFolderId)
}
@ -276,7 +278,7 @@ class CachedMusicService(private val musicService: MusicService) : MusicService,
@Throws(Exception::class)
override fun getDownloadInputStream(
song: MusicDirectory.Track,
song: Track,
offset: Long,
maxBitrate: Int,
save: Boolean

View File

@ -17,7 +17,7 @@ import org.koin.core.component.inject
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.domain.Artist
import org.moire.ultrasonic.domain.Identifiable
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
import org.moire.ultrasonic.subsonic.ImageLoaderProvider
import org.moire.ultrasonic.util.CacheCleaner
@ -38,7 +38,7 @@ import timber.log.Timber
*
*/
class DownloadFile(
val track: MusicDirectory.Track,
val track: Track,
save: Boolean
) : KoinComponent, Identifiable {
val partialFile: String

View File

@ -10,8 +10,8 @@ import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.PlayerState
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.util.LRUCache
import org.moire.ultrasonic.util.Settings
import org.moire.ultrasonic.util.ShufflePlayBuffer
@ -45,7 +45,7 @@ class Downloader(
private val jukeboxMediaPlayer: JukeboxMediaPlayer by inject()
// This cache helps us to avoid creating duplicate DownloadFile instances when showing Entries
private val downloadFileCache = LRUCache<MusicDirectory.Track, DownloadFile>(100)
private val downloadFileCache = LRUCache<Track, DownloadFile>(100)
private var executorService: ScheduledExecutorService? = null
private var wifiLock: WifiManager.WifiLock? = null
@ -345,7 +345,7 @@ class Downloader(
@Synchronized
fun addToPlaylist(
songs: List<MusicDirectory.Track>,
songs: List<Track>,
save: Boolean,
autoPlay: Boolean,
playNext: Boolean,
@ -407,7 +407,7 @@ class Downloader(
}
@Synchronized
fun downloadBackground(songs: List<MusicDirectory.Track>, save: Boolean) {
fun downloadBackground(songs: List<Track>, save: Boolean) {
// By using the counter we ensure that the songs are added in the correct order
for (song in songs) {
@ -435,7 +435,7 @@ class Downloader(
@Synchronized
@Suppress("ReturnCount")
fun getDownloadFileForSong(song: MusicDirectory.Track): DownloadFile {
fun getDownloadFileForSong(song: Track): DownloadFile {
for (downloadFile in playlist) {
if (downloadFile.track == song) {
return downloadFile
@ -513,7 +513,7 @@ class Downloader(
* Extension function
* Gathers the download file for a given song, and modifies shouldSave if provided.
*/
fun MusicDirectory.Track.getDownloadFile(save: Boolean? = null): DownloadFile {
fun Track.getDownloadFile(save: Boolean? = null): DownloadFile {
return getDownloadFileForSong(this).apply {
if (save != null) this.shouldSave = save
}

View File

@ -11,9 +11,9 @@ import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.moire.ultrasonic.app.UApp
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.PlayerState
import org.moire.ultrasonic.domain.RepeatMode
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.service.MediaPlayerService.Companion.executeOnStartedMediaPlayerService
import org.moire.ultrasonic.service.MediaPlayerService.Companion.getInstance
import org.moire.ultrasonic.service.MediaPlayerService.Companion.runningInstance
@ -65,7 +65,7 @@ class MediaPlayerController(
@Synchronized
fun restore(
songs: List<MusicDirectory.Track?>?,
songs: List<Track?>?,
currentPlayingIndex: Int,
currentPlayingPosition: Int,
autoPlay: Boolean,
@ -165,7 +165,7 @@ class MediaPlayerController(
@Synchronized
@Suppress("LongParameterList")
fun addToPlaylist(
songs: List<MusicDirectory.Track?>?,
songs: List<Track?>?,
save: Boolean,
autoPlay: Boolean,
playNext: Boolean,
@ -202,7 +202,7 @@ class MediaPlayerController(
}
@Synchronized
fun downloadBackground(songs: List<MusicDirectory.Track?>?, save: Boolean) {
fun downloadBackground(songs: List<Track?>?, save: Boolean) {
if (songs == null) return
val filteredSongs = songs.filterNotNull()
downloader.downloadBackground(filteredSongs, save)
@ -325,7 +325,7 @@ class MediaPlayerController(
@Synchronized
// TODO: Make it require not null
fun delete(songs: List<MusicDirectory.Track?>) {
fun delete(songs: List<Track?>) {
for (song in songs.filterNotNull()) {
downloader.getDownloadFileForSong(song).delete()
}
@ -333,7 +333,7 @@ class MediaPlayerController(
@Synchronized
// TODO: Make it require not null
fun unpin(songs: List<MusicDirectory.Track?>) {
fun unpin(songs: List<Track?>) {
for (song in songs.filterNotNull()) {
downloader.getDownloadFileForSong(song).unpin()
}
@ -509,7 +509,7 @@ class MediaPlayerController(
val playListDuration: Long
get() = downloader.downloadListDuration
fun getDownloadFileForSong(song: MusicDirectory.Track): DownloadFile {
fun getDownloadFileForSong(song: Track): DownloadFile {
return downloader.getDownloadFileForSong(song)
}

View File

@ -28,9 +28,9 @@ import org.koin.android.ext.android.inject
import org.moire.ultrasonic.R
import org.moire.ultrasonic.activity.NavigationActivity
import org.moire.ultrasonic.app.UApp
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.PlayerState
import org.moire.ultrasonic.domain.RepeatMode
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.imageloader.BitmapUtils
import org.moire.ultrasonic.provider.UltrasonicAppWidgetProvider4X1
import org.moire.ultrasonic.provider.UltrasonicAppWidgetProvider4X2
@ -340,7 +340,7 @@ class MediaPlayerService : Service() {
localMediaPlayer.setPlayerState(PlayerState.STARTED, localMediaPlayer.currentPlaying)
}
private fun updateWidget(playerState: PlayerState, song: MusicDirectory.Track?) {
private fun updateWidget(playerState: PlayerState, song: Track?) {
val started = playerState === PlayerState.STARTED
val context = this@MediaPlayerService
@ -589,7 +589,7 @@ class MediaPlayerService : Service() {
context: Context,
notificationBuilder: NotificationCompat.Builder,
playerState: PlayerState,
song: MusicDirectory.Track?
song: Track?
): IntArray {
// Init
val compactActionList = ArrayList<Int>()

View File

@ -7,6 +7,7 @@
package org.moire.ultrasonic.service
import java.io.InputStream
import org.moire.ultrasonic.domain.Album
import org.moire.ultrasonic.domain.Artist
import org.moire.ultrasonic.domain.Bookmark
import org.moire.ultrasonic.domain.ChatMessage
@ -21,6 +22,7 @@ import org.moire.ultrasonic.domain.PodcastsChannel
import org.moire.ultrasonic.domain.SearchCriteria
import org.moire.ultrasonic.domain.SearchResult
import org.moire.ultrasonic.domain.Share
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.domain.UserInfo
@Suppress("TooManyFunctions")
@ -57,7 +59,7 @@ interface MusicService {
fun getMusicDirectory(id: String, name: String?, refresh: Boolean): MusicDirectory
@Throws(Exception::class)
fun getArtist(id: String, name: String?, refresh: Boolean): List<MusicDirectory.Album>
fun getArtist(id: String, name: String?, refresh: Boolean): List<Album>
@Throws(Exception::class)
fun getAlbum(id: String, name: String?, refresh: Boolean): MusicDirectory
@ -75,7 +77,7 @@ interface MusicService {
fun getPlaylists(refresh: Boolean): List<Playlist>
@Throws(Exception::class)
fun createPlaylist(id: String?, name: String?, tracks: List<MusicDirectory.Track>)
fun createPlaylist(id: String?, name: String?, tracks: List<Track>)
@Throws(Exception::class)
fun deletePlaylist(id: String)
@ -95,7 +97,7 @@ interface MusicService {
size: Int,
offset: Int,
musicFolderId: String?
): List<MusicDirectory.Album>
): List<Album>
@Throws(Exception::class)
fun getAlbumList2(
@ -103,7 +105,7 @@ interface MusicService {
size: Int,
offset: Int,
musicFolderId: String?
): List<MusicDirectory.Album>
): List<Album>
@Throws(Exception::class)
fun getRandomSongs(size: Int): MusicDirectory
@ -123,7 +125,7 @@ interface MusicService {
*/
@Throws(Exception::class)
fun getDownloadInputStream(
song: MusicDirectory.Track,
song: Track,
offset: Long,
maxBitrate: Int,
save: Boolean

View File

@ -23,6 +23,7 @@ import java.util.regex.Pattern
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.domain.Album
import org.moire.ultrasonic.domain.Artist
import org.moire.ultrasonic.domain.ArtistOrIndex
import org.moire.ultrasonic.domain.Bookmark
@ -38,6 +39,7 @@ import org.moire.ultrasonic.domain.PodcastsChannel
import org.moire.ultrasonic.domain.SearchCriteria
import org.moire.ultrasonic.domain.SearchResult
import org.moire.ultrasonic.domain.Share
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.domain.UserInfo
import org.moire.ultrasonic.util.AbstractFile
import org.moire.ultrasonic.util.Constants
@ -126,8 +128,8 @@ class OfflineMusicService : MusicService, KoinComponent {
override fun search(criteria: SearchCriteria): SearchResult {
val artists: MutableList<ArtistOrIndex> = ArrayList()
val albums: MutableList<MusicDirectory.Album> = ArrayList()
val songs: MutableList<MusicDirectory.Track> = ArrayList()
val albums: MutableList<Album> = ArrayList()
val songs: MutableList<Track> = ArrayList()
val root = FileUtil.musicDirectory
var closeness: Int
for (artistFile in FileUtil.listFiles(root)) {
@ -227,7 +229,7 @@ class OfflineMusicService : MusicService, KoinComponent {
@Suppress("TooGenericExceptionCaught")
@Throws(Exception::class)
override fun createPlaylist(id: String?, name: String?, tracks: List<MusicDirectory.Track>) {
override fun createPlaylist(id: String?, name: String?, tracks: List<Track>) {
val playlistFile =
FileUtil.getPlaylistFile(activeServerProvider.getActiveServer().name, name)
val fw = FileWriter(playlistFile)
@ -299,7 +301,7 @@ class OfflineMusicService : MusicService, KoinComponent {
size: Int,
offset: Int,
musicFolderId: String?
): List<MusicDirectory.Album> {
): List<Album> {
throw OfflineException("Album lists not available in offline mode")
}
@ -309,7 +311,7 @@ class OfflineMusicService : MusicService, KoinComponent {
size: Int,
offset: Int,
musicFolderId: String?
): List<MusicDirectory.Album> {
): List<Album> {
throw OfflineException("getAlbumList2 isn't available in offline mode")
}
@ -455,7 +457,7 @@ class OfflineMusicService : MusicService, KoinComponent {
@Throws(OfflineException::class)
override fun getArtist(id: String, name: String?, refresh: Boolean):
List<MusicDirectory.Album> {
List<Album> {
throw OfflineException("getArtist isn't available in offline mode")
}
@ -471,7 +473,7 @@ class OfflineMusicService : MusicService, KoinComponent {
@Throws(OfflineException::class)
override fun getDownloadInputStream(
song: MusicDirectory.Track,
song: Track,
offset: Long,
maxBitrate: Int,
save: Boolean
@ -502,14 +504,14 @@ class OfflineMusicService : MusicService, KoinComponent {
return FileUtil.getBaseName(name)
}
private fun createEntry(file: AbstractFile, name: String?): MusicDirectory.Track {
val entry = MusicDirectory.Track(file.path)
private fun createEntry(file: AbstractFile, name: String?): Track {
val entry = Track(file.path)
entry.populateWithDataFrom(file, name)
return entry
}
private fun createAlbum(file: AbstractFile, name: String?): MusicDirectory.Album {
val album = MusicDirectory.Album(file.path)
private fun createAlbum(file: AbstractFile, name: String?): Album {
val album = Album(file.path)
album.populateWithDataFrom(file, name)
return album
}
@ -536,7 +538,7 @@ class OfflineMusicService : MusicService, KoinComponent {
* More extensive variant of Child.populateWithDataFrom(), which also parses the ID3 tags of
* a given track file.
*/
private fun MusicDirectory.Track.populateWithDataFrom(file: AbstractFile, name: String?) {
private fun Track.populateWithDataFrom(file: AbstractFile, name: String?) {
(this as MusicDirectory.Child).populateWithDataFrom(file, name)
val meta = RawMetadata(null)
@ -609,8 +611,8 @@ class OfflineMusicService : MusicService, KoinComponent {
artistName: String,
file: AbstractFile,
criteria: SearchCriteria,
albums: MutableList<MusicDirectory.Album>,
songs: MutableList<MusicDirectory.Track>
albums: MutableList<Album>,
songs: MutableList<Track>
) {
var closeness: Int
for (albumFile in FileUtil.listMediaFiles(file)) {

View File

@ -19,6 +19,7 @@ import org.moire.ultrasonic.api.subsonic.throwOnFailure
import org.moire.ultrasonic.api.subsonic.toStreamResponse
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
import org.moire.ultrasonic.domain.Album
import org.moire.ultrasonic.domain.Artist
import org.moire.ultrasonic.domain.Bookmark
import org.moire.ultrasonic.domain.ChatMessage
@ -33,6 +34,7 @@ import org.moire.ultrasonic.domain.PodcastsChannel
import org.moire.ultrasonic.domain.SearchCriteria
import org.moire.ultrasonic.domain.SearchResult
import org.moire.ultrasonic.domain.Share
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.domain.UserInfo
import org.moire.ultrasonic.domain.toArtistList
import org.moire.ultrasonic.domain.toDomainEntitiesList
@ -143,7 +145,7 @@ open class RESTMusicService(
id: String,
name: String?,
refresh: Boolean
): List<MusicDirectory.Album> {
): List<Album> {
val response = API.getArtist(id).execute().throwOnFailure()
return response.body()!!.artist.toDomainEntityList()
@ -262,7 +264,7 @@ open class RESTMusicService(
override fun createPlaylist(
id: String?,
name: String?,
tracks: List<MusicDirectory.Track>
tracks: List<Track>
) {
if (id == null && name == null)
throw IllegalArgumentException("Either id or name is required.")
@ -350,7 +352,7 @@ open class RESTMusicService(
size: Int,
offset: Int,
musicFolderId: String?
): List<MusicDirectory.Album> {
): List<Album> {
val response = API.getAlbumList(
fromName(type),
size,
@ -370,7 +372,7 @@ open class RESTMusicService(
size: Int,
offset: Int,
musicFolderId: String?
): List<MusicDirectory.Album> {
): List<Album> {
val response = API.getAlbumList2(
fromName(type),
size,
@ -418,7 +420,7 @@ open class RESTMusicService(
@Throws(Exception::class)
override fun getDownloadInputStream(
song: MusicDirectory.Track,
song: Track,
offset: Long,
maxBitrate: Int,
save: Boolean

View File

@ -8,6 +8,7 @@ import java.util.LinkedList
import org.moire.ultrasonic.R
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.service.MediaPlayerController
import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
import org.moire.ultrasonic.util.Constants
@ -33,7 +34,7 @@ class DownloadHandler(
autoPlay: Boolean,
playNext: Boolean,
shuffle: Boolean,
songs: List<MusicDirectory.Track?>
songs: List<Track?>
) {
val onValid = Runnable {
if (!append && !playNext) {
@ -195,15 +196,15 @@ class DownloadHandler(
isArtist: Boolean
) {
val activity = fragment.activity as Activity
val task = object : ModalBackgroundTask<List<MusicDirectory.Track>>(
val task = object : ModalBackgroundTask<List<Track>>(
activity,
false
) {
@Throws(Throwable::class)
override fun doInBackground(): List<MusicDirectory.Track> {
override fun doInBackground(): List<Track> {
val musicService = getMusicService()
val songs: MutableList<MusicDirectory.Track> = LinkedList()
val songs: MutableList<Track> = LinkedList()
val root: MusicDirectory
if (!isOffline() && isArtist && Settings.shouldUseId3Tags) {
getSongsForArtist(id, songs)
@ -235,7 +236,7 @@ class DownloadHandler(
@Throws(Exception::class)
private fun getSongsRecursively(
parent: MusicDirectory,
songs: MutableList<MusicDirectory.Track>
songs: MutableList<Track>
) {
if (songs.size > maxSongs) {
return
@ -259,7 +260,7 @@ class DownloadHandler(
@Throws(Exception::class)
private fun getSongsForArtist(
id: String,
songs: MutableCollection<MusicDirectory.Track>
songs: MutableCollection<Track>
) {
if (songs.size > maxSongs) {
return
@ -280,7 +281,7 @@ class DownloadHandler(
}
}
override fun done(songs: List<MusicDirectory.Track>) {
override fun done(songs: List<Track>) {
if (Settings.shouldSortByDisc) {
Collections.sort(songs, EntryByDiscAndTrackComparator())
}

View File

@ -15,8 +15,8 @@ import java.util.Locale
import java.util.regex.Pattern
import kotlin.collections.ArrayList
import org.moire.ultrasonic.R
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Share
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
import org.moire.ultrasonic.util.BackgroundTask
import org.moire.ultrasonic.util.CancellationToken
@ -44,7 +44,7 @@ class ShareHandler(val context: Context) {
fun createShare(
fragment: Fragment,
tracks: List<MusicDirectory.Track?>?,
tracks: List<Track?>?,
swipe: SwipeRefreshLayout?,
cancellationToken: CancellationToken
) {

View File

@ -4,7 +4,7 @@ import android.content.Context
import android.content.Intent
import android.net.Uri
import org.moire.ultrasonic.R
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.service.MusicServiceFactory
import org.moire.ultrasonic.util.Util
@ -14,7 +14,7 @@ import org.moire.ultrasonic.util.Util
@Suppress("UtilityClassWithPublicConstructor")
class VideoPlayer {
companion object {
fun playVideo(context: Context, track: MusicDirectory.Track?) {
fun playVideo(context: Context, track: Track?) {
if (!Util.isNetworkConnected() || track == null) {
Util.toast(context, R.string.select_album_no_network)
return

View File

@ -2,13 +2,14 @@ package org.moire.ultrasonic.util
import java.util.Comparator
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Track
class EntryByDiscAndTrackComparator : Comparator<MusicDirectory.Child> {
override fun compare(x: MusicDirectory.Child, y: MusicDirectory.Child): Int {
val discX = x.discNumber
val discY = y.discNumber
val trackX = if (x is MusicDirectory.Track) x.track else null
val trackY = if (y is MusicDirectory.Track) y.track else null
val trackX = if (x is Track) x.track else null
val trackY = if (y is Track) y.track else null
val albumX = x.album
val albumY = y.album
val pathX = x.path

View File

@ -27,6 +27,7 @@ import java.util.TreeSet
import java.util.regex.Pattern
import org.moire.ultrasonic.app.UApp
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.util.Util.safeClose
import timber.log.Timber
@ -49,7 +50,7 @@ object FileUtil {
const val SUFFIX_SMALL = ".jpeg-small"
private const val UNNAMED = "unnamed"
fun getSongFile(song: MusicDirectory.Track): String {
fun getSongFile(song: Track): String {
val dir = getAlbumDirectory(song)
// Do not generate new name for offline files. Offline files will have their Path as their Id.

View File

@ -55,6 +55,7 @@ import org.moire.ultrasonic.domain.Bookmark
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.PlayerState
import org.moire.ultrasonic.domain.SearchResult
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.service.DownloadFile
import timber.log.Timber
@ -438,7 +439,7 @@ object Util {
@JvmStatic
fun getSongsFromBookmarks(bookmarks: Iterable<Bookmark>): MusicDirectory {
val musicDirectory = MusicDirectory()
var song: MusicDirectory.Track
var song: Track
for (bookmark in bookmarks) {
song = bookmark.track
song.bookmarkPosition = bookmark.position
@ -450,7 +451,7 @@ object Util {
/**
* Broadcasts the given song info as the new song being played.
*/
fun broadcastNewTrackInfo(context: Context, song: MusicDirectory.Track?) {
fun broadcastNewTrackInfo(context: Context, song: Track?) {
val intent = Intent(EVENT_META_CHANGED)
if (song != null) {
intent.putExtra("title", song.title)
@ -476,7 +477,7 @@ object Util {
) {
if (!Settings.shouldSendBluetoothNotifications) return
var song: MusicDirectory.Track? = null
var song: Track? = null
val avrcpIntent = Intent(CM_AVRCP_METADATA_CHANGED)
if (currentPlaying != null) song = currentPlaying.track
@ -489,7 +490,7 @@ object Util {
fun broadcastA2dpPlayStatusChange(
context: Context,
state: PlayerState?,
newSong: MusicDirectory.Track?,
newSong: Track?,
listSize: Int,
id: Int,
playerPosition: Int
@ -520,7 +521,7 @@ object Util {
private fun fillIntent(
intent: Intent,
song: MusicDirectory.Track?,
song: Track?,
playerPosition: Int,
id: Int,
listSize: Int
@ -776,7 +777,7 @@ object Util {
)
fun getMediaDescriptionForEntry(
song: MusicDirectory.Track,
song: Track,
mediaId: String? = null,
groupNameId: Int? = null
): MediaDescriptionCompat {
@ -809,7 +810,7 @@ object Util {
}
@Suppress("ComplexMethod", "LongMethod")
fun readableEntryDescription(song: MusicDirectory.Track): ReadableEntryDescription {
fun readableEntryDescription(song: Track): ReadableEntryDescription {
val artist = StringBuilder(LINE_LENGTH)
var bitRate: String? = null
var trackText = ""