Browse Source

Merge branch 'housekeeping/upgrade-android-gradle-plugin-and-cleanup' into 'develop'

Upgrading Android Gradle Plugin

See merge request funkwhale/funkwhale-android!72
deploy-in-docker
Ryan Harg 3 years ago
parent
commit
5125098ea4
  1. 1
      app/src/main/java/audio/funkwhale/ffa/activities/MainActivity.kt
  2. 2
      app/src/main/java/audio/funkwhale/ffa/activities/SearchActivity.kt
  3. 2
      app/src/main/java/audio/funkwhale/ffa/adapters/AlbumsAdapter.kt
  4. 2
      app/src/main/java/audio/funkwhale/ffa/adapters/AlbumsGridAdapter.kt
  5. 2
      app/src/main/java/audio/funkwhale/ffa/adapters/ArtistsAdapter.kt
  6. 4
      app/src/main/java/audio/funkwhale/ffa/adapters/DownloadsAdapter.kt
  7. 2
      app/src/main/java/audio/funkwhale/ffa/adapters/FavoritesAdapter.kt
  8. 4
      app/src/main/java/audio/funkwhale/ffa/adapters/PlaylistTracksAdapter.kt
  9. 2
      app/src/main/java/audio/funkwhale/ffa/adapters/PlaylistsAdapter.kt
  10. 2
      app/src/main/java/audio/funkwhale/ffa/adapters/RadiosAdapter.kt
  11. 6
      app/src/main/java/audio/funkwhale/ffa/adapters/SearchAdapter.kt
  12. 2
      app/src/main/java/audio/funkwhale/ffa/adapters/TracksAdapter.kt
  13. 2
      app/src/main/java/audio/funkwhale/ffa/fragments/AddToPlaylistDialog.kt
  14. 2
      app/src/main/java/audio/funkwhale/ffa/fragments/AlbumsFragment.kt
  15. 2
      app/src/main/java/audio/funkwhale/ffa/fragments/AlbumsGridFragment.kt
  16. 2
      app/src/main/java/audio/funkwhale/ffa/fragments/ArtistsFragment.kt
  17. 1
      app/src/main/java/audio/funkwhale/ffa/fragments/FavoritesFragment.kt
  18. 6
      app/src/main/java/audio/funkwhale/ffa/fragments/PlaylistTracksFragment.kt
  19. 2
      app/src/main/java/audio/funkwhale/ffa/fragments/PlaylistsFragment.kt
  20. 2
      app/src/main/java/audio/funkwhale/ffa/fragments/RadiosFragment.kt
  21. 2
      app/src/main/java/audio/funkwhale/ffa/fragments/TrackInfoDetailsFragment.kt
  22. 2
      app/src/main/java/audio/funkwhale/ffa/fragments/TracksFragment.kt
  23. 17
      app/src/main/java/audio/funkwhale/ffa/model/Album.kt
  24. 9
      app/src/main/java/audio/funkwhale/ffa/model/AlbumsResponse.kt
  25. 16
      app/src/main/java/audio/funkwhale/ffa/model/Artist.kt
  26. 9
      app/src/main/java/audio/funkwhale/ffa/model/ArtistsResponse.kt
  27. 12
      app/src/main/java/audio/funkwhale/ffa/model/CacheItem.kt
  28. 3
      app/src/main/java/audio/funkwhale/ffa/model/CoverUrls.kt
  29. 3
      app/src/main/java/audio/funkwhale/ffa/model/Covers.kt
  30. 11
      app/src/main/java/audio/funkwhale/ffa/model/DownloadInfo.kt
  31. 8
      app/src/main/java/audio/funkwhale/ffa/model/FFAResponse.kt
  32. 3
      app/src/main/java/audio/funkwhale/ffa/model/Favorited.kt
  33. 9
      app/src/main/java/audio/funkwhale/ffa/model/FavoritedResponse.kt
  34. 9
      app/src/main/java/audio/funkwhale/ffa/model/Playlist.kt
  35. 3
      app/src/main/java/audio/funkwhale/ffa/model/PlaylistTrack.kt
  36. 9
      app/src/main/java/audio/funkwhale/ffa/model/PlaylistTracksResponse.kt
  37. 9
      app/src/main/java/audio/funkwhale/ffa/model/PlaylistsResponse.kt
  38. 9
      app/src/main/java/audio/funkwhale/ffa/model/Radio.kt
  39. 9
      app/src/main/java/audio/funkwhale/ffa/model/RadiosResponse.kt
  40. 7
      app/src/main/java/audio/funkwhale/ffa/model/SearchResult.kt
  41. 64
      app/src/main/java/audio/funkwhale/ffa/model/Track.kt
  42. 9
      app/src/main/java/audio/funkwhale/ffa/model/TracksResponse.kt
  43. 5
      app/src/main/java/audio/funkwhale/ffa/model/User.kt
  44. 24
      app/src/main/java/audio/funkwhale/ffa/playback/CacheDataSourceFactoryProvider.kt
  45. 2
      app/src/main/java/audio/funkwhale/ffa/playback/MediaControlsManager.kt
  46. 4
      app/src/main/java/audio/funkwhale/ffa/playback/MediaSession.kt
  47. 2
      app/src/main/java/audio/funkwhale/ffa/playback/PinService.kt
  48. 2
      app/src/main/java/audio/funkwhale/ffa/playback/PlayerService.kt
  49. 3
      app/src/main/java/audio/funkwhale/ffa/playback/QueueManager.kt
  50. 2
      app/src/main/java/audio/funkwhale/ffa/playback/RadioPlayer.kt
  51. 6
      app/src/main/java/audio/funkwhale/ffa/repositories/AlbumsRepository.kt
  52. 8
      app/src/main/java/audio/funkwhale/ffa/repositories/ArtistTracksRepository.kt
  53. 8
      app/src/main/java/audio/funkwhale/ffa/repositories/ArtistsRepository.kt
  54. 5
      app/src/main/java/audio/funkwhale/ffa/repositories/FavoritesRepository.kt
  55. 5
      app/src/main/java/audio/funkwhale/ffa/repositories/HttpUpstream.kt
  56. 8
      app/src/main/java/audio/funkwhale/ffa/repositories/PlaylistTracksRepository.kt
  57. 10
      app/src/main/java/audio/funkwhale/ffa/repositories/PlaylistsRepository.kt
  58. 8
      app/src/main/java/audio/funkwhale/ffa/repositories/RadiosRepository.kt
  59. 2
      app/src/main/java/audio/funkwhale/ffa/repositories/Repository.kt
  60. 1
      app/src/main/java/audio/funkwhale/ffa/repositories/SearchRepository.kt
  61. 10
      app/src/main/java/audio/funkwhale/ffa/repositories/TracksRepository.kt
  62. 2
      app/src/main/java/audio/funkwhale/ffa/utils/Bus.kt
  63. 3
      app/src/main/java/audio/funkwhale/ffa/utils/Extensions.kt
  64. 3
      app/src/main/java/audio/funkwhale/ffa/utils/FFACache.kt
  65. 213
      app/src/main/java/audio/funkwhale/ffa/utils/Models.kt
  66. 1
      app/src/main/java/audio/funkwhale/ffa/utils/RefreshError.kt
  67. 1
      app/src/main/java/audio/funkwhale/ffa/utils/Userinfo.kt
  68. 2
      build.gradle.kts
  69. 1
      buildSrc/src/main/java/Versions.kt

1
app/src/main/java/audio/funkwhale/ffa/activities/MainActivity.kt

@ -25,6 +25,7 @@ import audio.funkwhale.ffa.FFA
import audio.funkwhale.ffa.R import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.databinding.ActivityMainBinding import audio.funkwhale.ffa.databinding.ActivityMainBinding
import audio.funkwhale.ffa.fragments.* import audio.funkwhale.ffa.fragments.*
import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.playback.MediaControlsManager import audio.funkwhale.ffa.playback.MediaControlsManager
import audio.funkwhale.ffa.playback.PinService import audio.funkwhale.ffa.playback.PinService
import audio.funkwhale.ffa.playback.PlayerService import audio.funkwhale.ffa.playback.PlayerService

2
app/src/main/java/audio/funkwhale/ffa/activities/SearchActivity.kt

@ -11,6 +11,8 @@ import audio.funkwhale.ffa.databinding.ActivitySearchBinding
import audio.funkwhale.ffa.fragments.AddToPlaylistDialog import audio.funkwhale.ffa.fragments.AddToPlaylistDialog
import audio.funkwhale.ffa.fragments.AlbumsFragment import audio.funkwhale.ffa.fragments.AlbumsFragment
import audio.funkwhale.ffa.fragments.ArtistsFragment import audio.funkwhale.ffa.fragments.ArtistsFragment
import audio.funkwhale.ffa.model.Album
import audio.funkwhale.ffa.model.Artist
import audio.funkwhale.ffa.repositories.* import audio.funkwhale.ffa.repositories.*
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.utils.*
import com.google.android.exoplayer2.offline.Download import com.google.android.exoplayer2.offline.Download

2
app/src/main/java/audio/funkwhale/ffa/adapters/AlbumsAdapter.kt

@ -7,7 +7,7 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import audio.funkwhale.ffa.databinding.RowAlbumBinding import audio.funkwhale.ffa.databinding.RowAlbumBinding
import audio.funkwhale.ffa.fragments.FFAAdapter import audio.funkwhale.ffa.fragments.FFAAdapter
import audio.funkwhale.ffa.utils.Album import audio.funkwhale.ffa.model.Album
import audio.funkwhale.ffa.utils.maybeLoad import audio.funkwhale.ffa.utils.maybeLoad
import audio.funkwhale.ffa.utils.maybeNormalizeUrl import audio.funkwhale.ffa.utils.maybeNormalizeUrl
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso

2
app/src/main/java/audio/funkwhale/ffa/adapters/AlbumsGridAdapter.kt

@ -7,7 +7,7 @@ import androidx.recyclerview.widget.RecyclerView
import audio.funkwhale.ffa.R import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.databinding.RowAlbumGridBinding import audio.funkwhale.ffa.databinding.RowAlbumGridBinding
import audio.funkwhale.ffa.fragments.FFAAdapter import audio.funkwhale.ffa.fragments.FFAAdapter
import audio.funkwhale.ffa.utils.Album import audio.funkwhale.ffa.model.Album
import audio.funkwhale.ffa.utils.maybeLoad import audio.funkwhale.ffa.utils.maybeLoad
import audio.funkwhale.ffa.utils.maybeNormalizeUrl import audio.funkwhale.ffa.utils.maybeNormalizeUrl
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso

2
app/src/main/java/audio/funkwhale/ffa/adapters/ArtistsAdapter.kt

@ -8,7 +8,7 @@ import androidx.recyclerview.widget.RecyclerView
import audio.funkwhale.ffa.R import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.databinding.RowArtistBinding import audio.funkwhale.ffa.databinding.RowArtistBinding
import audio.funkwhale.ffa.fragments.FFAAdapter import audio.funkwhale.ffa.fragments.FFAAdapter
import audio.funkwhale.ffa.utils.Artist import audio.funkwhale.ffa.model.Artist
import audio.funkwhale.ffa.utils.maybeLoad import audio.funkwhale.ffa.utils.maybeLoad
import audio.funkwhale.ffa.utils.maybeNormalizeUrl import audio.funkwhale.ffa.utils.maybeNormalizeUrl
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso

4
app/src/main/java/audio/funkwhale/ffa/adapters/DownloadsAdapter.kt

@ -9,8 +9,8 @@ import androidx.recyclerview.widget.RecyclerView
import audio.funkwhale.ffa.R import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.databinding.RowDownloadBinding import audio.funkwhale.ffa.databinding.RowDownloadBinding
import audio.funkwhale.ffa.playback.PinService import audio.funkwhale.ffa.playback.PinService
import audio.funkwhale.ffa.utils.DownloadInfo import audio.funkwhale.ffa.model.DownloadInfo
import audio.funkwhale.ffa.utils.Track import audio.funkwhale.ffa.model.Track
import com.google.android.exoplayer2.offline.Download import com.google.android.exoplayer2.offline.Download
import com.google.android.exoplayer2.offline.DownloadService import com.google.android.exoplayer2.offline.DownloadService

2
app/src/main/java/audio/funkwhale/ffa/adapters/FavoritesAdapter.kt

@ -15,7 +15,7 @@ import audio.funkwhale.ffa.databinding.RowTrackBinding
import audio.funkwhale.ffa.fragments.FFAAdapter import audio.funkwhale.ffa.fragments.FFAAdapter
import audio.funkwhale.ffa.utils.Command import audio.funkwhale.ffa.utils.Command
import audio.funkwhale.ffa.utils.CommandBus import audio.funkwhale.ffa.utils.CommandBus
import audio.funkwhale.ffa.utils.Track import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.utils.maybeLoad import audio.funkwhale.ffa.utils.maybeLoad
import audio.funkwhale.ffa.utils.maybeNormalizeUrl import audio.funkwhale.ffa.utils.maybeNormalizeUrl
import audio.funkwhale.ffa.utils.toast import audio.funkwhale.ffa.utils.toast

4
app/src/main/java/audio/funkwhale/ffa/adapters/PlaylistTracksAdapter.kt

@ -18,8 +18,8 @@ import audio.funkwhale.ffa.databinding.RowTrackBinding
import audio.funkwhale.ffa.fragments.FFAAdapter import audio.funkwhale.ffa.fragments.FFAAdapter
import audio.funkwhale.ffa.utils.Command import audio.funkwhale.ffa.utils.Command
import audio.funkwhale.ffa.utils.CommandBus import audio.funkwhale.ffa.utils.CommandBus
import audio.funkwhale.ffa.utils.PlaylistTrack import audio.funkwhale.ffa.model.PlaylistTrack
import audio.funkwhale.ffa.utils.Track import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.utils.maybeLoad import audio.funkwhale.ffa.utils.maybeLoad
import audio.funkwhale.ffa.utils.maybeNormalizeUrl import audio.funkwhale.ffa.utils.maybeNormalizeUrl
import audio.funkwhale.ffa.utils.toast import audio.funkwhale.ffa.utils.toast

2
app/src/main/java/audio/funkwhale/ffa/adapters/PlaylistsAdapter.kt

@ -9,7 +9,7 @@ import androidx.recyclerview.widget.RecyclerView
import audio.funkwhale.ffa.R import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.databinding.RowPlaylistBinding import audio.funkwhale.ffa.databinding.RowPlaylistBinding
import audio.funkwhale.ffa.fragments.FFAAdapter import audio.funkwhale.ffa.fragments.FFAAdapter
import audio.funkwhale.ffa.utils.Playlist import audio.funkwhale.ffa.model.Playlist
import audio.funkwhale.ffa.utils.toDurationString import audio.funkwhale.ffa.utils.toDurationString
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import jp.wasabeef.picasso.transformations.RoundedCornersTransformation import jp.wasabeef.picasso.transformations.RoundedCornersTransformation

2
app/src/main/java/audio/funkwhale/ffa/adapters/RadiosAdapter.kt

@ -12,7 +12,7 @@ import audio.funkwhale.ffa.fragments.FFAAdapter
import audio.funkwhale.ffa.utils.AppContext import audio.funkwhale.ffa.utils.AppContext
import audio.funkwhale.ffa.utils.Event import audio.funkwhale.ffa.utils.Event
import audio.funkwhale.ffa.utils.EventBus import audio.funkwhale.ffa.utils.EventBus
import audio.funkwhale.ffa.utils.Radio import audio.funkwhale.ffa.model.Radio
import audio.funkwhale.ffa.views.LoadingImageView import audio.funkwhale.ffa.views.LoadingImageView
import com.preference.PowerPreference import com.preference.PowerPreference
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope

6
app/src/main/java/audio/funkwhale/ffa/adapters/SearchAdapter.kt

@ -15,11 +15,11 @@ import androidx.recyclerview.widget.RecyclerView
import audio.funkwhale.ffa.R import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.databinding.RowSearchHeaderBinding import audio.funkwhale.ffa.databinding.RowSearchHeaderBinding
import audio.funkwhale.ffa.databinding.RowTrackBinding import audio.funkwhale.ffa.databinding.RowTrackBinding
import audio.funkwhale.ffa.utils.Album import audio.funkwhale.ffa.model.Album
import audio.funkwhale.ffa.utils.Artist import audio.funkwhale.ffa.model.Artist
import audio.funkwhale.ffa.utils.Command import audio.funkwhale.ffa.utils.Command
import audio.funkwhale.ffa.utils.CommandBus import audio.funkwhale.ffa.utils.CommandBus
import audio.funkwhale.ffa.utils.Track import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.utils.maybeLoad import audio.funkwhale.ffa.utils.maybeLoad
import audio.funkwhale.ffa.utils.maybeNormalizeUrl import audio.funkwhale.ffa.utils.maybeNormalizeUrl
import audio.funkwhale.ffa.utils.onApi import audio.funkwhale.ffa.utils.onApi

2
app/src/main/java/audio/funkwhale/ffa/adapters/TracksAdapter.kt

@ -20,7 +20,7 @@ import audio.funkwhale.ffa.databinding.RowTrackBinding
import audio.funkwhale.ffa.fragments.FFAAdapter import audio.funkwhale.ffa.fragments.FFAAdapter
import audio.funkwhale.ffa.utils.Command import audio.funkwhale.ffa.utils.Command
import audio.funkwhale.ffa.utils.CommandBus import audio.funkwhale.ffa.utils.CommandBus
import audio.funkwhale.ffa.utils.Track import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.utils.maybeLoad import audio.funkwhale.ffa.utils.maybeLoad
import audio.funkwhale.ffa.utils.maybeNormalizeUrl import audio.funkwhale.ffa.utils.maybeNormalizeUrl
import audio.funkwhale.ffa.utils.toast import audio.funkwhale.ffa.utils.toast

2
app/src/main/java/audio/funkwhale/ffa/fragments/AddToPlaylistDialog.kt

@ -11,6 +11,8 @@ import androidx.recyclerview.widget.LinearLayoutManager
import audio.funkwhale.ffa.R import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.adapters.PlaylistsAdapter import audio.funkwhale.ffa.adapters.PlaylistsAdapter
import audio.funkwhale.ffa.databinding.DialogAddToPlaylistBinding import audio.funkwhale.ffa.databinding.DialogAddToPlaylistBinding
import audio.funkwhale.ffa.model.Playlist
import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.repositories.ManagementPlaylistsRepository import audio.funkwhale.ffa.repositories.ManagementPlaylistsRepository
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.utils.*
import com.google.gson.Gson import com.google.gson.Gson

2
app/src/main/java/audio/funkwhale/ffa/fragments/AlbumsFragment.kt

@ -20,6 +20,8 @@ import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.activities.MainActivity import audio.funkwhale.ffa.activities.MainActivity
import audio.funkwhale.ffa.adapters.AlbumsAdapter import audio.funkwhale.ffa.adapters.AlbumsAdapter
import audio.funkwhale.ffa.databinding.FragmentAlbumsBinding import audio.funkwhale.ffa.databinding.FragmentAlbumsBinding
import audio.funkwhale.ffa.model.Album
import audio.funkwhale.ffa.model.Artist
import audio.funkwhale.ffa.repositories.AlbumsRepository import audio.funkwhale.ffa.repositories.AlbumsRepository
import audio.funkwhale.ffa.repositories.ArtistTracksRepository import audio.funkwhale.ffa.repositories.ArtistTracksRepository
import audio.funkwhale.ffa.repositories.Repository import audio.funkwhale.ffa.repositories.Repository

2
app/src/main/java/audio/funkwhale/ffa/fragments/AlbumsGridFragment.kt

@ -14,7 +14,7 @@ import audio.funkwhale.ffa.activities.MainActivity
import audio.funkwhale.ffa.adapters.AlbumsGridAdapter import audio.funkwhale.ffa.adapters.AlbumsGridAdapter
import audio.funkwhale.ffa.databinding.FragmentAlbumsGridBinding import audio.funkwhale.ffa.databinding.FragmentAlbumsGridBinding
import audio.funkwhale.ffa.repositories.AlbumsRepository import audio.funkwhale.ffa.repositories.AlbumsRepository
import audio.funkwhale.ffa.utils.Album import audio.funkwhale.ffa.model.Album
import audio.funkwhale.ffa.utils.AppContext import audio.funkwhale.ffa.utils.AppContext
class AlbumsGridFragment : FFAFragment<Album, AlbumsGridAdapter>() { class AlbumsGridFragment : FFAFragment<Album, AlbumsGridAdapter>() {

2
app/src/main/java/audio/funkwhale/ffa/fragments/ArtistsFragment.kt

@ -15,9 +15,9 @@ import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.activities.MainActivity import audio.funkwhale.ffa.activities.MainActivity
import audio.funkwhale.ffa.adapters.ArtistsAdapter import audio.funkwhale.ffa.adapters.ArtistsAdapter
import audio.funkwhale.ffa.databinding.FragmentArtistsBinding import audio.funkwhale.ffa.databinding.FragmentArtistsBinding
import audio.funkwhale.ffa.model.Artist
import audio.funkwhale.ffa.repositories.ArtistsRepository import audio.funkwhale.ffa.repositories.ArtistsRepository
import audio.funkwhale.ffa.utils.AppContext import audio.funkwhale.ffa.utils.AppContext
import audio.funkwhale.ffa.utils.Artist
import audio.funkwhale.ffa.utils.onViewPager import audio.funkwhale.ffa.utils.onViewPager
class ArtistsFragment : FFAFragment<Artist, ArtistsAdapter>() { class ArtistsFragment : FFAFragment<Artist, ArtistsAdapter>() {

1
app/src/main/java/audio/funkwhale/ffa/fragments/FavoritesFragment.kt

@ -8,6 +8,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import audio.funkwhale.ffa.adapters.FavoritesAdapter import audio.funkwhale.ffa.adapters.FavoritesAdapter
import audio.funkwhale.ffa.databinding.FragmentFavoritesBinding import audio.funkwhale.ffa.databinding.FragmentFavoritesBinding
import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.repositories.FavoritesRepository import audio.funkwhale.ffa.repositories.FavoritesRepository
import audio.funkwhale.ffa.repositories.TracksRepository import audio.funkwhale.ffa.repositories.TracksRepository
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.utils.*

6
app/src/main/java/audio/funkwhale/ffa/fragments/PlaylistTracksFragment.kt

@ -17,12 +17,12 @@ import audio.funkwhale.ffa.repositories.ManagementPlaylistsRepository
import audio.funkwhale.ffa.repositories.PlaylistTracksRepository import audio.funkwhale.ffa.repositories.PlaylistTracksRepository
import audio.funkwhale.ffa.utils.Command import audio.funkwhale.ffa.utils.Command
import audio.funkwhale.ffa.utils.CommandBus import audio.funkwhale.ffa.utils.CommandBus
import audio.funkwhale.ffa.utils.Playlist import audio.funkwhale.ffa.model.Playlist
import audio.funkwhale.ffa.utils.PlaylistTrack import audio.funkwhale.ffa.model.PlaylistTrack
import audio.funkwhale.ffa.utils.Request import audio.funkwhale.ffa.utils.Request
import audio.funkwhale.ffa.utils.RequestBus import audio.funkwhale.ffa.utils.RequestBus
import audio.funkwhale.ffa.utils.Response import audio.funkwhale.ffa.utils.Response
import audio.funkwhale.ffa.utils.Track import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.utils.maybeLoad import audio.funkwhale.ffa.utils.maybeLoad
import audio.funkwhale.ffa.utils.maybeNormalizeUrl import audio.funkwhale.ffa.utils.maybeNormalizeUrl
import audio.funkwhale.ffa.utils.toast import audio.funkwhale.ffa.utils.toast

2
app/src/main/java/audio/funkwhale/ffa/fragments/PlaylistsFragment.kt

@ -14,7 +14,7 @@ import audio.funkwhale.ffa.adapters.PlaylistsAdapter
import audio.funkwhale.ffa.databinding.FragmentPlaylistsBinding import audio.funkwhale.ffa.databinding.FragmentPlaylistsBinding
import audio.funkwhale.ffa.repositories.PlaylistsRepository import audio.funkwhale.ffa.repositories.PlaylistsRepository
import audio.funkwhale.ffa.utils.AppContext import audio.funkwhale.ffa.utils.AppContext
import audio.funkwhale.ffa.utils.Playlist import audio.funkwhale.ffa.model.Playlist
class PlaylistsFragment : FFAFragment<Playlist, PlaylistsAdapter>() { class PlaylistsFragment : FFAFragment<Playlist, PlaylistsAdapter>() {

2
app/src/main/java/audio/funkwhale/ffa/fragments/RadiosFragment.kt

@ -14,7 +14,7 @@ import audio.funkwhale.ffa.utils.Command
import audio.funkwhale.ffa.utils.CommandBus import audio.funkwhale.ffa.utils.CommandBus
import audio.funkwhale.ffa.utils.Event import audio.funkwhale.ffa.utils.Event
import audio.funkwhale.ffa.utils.EventBus import audio.funkwhale.ffa.utils.EventBus
import audio.funkwhale.ffa.utils.Radio import audio.funkwhale.ffa.model.Radio
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch import kotlinx.coroutines.launch

2
app/src/main/java/audio/funkwhale/ffa/fragments/TrackInfoDetailsFragment.kt

@ -12,7 +12,7 @@ import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import audio.funkwhale.ffa.R import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.databinding.FragmentTrackInfoDetailsBinding import audio.funkwhale.ffa.databinding.FragmentTrackInfoDetailsBinding
import audio.funkwhale.ffa.utils.Track import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.utils.mustNormalizeUrl import audio.funkwhale.ffa.utils.mustNormalizeUrl
import audio.funkwhale.ffa.utils.toDurationString import audio.funkwhale.ffa.utils.toDurationString

2
app/src/main/java/audio/funkwhale/ffa/fragments/TracksFragment.kt

@ -14,6 +14,8 @@ import androidx.recyclerview.widget.RecyclerView
import audio.funkwhale.ffa.R import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.adapters.TracksAdapter import audio.funkwhale.ffa.adapters.TracksAdapter
import audio.funkwhale.ffa.databinding.FragmentTracksBinding import audio.funkwhale.ffa.databinding.FragmentTracksBinding
import audio.funkwhale.ffa.model.Album
import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.repositories.FavoritedRepository import audio.funkwhale.ffa.repositories.FavoritedRepository
import audio.funkwhale.ffa.repositories.FavoritesRepository import audio.funkwhale.ffa.repositories.FavoritesRepository
import audio.funkwhale.ffa.repositories.TracksRepository import audio.funkwhale.ffa.repositories.TracksRepository

17
app/src/main/java/audio/funkwhale/ffa/model/Album.kt

@ -0,0 +1,17 @@
package audio.funkwhale.ffa.model
data class Album(
val id: Int,
val artist: Artist,
val title: String,
val cover: Covers?,
val release_date: String?
) : SearchResult {
data class Artist(val name: String)
override fun cover() = cover?.urls?.original
override fun title() = title
override fun subtitle() = artist.name
}
typealias AlbumList = List<Album>

9
app/src/main/java/audio/funkwhale/ffa/model/AlbumsResponse.kt

@ -0,0 +1,9 @@
package audio.funkwhale.ffa.model
data class AlbumsResponse(
override val count: Int,
override val next: String?,
val results: AlbumList
) : FFAResponse<Album>() {
override fun getData() = results
}

16
app/src/main/java/audio/funkwhale/ffa/model/Artist.kt

@ -0,0 +1,16 @@
package audio.funkwhale.ffa.model
data class Artist(
val id: Int,
val name: String,
val albums: List<Album>?
) : SearchResult {
data class Album(
val title: String,
val cover: Covers?
)
override fun cover(): String? = albums?.getOrNull(0)?.cover?.urls?.original
override fun title() = name
override fun subtitle() = "Artist"
}

9
app/src/main/java/audio/funkwhale/ffa/model/ArtistsResponse.kt

@ -0,0 +1,9 @@
package audio.funkwhale.ffa.model
data class ArtistsResponse(
override val count: Int,
override val next: String?,
val results: List<Artist>
) : FFAResponse<Artist>() {
override fun getData() = results
}

12
app/src/main/java/audio/funkwhale/ffa/model/CacheItem.kt

@ -0,0 +1,12 @@
package audio.funkwhale.ffa.model
sealed class CacheItem<D : Any>(val data: List<D>)
class ArtistsCache(data: List<Artist>) : CacheItem<Artist>(data)
class AlbumsCache(data: List<Album>) : CacheItem<Album>(data)
class TracksCache(data: List<Track>) : CacheItem<Track>(data)
class PlaylistsCache(data: List<Playlist>) : CacheItem<Playlist>(data)
class PlaylistTracksCache(data: List<PlaylistTrack>) : CacheItem<PlaylistTrack>(data)
class RadiosCache(data: List<Radio>) : CacheItem<Radio>(data)
class FavoritedCache(data: List<Int>) : CacheItem<Int>(data)
class QueueCache(data: List<Track>) : CacheItem<Track>(data)

3
app/src/main/java/audio/funkwhale/ffa/model/CoverUrls.kt

@ -0,0 +1,3 @@
package audio.funkwhale.ffa.model
data class CoverUrls(val original: String)

3
app/src/main/java/audio/funkwhale/ffa/model/Covers.kt

@ -0,0 +1,3 @@
package audio.funkwhale.ffa.model
data class Covers(val urls: CoverUrls)

11
app/src/main/java/audio/funkwhale/ffa/model/DownloadInfo.kt

@ -0,0 +1,11 @@
package audio.funkwhale.ffa.model
import com.google.android.exoplayer2.offline.Download
data class DownloadInfo(
val id: Int,
val contentId: String,
val title: String,
val artist: String,
var download: Download?
)

8
app/src/main/java/audio/funkwhale/ffa/model/FFAResponse.kt

@ -0,0 +1,8 @@
package audio.funkwhale.ffa.model
abstract class FFAResponse<D : Any> {
abstract val count: Int
abstract val next: String?
abstract fun getData(): List<D>
}

3
app/src/main/java/audio/funkwhale/ffa/model/Favorited.kt

@ -0,0 +1,3 @@
package audio.funkwhale.ffa.model
data class Favorited(val track: Int)

9
app/src/main/java/audio/funkwhale/ffa/model/FavoritedResponse.kt

@ -0,0 +1,9 @@
package audio.funkwhale.ffa.model
data class FavoritedResponse(
override val count: Int,
override val next: String?,
val results: List<Favorited>
) : FFAResponse<Int>() {
override fun getData() = results.map { it.track }
}

9
app/src/main/java/audio/funkwhale/ffa/model/Playlist.kt

@ -0,0 +1,9 @@
package audio.funkwhale.ffa.model
data class Playlist(
val id: Int,
val name: String,
val album_covers: List<String>,
val tracks_count: Int,
val duration: Int
)

3
app/src/main/java/audio/funkwhale/ffa/model/PlaylistTrack.kt

@ -0,0 +1,3 @@
package audio.funkwhale.ffa.model
data class PlaylistTrack(val track: Track)

9
app/src/main/java/audio/funkwhale/ffa/model/PlaylistTracksResponse.kt

@ -0,0 +1,9 @@
package audio.funkwhale.ffa.model
data class PlaylistTracksResponse(
override val count: Int,
override val next: String?,
val results: List<PlaylistTrack>
) : FFAResponse<PlaylistTrack>() {
override fun getData() = results
}

9
app/src/main/java/audio/funkwhale/ffa/model/PlaylistsResponse.kt

@ -0,0 +1,9 @@
package audio.funkwhale.ffa.model
data class PlaylistsResponse(
override val count: Int,
override val next: String?,
val results: List<Playlist>
) : FFAResponse<Playlist>() {
override fun getData() = results
}

9
app/src/main/java/audio/funkwhale/ffa/model/Radio.kt

@ -0,0 +1,9 @@
package audio.funkwhale.ffa.model
data class Radio(
val id: Int,
var radio_type: String,
val name: String,
val description: String,
var related_object_id: String? = null
)

9
app/src/main/java/audio/funkwhale/ffa/model/RadiosResponse.kt

@ -0,0 +1,9 @@
package audio.funkwhale.ffa.model
data class RadiosResponse(
override val count: Int,
override val next: String?,
val results: List<Radio>
) : FFAResponse<Radio>() {
override fun getData() = results
}

7
app/src/main/java/audio/funkwhale/ffa/model/SearchResult.kt

@ -0,0 +1,7 @@
package audio.funkwhale.ffa.model
interface SearchResult {
fun cover(): String?
fun title(): String
fun subtitle(): String
}

64
app/src/main/java/audio/funkwhale/ffa/model/Track.kt

@ -0,0 +1,64 @@
package audio.funkwhale.ffa.model
import com.preference.PowerPreference
data class Track(
val id: Int = 0,
val title: String,
val artist: Artist,
val album: Album?,
val disc_number: Int = 0,
val position: Int = 0,
val uploads: List<Upload> = listOf(),
val copyright: String? = null,
val license: String? = null
) : SearchResult {
var current: Boolean = false
var favorite: Boolean = false
var cached: Boolean = false
var downloaded: Boolean = false
companion object {
fun fromDownload(download: DownloadInfo): Track = Track(
id = download.id,
title = download.title,
artist = Artist(0, download.artist, listOf()),
album = Album(0, Album.Artist(""), "", Covers(CoverUrls("")), ""),
uploads = listOf(Upload(download.contentId, 0, 0))
)
}
data class Upload(
val listen_url: String,
val duration: Int,
val bitrate: Int
)
override fun equals(other: Any?): Boolean {
return when (other) {
is Track -> other.id == id
else -> false
}
}
override fun hashCode(): Int {
return id
}
fun bestUpload(): Upload? {
if (uploads.isEmpty()) return null
return when (PowerPreference.getDefaultFile().getString("media_cache_quality")) {
"quality" -> uploads.maxByOrNull { it.bitrate } ?: uploads[0]
"size" -> uploads.minByOrNull { it.bitrate } ?: uploads[0]
else -> uploads.maxByOrNull { it.bitrate } ?: uploads[0]
}
}
override fun cover() = album?.cover?.urls?.original
override fun title() = title
override fun subtitle() = artist.name
val formatted: String get() = "$id $artist ($album): $title"
}

9
app/src/main/java/audio/funkwhale/ffa/model/TracksResponse.kt

@ -0,0 +1,9 @@
package audio.funkwhale.ffa.model
data class TracksResponse(
override val count: Int,
override val next: String?,
val results: List<Track>
) : FFAResponse<Track>() {
override fun getData() = results
}

5
app/src/main/java/audio/funkwhale/ffa/model/User.kt

@ -0,0 +1,5 @@
package audio.funkwhale.ffa.model
data class User(
val full_username: String
)

24
app/src/main/java/audio/funkwhale/ffa/playback/CacheDataSourceFactoryProvider.kt

@ -13,32 +13,32 @@ import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory
import com.google.android.exoplayer2.util.Util import com.google.android.exoplayer2.util.Util
class CacheDataSourceFactoryProvider( class CacheDataSourceFactoryProvider(
private val oAuth: OAuth, private val oAuth: OAuth,
private val exoCache: Cache, private val exoCache: Cache,
private val exoDownloadCache: Cache private val exoDownloadCache: Cache
) { ) {
fun create(context: Context): CacheDataSourceFactory { fun create(context: Context): CacheDataSourceFactory {
val playbackCache = val playbackCache =
CacheDataSourceFactory(exoCache, createDatasourceFactory(context, oAuth)) CacheDataSourceFactory(exoCache, createDatasourceFactory(context, oAuth))
return CacheDataSourceFactory( return CacheDataSourceFactory(
exoDownloadCache, exoDownloadCache,
playbackCache, playbackCache,
FileDataSource.Factory(), FileDataSource.Factory(),
null, null,
CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR, CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR,
null null
) )
} }
private fun createDatasourceFactory(context: Context, oAuth: OAuth): DataSource.Factory { private fun createDatasourceFactory(context: Context, oAuth: OAuth): DataSource.Factory {
val http = DefaultHttpDataSourceFactory( val http = DefaultHttpDataSourceFactory(
Util.getUserAgent(context, context.getString(R.string.app_name)) Util.getUserAgent(context, context.getString(R.string.app_name))
) )
return if (!Settings.isAnonymous()) { return if (!Settings.isAnonymous()) {
OAuth2DatasourceFactory(context, http, oAuth) OAuth2DatasourceFactory(context, http, oAuth)
} else { } else {
http http
} }

2
app/src/main/java/audio/funkwhale/ffa/playback/MediaControlsManager.kt

@ -13,7 +13,7 @@ import androidx.media.session.MediaButtonReceiver
import audio.funkwhale.ffa.R import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.activities.MainActivity import audio.funkwhale.ffa.activities.MainActivity
import audio.funkwhale.ffa.utils.AppContext import audio.funkwhale.ffa.utils.AppContext
import audio.funkwhale.ffa.utils.Track import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.utils.maybeNormalizeUrl import audio.funkwhale.ffa.utils.maybeNormalizeUrl
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope

4
app/src/main/java/audio/funkwhale/ffa/playback/MediaSession.kt

@ -40,7 +40,7 @@ class MediaSession(private val context: Context) {
val connector: MediaSessionConnector by lazy { val connector: MediaSessionConnector by lazy {
MediaSessionConnector(session).also { MediaSessionConnector(session).also {
it.setQueueNavigator(OtterQueueNavigator()) it.setQueueNavigator(FFAQueueNavigator())
it.setMediaButtonEventHandler { _, _, intent -> it.setMediaButtonEventHandler { _, _, intent ->
if (!active) { if (!active) {
@ -59,7 +59,7 @@ class MediaSession(private val context: Context) {
} }
} }
class OtterQueueNavigator : MediaSessionConnector.QueueNavigator { class FFAQueueNavigator : MediaSessionConnector.QueueNavigator {
override fun onSkipToQueueItem(player: Player, controlDispatcher: ControlDispatcher, id: Long) { override fun onSkipToQueueItem(player: Player, controlDispatcher: ControlDispatcher, id: Long) {
CommandBus.send(Command.PlayTrack(id.toInt())) CommandBus.send(Command.PlayTrack(id.toInt()))
} }

2
app/src/main/java/audio/funkwhale/ffa/playback/PinService.kt

@ -5,6 +5,8 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import audio.funkwhale.ffa.R import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.model.DownloadInfo
import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.utils.*
import com.google.android.exoplayer2.offline.Download import com.google.android.exoplayer2.offline.Download
import com.google.android.exoplayer2.offline.DownloadManager import com.google.android.exoplayer2.offline.DownloadManager

2
app/src/main/java/audio/funkwhale/ffa/playback/PlayerService.kt

@ -12,11 +12,11 @@ import android.media.MediaMetadata
import android.os.Build import android.os.Build
import android.os.IBinder import android.os.IBinder
import android.support.v4.media.MediaMetadataCompat import android.support.v4.media.MediaMetadataCompat
import android.util.Log
import android.view.KeyEvent import android.view.KeyEvent
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
import androidx.media.session.MediaButtonReceiver import androidx.media.session.MediaButtonReceiver
import audio.funkwhale.ffa.R import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.utils.*
import com.google.android.exoplayer2.C import com.google.android.exoplayer2.C
import com.google.android.exoplayer2.ExoPlaybackException import com.google.android.exoplayer2.ExoPlaybackException

3
app/src/main/java/audio/funkwhale/ffa/playback/QueueManager.kt

@ -2,6 +2,8 @@ package audio.funkwhale.ffa.playback
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import audio.funkwhale.ffa.model.QueueCache
import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.utils.*
import com.github.kittinunf.fuel.gson.gsonDeserializerOf import com.github.kittinunf.fuel.gson.gsonDeserializerOf
import com.google.android.exoplayer2.source.ConcatenatingMediaSource import com.google.android.exoplayer2.source.ConcatenatingMediaSource
@ -48,7 +50,6 @@ class QueueManager(val context: Context) {
) )
} }
fun replace(tracks: List<Track>) { fun replace(tracks: List<Track>) {
tracks.map { it.formatted }.log("Replacing queue with ${tracks.size} tracks") tracks.map { it.formatted }.log("Replacing queue with ${tracks.size} tracks")
val factory = cacheDataSourceFactoryProvider.create(context) val factory = cacheDataSourceFactoryProvider.create(context)

2
app/src/main/java/audio/funkwhale/ffa/playback/RadioPlayer.kt

@ -2,6 +2,8 @@ package audio.funkwhale.ffa.playback
import android.content.Context import android.content.Context
import audio.funkwhale.ffa.R import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.model.Radio
import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.repositories.FavoritedRepository import audio.funkwhale.ffa.repositories.FavoritedRepository
import audio.funkwhale.ffa.repositories.Repository import audio.funkwhale.ffa.repositories.Repository
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.utils.*

6
app/src/main/java/audio/funkwhale/ffa/repositories/AlbumsRepository.kt

@ -1,9 +1,9 @@
package audio.funkwhale.ffa.repositories package audio.funkwhale.ffa.repositories
import android.content.Context import android.content.Context
import audio.funkwhale.ffa.utils.Album import audio.funkwhale.ffa.model.Album
import audio.funkwhale.ffa.utils.AlbumsCache import audio.funkwhale.ffa.model.AlbumsCache
import audio.funkwhale.ffa.utils.AlbumsResponse import audio.funkwhale.ffa.model.AlbumsResponse
import audio.funkwhale.ffa.utils.OAuth import audio.funkwhale.ffa.utils.OAuth
import com.github.kittinunf.fuel.gson.gsonDeserializerOf import com.github.kittinunf.fuel.gson.gsonDeserializerOf
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken

8
app/src/main/java/audio/funkwhale/ffa/repositories/ArtistTracksRepository.kt

@ -1,7 +1,11 @@
package audio.funkwhale.ffa.repositories package audio.funkwhale.ffa.repositories
import android.content.Context import android.content.Context
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.model.FFAResponse
import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.model.TracksCache
import audio.funkwhale.ffa.model.TracksResponse
import audio.funkwhale.ffa.utils.OAuth
import com.github.kittinunf.fuel.gson.gsonDeserializerOf import com.github.kittinunf.fuel.gson.gsonDeserializerOf
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import org.koin.java.KoinJavaComponent.inject import org.koin.java.KoinJavaComponent.inject
@ -14,7 +18,7 @@ class ArtistTracksRepository(override val context: Context?, private val artistI
override val cacheId = "tracks-artist-$artistId" override val cacheId = "tracks-artist-$artistId"
override val upstream = HttpUpstream<Track, OtterResponse<Track>>( override val upstream = HttpUpstream<Track, FFAResponse<Track>>(
context, context,
HttpUpstream.Behavior.AtOnce, HttpUpstream.Behavior.AtOnce,
"/api/v1/tracks/?playable=true&artist=$artistId", "/api/v1/tracks/?playable=true&artist=$artistId",

8
app/src/main/java/audio/funkwhale/ffa/repositories/ArtistsRepository.kt

@ -1,7 +1,11 @@
package audio.funkwhale.ffa.repositories package audio.funkwhale.ffa.repositories
import android.content.Context import android.content.Context
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.model.Artist
import audio.funkwhale.ffa.model.ArtistsCache
import audio.funkwhale.ffa.model.ArtistsResponse
import audio.funkwhale.ffa.model.FFAResponse
import audio.funkwhale.ffa.utils.OAuth
import com.github.kittinunf.fuel.gson.gsonDeserializerOf import com.github.kittinunf.fuel.gson.gsonDeserializerOf
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import org.koin.java.KoinJavaComponent.inject import org.koin.java.KoinJavaComponent.inject
@ -13,7 +17,7 @@ class ArtistsRepository(override val context: Context?) : Repository<Artist, Art
override val cacheId = "artists" override val cacheId = "artists"
override val upstream = HttpUpstream<Artist, OtterResponse<Artist>>( override val upstream = HttpUpstream<Artist, FFAResponse<Artist>>(
context, context,
HttpUpstream.Behavior.Progressive, HttpUpstream.Behavior.Progressive,
"/api/v1/artists/?playable=true&ordering=name", "/api/v1/artists/?playable=true&ordering=name",

5
app/src/main/java/audio/funkwhale/ffa/repositories/FavoritesRepository.kt

@ -1,6 +1,7 @@
package audio.funkwhale.ffa.repositories package audio.funkwhale.ffa.repositories
import android.content.Context import android.content.Context
import audio.funkwhale.ffa.model.*
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.utils.*
import com.github.kittinunf.fuel.Fuel import com.github.kittinunf.fuel.Fuel
import com.github.kittinunf.fuel.coroutines.awaitByteArrayResponseResult import com.github.kittinunf.fuel.coroutines.awaitByteArrayResponseResult
@ -25,7 +26,7 @@ class FavoritesRepository(override val context: Context?) : Repository<Track, Tr
override val cacheId = "favorites.v2" override val cacheId = "favorites.v2"
override val upstream = HttpUpstream<Track, OtterResponse<Track>>( override val upstream = HttpUpstream<Track, FFAResponse<Track>>(
context!!, context!!,
HttpUpstream.Behavior.AtOnce, HttpUpstream.Behavior.AtOnce,
"/api/v1/tracks/?favorites=true&playable=true&ordering=title", "/api/v1/tracks/?favorites=true&playable=true&ordering=title",
@ -106,7 +107,7 @@ class FavoritedRepository(override val context: Context?) : Repository<Int, Favo
private val oAuth: OAuth by inject(OAuth::class.java) private val oAuth: OAuth by inject(OAuth::class.java)
override val cacheId = "favorited" override val cacheId = "favorited"
override val upstream = HttpUpstream<Int, OtterResponse<Int>>( override val upstream = HttpUpstream<Int, FFAResponse<Int>>(
context, context,
HttpUpstream.Behavior.Single, HttpUpstream.Behavior.Single,
"/api/v1/favorites/tracks/all/?playable=true", "/api/v1/favorites/tracks/all/?playable=true",

5
app/src/main/java/audio/funkwhale/ffa/repositories/HttpUpstream.kt

@ -3,6 +3,7 @@ package audio.funkwhale.ffa.repositories
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import android.util.Log import android.util.Log
import audio.funkwhale.ffa.model.FFAResponse
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.utils.*
import com.github.kittinunf.fuel.Fuel import com.github.kittinunf.fuel.Fuel
import com.github.kittinunf.fuel.core.FuelError import com.github.kittinunf.fuel.core.FuelError
@ -19,7 +20,7 @@ import java.io.Reader
import java.lang.reflect.Type import java.lang.reflect.Type
import kotlin.math.ceil import kotlin.math.ceil
class HttpUpstream<D : Any, R : OtterResponse<D>>( class HttpUpstream<D : Any, R : FFAResponse<D>>(
val context: Context?, val context: Context?,
val behavior: Behavior, val behavior: Behavior,
private val url: String, private val url: String,
@ -78,7 +79,7 @@ class HttpUpstream<D : Any, R : OtterResponse<D>>(
hasMore hasMore
) )
class GenericDeserializer<T : OtterResponse<*>>(val type: Type) : ResponseDeserializable<T> { class GenericDeserializer<T : FFAResponse<*>>(val type: Type) : ResponseDeserializable<T> {
override fun deserialize(reader: Reader): T? { override fun deserialize(reader: Reader): T? {
return Gson().fromJson(reader, type) return Gson().fromJson(reader, type)
} }

8
app/src/main/java/audio/funkwhale/ffa/repositories/PlaylistTracksRepository.kt

@ -1,7 +1,11 @@
package audio.funkwhale.ffa.repositories package audio.funkwhale.ffa.repositories
import android.content.Context import android.content.Context
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.model.FFAResponse
import audio.funkwhale.ffa.model.PlaylistTrack
import audio.funkwhale.ffa.model.PlaylistTracksCache
import audio.funkwhale.ffa.model.PlaylistTracksResponse
import audio.funkwhale.ffa.utils.OAuth
import com.github.kittinunf.fuel.gson.gsonDeserializerOf import com.github.kittinunf.fuel.gson.gsonDeserializerOf
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@ -17,7 +21,7 @@ class PlaylistTracksRepository(override val context: Context?, playlistId: Int)
override val cacheId = "tracks-playlist-$playlistId" override val cacheId = "tracks-playlist-$playlistId"
override val upstream = HttpUpstream<PlaylistTrack, OtterResponse<PlaylistTrack>>( override val upstream = HttpUpstream<PlaylistTrack, FFAResponse<PlaylistTrack>>(
context, context,
HttpUpstream.Behavior.Single, HttpUpstream.Behavior.Single,
"/api/v1/playlists/$playlistId/tracks/?playable=true", "/api/v1/playlists/$playlistId/tracks/?playable=true",

10
app/src/main/java/audio/funkwhale/ffa/repositories/PlaylistsRepository.kt

@ -1,7 +1,11 @@
package audio.funkwhale.ffa.repositories package audio.funkwhale.ffa.repositories
import android.content.Context import android.content.Context
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.model.*
import audio.funkwhale.ffa.utils.OAuth
import audio.funkwhale.ffa.utils.Settings
import audio.funkwhale.ffa.utils.authorize
import audio.funkwhale.ffa.utils.mustNormalizeUrl
import com.github.kittinunf.fuel.Fuel import com.github.kittinunf.fuel.Fuel
import com.github.kittinunf.fuel.coroutines.awaitByteArrayResponseResult import com.github.kittinunf.fuel.coroutines.awaitByteArrayResponseResult
import com.github.kittinunf.fuel.coroutines.awaitObjectResponseResult import com.github.kittinunf.fuel.coroutines.awaitObjectResponseResult
@ -21,7 +25,7 @@ class PlaylistsRepository(override val context: Context?) : Repository<Playlist,
private val oAuth: OAuth by inject(OAuth::class.java) private val oAuth: OAuth by inject(OAuth::class.java)
override val upstream = HttpUpstream<Playlist, OtterResponse<Playlist>>( override val upstream = HttpUpstream<Playlist, FFAResponse<Playlist>>(
context!!, context!!,
HttpUpstream.Behavior.Progressive, HttpUpstream.Behavior.Progressive,
"/api/v1/playlists/?playable=true&ordering=name", "/api/v1/playlists/?playable=true&ordering=name",
@ -41,7 +45,7 @@ class ManagementPlaylistsRepository(override val context: Context?) :
override val cacheId = "tracks-playlists-management" override val cacheId = "tracks-playlists-management"
override val upstream = HttpUpstream<Playlist, OtterResponse<Playlist>>( override val upstream = HttpUpstream<Playlist, FFAResponse<Playlist>>(
context, context,
HttpUpstream.Behavior.AtOnce, HttpUpstream.Behavior.AtOnce,
"/api/v1/playlists/?scope=me&ordering=name", "/api/v1/playlists/?scope=me&ordering=name",

8
app/src/main/java/audio/funkwhale/ffa/repositories/RadiosRepository.kt

@ -1,7 +1,11 @@
package audio.funkwhale.ffa.repositories package audio.funkwhale.ffa.repositories
import android.content.Context import android.content.Context
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.model.FFAResponse
import audio.funkwhale.ffa.model.Radio
import audio.funkwhale.ffa.model.RadiosCache
import audio.funkwhale.ffa.model.RadiosResponse
import audio.funkwhale.ffa.utils.OAuth
import com.github.kittinunf.fuel.gson.gsonDeserializerOf import com.github.kittinunf.fuel.gson.gsonDeserializerOf
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import org.koin.java.KoinJavaComponent.inject import org.koin.java.KoinJavaComponent.inject
@ -13,7 +17,7 @@ class RadiosRepository(override val context: Context?) : Repository<Radio, Radio
override val cacheId = "radios" override val cacheId = "radios"
override val upstream = HttpUpstream<Radio, OtterResponse<Radio>>( override val upstream = HttpUpstream<Radio, FFAResponse<Radio>>(
context, context,
HttpUpstream.Behavior.Progressive, HttpUpstream.Behavior.Progressive,
"/api/v1/radios/radios/?ordering=name", "/api/v1/radios/radios/?ordering=name",

2
app/src/main/java/audio/funkwhale/ffa/repositories/Repository.kt

@ -2,7 +2,7 @@ package audio.funkwhale.ffa.repositories
import android.content.Context import android.content.Context
import audio.funkwhale.ffa.utils.AppContext import audio.funkwhale.ffa.utils.AppContext
import audio.funkwhale.ffa.utils.CacheItem import audio.funkwhale.ffa.model.CacheItem
import audio.funkwhale.ffa.utils.FFACache import audio.funkwhale.ffa.utils.FFACache
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO

1
app/src/main/java/audio/funkwhale/ffa/repositories/SearchRepository.kt

@ -1,6 +1,7 @@
package audio.funkwhale.ffa.repositories package audio.funkwhale.ffa.repositories
import android.content.Context import android.content.Context
import audio.funkwhale.ffa.model.*
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.utils.*
import com.github.kittinunf.fuel.gson.gsonDeserializerOf import com.github.kittinunf.fuel.gson.gsonDeserializerOf
import com.google.android.exoplayer2.offline.DownloadManager import com.google.android.exoplayer2.offline.DownloadManager

10
app/src/main/java/audio/funkwhale/ffa/repositories/TracksRepository.kt

@ -1,7 +1,13 @@
package audio.funkwhale.ffa.repositories package audio.funkwhale.ffa.repositories
import android.content.Context import android.content.Context
import audio.funkwhale.ffa.utils.* import audio.funkwhale.ffa.model.FFAResponse
import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.model.TracksCache
import audio.funkwhale.ffa.model.TracksResponse
import audio.funkwhale.ffa.utils.OAuth
import audio.funkwhale.ffa.utils.getMetadata
import audio.funkwhale.ffa.utils.mustNormalizeUrl
import com.github.kittinunf.fuel.gson.gsonDeserializerOf import com.github.kittinunf.fuel.gson.gsonDeserializerOf
import com.google.android.exoplayer2.offline.Download import com.google.android.exoplayer2.offline.Download
import com.google.android.exoplayer2.offline.DownloadManager import com.google.android.exoplayer2.offline.DownloadManager
@ -23,7 +29,7 @@ class TracksRepository(override val context: Context?, albumId: Int) :
override val cacheId = "tracks-album-$albumId" override val cacheId = "tracks-album-$albumId"
override val upstream = HttpUpstream<Track, OtterResponse<Track>>( override val upstream = HttpUpstream<Track, FFAResponse<Track>>(
context, context,
HttpUpstream.Behavior.AtOnce, HttpUpstream.Behavior.AtOnce,
"/api/v1/tracks/?playable=true&album=$albumId&ordering=disc_number,position", "/api/v1/tracks/?playable=true&album=$albumId&ordering=disc_number,position",

2
app/src/main/java/audio/funkwhale/ffa/utils/Bus.kt

@ -1,6 +1,8 @@
package audio.funkwhale.ffa.utils package audio.funkwhale.ffa.utils
import audio.funkwhale.ffa.FFA import audio.funkwhale.ffa.FFA
import audio.funkwhale.ffa.model.Radio
import audio.funkwhale.ffa.model.Track
import com.google.android.exoplayer2.offline.Download import com.google.android.exoplayer2.offline.Download
import com.google.android.exoplayer2.offline.DownloadCursor import com.google.android.exoplayer2.offline.DownloadCursor
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO

3
app/src/main/java/audio/funkwhale/ffa/utils/Extensions.kt

@ -2,11 +2,11 @@ package audio.funkwhale.ffa.utils
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import android.os.SystemClock
import android.util.Log import android.util.Log
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import audio.funkwhale.ffa.R import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.fragments.BrowseFragment import audio.funkwhale.ffa.fragments.BrowseFragment
import audio.funkwhale.ffa.model.DownloadInfo
import audio.funkwhale.ffa.repositories.Repository import audio.funkwhale.ffa.repositories.Repository
import com.github.kittinunf.fuel.core.FuelError import com.github.kittinunf.fuel.core.FuelError
import com.github.kittinunf.fuel.core.Request import com.github.kittinunf.fuel.core.Request
@ -26,7 +26,6 @@ import java.text.SimpleDateFormat
import java.util.* import java.util.*
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
inline fun <D> Flow<Repository.Response<D>>.untilNetwork( inline fun <D> Flow<Repository.Response<D>>.untilNetwork(
scope: CoroutineScope, scope: CoroutineScope,
context: CoroutineContext = Main, context: CoroutineContext = Main,

3
app/src/main/java/audio/funkwhale/ffa/utils/FFACache.kt

@ -7,6 +7,7 @@ import java.nio.charset.Charset
import java.security.MessageDigest import java.security.MessageDigest
object FFACache { object FFACache {
private fun key(key: String): String { private fun key(key: String): String {
val md = MessageDigest.getInstance("SHA-1") val md = MessageDigest.getInstance("SHA-1")
val digest = md.digest(key.toByteArray(Charset.defaultCharset())) val digest = md.digest(key.toByteArray(Charset.defaultCharset()))
@ -35,4 +36,4 @@ object FFACache {
delete() delete()
} }
} }
} }

213
app/src/main/java/audio/funkwhale/ffa/utils/Models.kt

@ -1,213 +0,0 @@
package audio.funkwhale.ffa.utils
import com.google.android.exoplayer2.offline.Download
import com.preference.PowerPreference
data class User(
val full_username: String
)
sealed class CacheItem<D : Any>(val data: List<D>)
class ArtistsCache(data: List<Artist>) : CacheItem<Artist>(data)
class AlbumsCache(data: List<Album>) : CacheItem<Album>(data)
class TracksCache(data: List<Track>) : CacheItem<Track>(data)
class PlaylistsCache(data: List<Playlist>) : CacheItem<Playlist>(data)
class PlaylistTracksCache(data: List<PlaylistTrack>) : CacheItem<PlaylistTrack>(data)
class RadiosCache(data: List<Radio>) : CacheItem<Radio>(data)
class FavoritedCache(data: List<Int>) : CacheItem<Int>(data)
class QueueCache(data: List<Track>) : CacheItem<Track>(data)
abstract class OtterResponse<D : Any> {
abstract val count: Int
abstract val next: String?
abstract fun getData(): List<D>
}
data class UserResponse(
override val count: Int,
override val next: String?,
val results: List<Artist>
) : OtterResponse<Artist>() {
override fun getData() = results
}
data class ArtistsResponse(
override val count: Int,
override val next: String?,
val results: List<Artist>
) : OtterResponse<Artist>() {
override fun getData() = results
}
data class AlbumsResponse(
override val count: Int,
override val next: String?,
val results: AlbumList
) : OtterResponse<Album>() {
override fun getData() = results
}
data class TracksResponse(
override val count: Int,
override val next: String?,
val results: List<Track>
) : OtterResponse<Track>() {
override fun getData() = results
}
data class FavoritedResponse(
override val count: Int,
override val next: String?,
val results: List<Favorited>
) : OtterResponse<Int>() {
override fun getData() = results.map { it.track }
}
data class PlaylistsResponse(
override val count: Int,
override val next: String?,
val results: List<Playlist>
) : OtterResponse<Playlist>() {
override fun getData() = results
}
data class PlaylistTracksResponse(
override val count: Int,
override val next: String?,
val results: List<PlaylistTrack>
) : OtterResponse<PlaylistTrack>() {
override fun getData() = results
}
data class RadiosResponse(
override val count: Int,
override val next: String?,
val results: List<Radio>
) : OtterResponse<Radio>() {
override fun getData() = results
}
data class Covers(val urls: CoverUrls)
data class CoverUrls(val original: String)
typealias AlbumList = List<Album>
interface SearchResult {
fun cover(): String?
fun title(): String
fun subtitle(): String
}
data class Album(
val id: Int,
val artist: Artist,
val title: String,
val cover: Covers?,
val release_date: String?
) : SearchResult {
data class Artist(val name: String)
override fun cover() = cover?.urls?.original
override fun title() = title
override fun subtitle() = artist.name
}
data class Artist(
val id: Int,
val name: String,
val albums: List<Album>?
) : SearchResult {
data class Album(
val title: String,
val cover: Covers?
)
override fun cover(): String? = albums?.getOrNull(0)?.cover?.urls?.original
override fun title() = name
override fun subtitle() = "Artist"
}
data class Track(
val id: Int = 0,
val title: String,
val artist: Artist,
val album: Album?,
val disc_number: Int = 0,
val position: Int = 0,
val uploads: List<Upload> = listOf(),
val copyright: String? = null,
val license: String? = null
) : SearchResult {
var current: Boolean = false
var favorite: Boolean = false
var cached: Boolean = false
var downloaded: Boolean = false
companion object {
fun fromDownload(download: DownloadInfo): Track = Track(
id = download.id,
title = download.title,
artist = Artist(0, download.artist, listOf()),
album = Album(0, Album.Artist(""), "", Covers(CoverUrls("")), ""),
uploads = listOf(Upload(download.contentId, 0, 0))
)
}
data class Upload(
val listen_url: String,
val duration: Int,
val bitrate: Int
)
override fun equals(other: Any?): Boolean {
return when (other) {
is Track -> other.id == id
else -> false
}
}
fun bestUpload(): Upload? {
if (uploads.isEmpty()) return null
return when (PowerPreference.getDefaultFile().getString("media_cache_quality")) {
"quality" -> uploads.maxByOrNull { it.bitrate } ?: uploads[0]
"size" -> uploads.minByOrNull { it.bitrate } ?: uploads[0]
else -> uploads.maxByOrNull { it.bitrate } ?: uploads[0]
}
}
override fun cover() = album?.cover?.urls?.original
override fun title() = title
override fun subtitle() = artist.name
val formatted: String get() = "$id $artist ($album): $title"
}
data class Favorited(val track: Int)
data class Playlist(
val id: Int,
val name: String,
val album_covers: List<String>,
val tracks_count: Int,
val duration: Int
)
data class PlaylistTrack(val track: Track)
data class Radio(
val id: Int,
var radio_type: String,
val name: String,
val description: String,
var related_object_id: String? = null
)
data class DownloadInfo(
val id: Int,
val contentId: String,
val title: String,
val artist: String,
var download: Download?
)

1
app/src/main/java/audio/funkwhale/ffa/utils/RefreshError.kt

@ -1,4 +1,3 @@
package audio.funkwhale.ffa.utils package audio.funkwhale.ffa.utils
object RefreshError : Throwable() object RefreshError : Throwable()

1
app/src/main/java/audio/funkwhale/ffa/utils/Userinfo.kt

@ -1,6 +1,7 @@
package audio.funkwhale.ffa.utils package audio.funkwhale.ffa.utils
import android.content.Context import android.content.Context
import audio.funkwhale.ffa.model.User
import com.github.kittinunf.fuel.Fuel import com.github.kittinunf.fuel.Fuel
import com.github.kittinunf.fuel.coroutines.awaitObjectResponseResult import com.github.kittinunf.fuel.coroutines.awaitObjectResponseResult
import com.github.kittinunf.fuel.gson.gsonDeserializerOf import com.github.kittinunf.fuel.gson.gsonDeserializerOf

2
build.gradle.kts

@ -7,7 +7,7 @@ buildscript {
} }
dependencies { dependencies {
classpath("com.android.tools.build:gradle:${Versions.androidGradlePlugin}") classpath("com.android.tools.build:gradle:7.0.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}")
classpath("com.github.bjoernq:unmockplugin:${Versions.unmock}") classpath("com.github.bjoernq:unmockplugin:${Versions.unmock}")
classpath("com.github.ben-manes:gradle-versions-plugin:${Versions.gradleDependencyPlugin}") classpath("com.github.ben-manes:gradle-versions-plugin:${Versions.gradleDependencyPlugin}")

1
buildSrc/src/main/java/Versions.kt

@ -2,7 +2,6 @@ object Versions {
const val kotlin = "1.5.21" const val kotlin = "1.5.21"
const val jacoco = "0.8.7" const val jacoco = "0.8.7"
const val unmock = "0.7.8" const val unmock = "0.7.8"
const val androidGradlePlugin = "7.0.0"
const val gradleDependencyPlugin = "0.38.0" const val gradleDependencyPlugin = "0.38.0"
const val exoPlayer = "2.11.8" const val exoPlayer = "2.11.8"

Loading…
Cancel
Save