Minor cleanup, added comments

This commit is contained in:
Nite 2021-03-01 17:24:25 +01:00
parent 9910792c11
commit 46859e2413
No known key found for this signature in database
GPG Key ID: 1D1AD59B1C6386C1
25 changed files with 158 additions and 112 deletions

View File

@ -192,7 +192,7 @@ public class NowPlayingFragment extends Fragment {
{ {
if (deltaY < 0) if (deltaY < 0)
{ {
nowPlayingEventDistributor.getValue().RaiseNowPlayingDismissedEvent(); nowPlayingEventDistributor.getValue().raiseNowPlayingDismissedEvent();
return false; return false;
} }
if (deltaY > 0) if (deltaY > 0)

View File

@ -285,11 +285,11 @@ public class MediaPlayerService extends Service
if (currentPlaying != null) if (currentPlaying != null)
{ {
updateNotification(localMediaPlayer.playerState, currentPlaying); updateNotification(localMediaPlayer.playerState, currentPlaying);
nowPlayingEventDistributor.getValue().RaiseShowNowPlayingEvent(); nowPlayingEventDistributor.getValue().raiseShowNowPlayingEvent();
} }
else else
{ {
nowPlayingEventDistributor.getValue().RaiseHideNowPlayingEvent(); nowPlayingEventDistributor.getValue().raiseHideNowPlayingEvent();
stopForeground(true); stopForeground(true);
localMediaPlayer.clearRemoteControl(); localMediaPlayer.clearRemoteControl();
isInForeground = false; isInForeground = false;
@ -501,12 +501,12 @@ public class MediaPlayerService extends Service
if (playerState == PlayerState.STARTED || playerState == PlayerState.PAUSED) if (playerState == PlayerState.STARTED || playerState == PlayerState.PAUSED)
{ {
updateNotification(playerState, currentPlaying); updateNotification(playerState, currentPlaying);
nowPlayingEventDistributor.getValue().RaiseShowNowPlayingEvent(); nowPlayingEventDistributor.getValue().raiseShowNowPlayingEvent();
} }
} }
else else
{ {
nowPlayingEventDistributor.getValue().RaiseHideNowPlayingEvent(); nowPlayingEventDistributor.getValue().raiseHideNowPlayingEvent();
stopForeground(true); stopForeground(true);
localMediaPlayer.clearRemoteControl(); localMediaPlayer.clearRemoteControl();
isInForeground = false; isInForeground = false;

View File

@ -12,6 +12,9 @@ import org.moire.ultrasonic.util.Util
const val SP_NAME = "Default_SP" const val SP_NAME = "Default_SP"
/**
* This Koin module contains registration of classes related to permanent storage
*/
val appPermanentStorage = module { val appPermanentStorage = module {
single(named(SP_NAME)) { Util.getPreferences(androidContext()) } single(named(SP_NAME)) { Util.getPreferences(androidContext()) }

View File

@ -8,6 +8,9 @@ import org.moire.ultrasonic.util.NowPlayingEventDistributor
import org.moire.ultrasonic.util.PermissionUtil import org.moire.ultrasonic.util.PermissionUtil
import org.moire.ultrasonic.util.ThemeChangedEventDistributor import org.moire.ultrasonic.util.ThemeChangedEventDistributor
/**
* This Koin module contains the registration of general classes needed for Ultrasonic
*/
val applicationModule = module { val applicationModule = module {
single { ActiveServerProvider(get(), androidContext()) } single { ActiveServerProvider(get(), androidContext()) }
single { ImageLoaderProvider(androidContext()) } single { ImageLoaderProvider(androidContext()) }

View File

@ -4,7 +4,7 @@ import okhttp3.OkHttpClient
import org.koin.dsl.module import org.koin.dsl.module
/** /**
* Provides base network dependencies. * This Koin module provides base network dependencies.
*/ */
val baseNetworkModule = module { val baseNetworkModule = module {
single { OkHttpClient.Builder().build() } single { OkHttpClient.Builder().build() }

View File

@ -5,6 +5,9 @@ import org.koin.dsl.module
import org.moire.ultrasonic.cache.AndroidDirectories import org.moire.ultrasonic.cache.AndroidDirectories
import org.moire.ultrasonic.cache.Directories import org.moire.ultrasonic.cache.Directories
/**
* This Koin module contains the registration for Directories
*/
val directoriesModule = module { val directoriesModule = module {
single { AndroidDirectories(get()) } bind Directories::class single { AndroidDirectories(get()) } bind Directories::class
} }

View File

@ -4,6 +4,9 @@ import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module import org.koin.dsl.module
import org.moire.ultrasonic.featureflags.FeatureStorage import org.moire.ultrasonic.featureflags.FeatureStorage
/**
* This Koin module contains the registration for the Feature Flags
*/
val featureFlagsModule = module { val featureFlagsModule = module {
factory { FeatureStorage(androidContext()) } factory { FeatureStorage(androidContext()) }
} }

View File

@ -13,6 +13,9 @@ import org.moire.ultrasonic.service.MediaPlayerControllerImpl
import org.moire.ultrasonic.service.MediaPlayerLifecycleSupport import org.moire.ultrasonic.service.MediaPlayerLifecycleSupport
import org.moire.ultrasonic.util.ShufflePlayBuffer import org.moire.ultrasonic.util.ShufflePlayBuffer
/**
* This Koin module contains the registration of classes related to the media player
*/
val mediaPlayerModule = module { val mediaPlayerModule = module {
single<MediaPlayerController> { single<MediaPlayerController> {
MediaPlayerControllerImpl(androidContext(), get(), get(), get(), get(), get()) MediaPlayerControllerImpl(androidContext(), get(), get(), get(), get(), get())

View File

@ -27,6 +27,9 @@ import org.moire.ultrasonic.subsonic.VideoPlayer
import org.moire.ultrasonic.subsonic.loader.image.SubsonicImageLoader import org.moire.ultrasonic.subsonic.loader.image.SubsonicImageLoader
import org.moire.ultrasonic.util.Constants import org.moire.ultrasonic.util.Constants
/**
* This Koin module contains the registration of classes related to the Music Services
*/
internal const val ONLINE_MUSIC_SERVICE = "OnlineMusicService" internal const val ONLINE_MUSIC_SERVICE = "OnlineMusicService"
internal const val OFFLINE_MUSIC_SERVICE = "OfflineMusicService" internal const val OFFLINE_MUSIC_SERVICE = "OfflineMusicService"

View File

@ -30,6 +30,9 @@ import org.moire.ultrasonic.util.ModalBackgroundTask
import org.moire.ultrasonic.util.Util import org.moire.ultrasonic.util.Util
import timber.log.Timber import timber.log.Timber
/**
* Displays a form where server settings can be created / edited
*/
class EditServerFragment : Fragment(), OnBackPressedHandler { class EditServerFragment : Fragment(), OnBackPressedHandler {
companion object { companion object {
const val EDIT_SERVER_INTENT_INDEX = "index" const val EDIT_SERVER_INTENT_INDEX = "index"

View File

@ -3,10 +3,13 @@ package org.moire.ultrasonic.fragment
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
/**
* Contains utility functions related to Fragment title handling
*/
class FragmentTitle { class FragmentTitle {
companion object { companion object {
fun setTitle(fragment: Fragment, title: CharSequence?) { fun setTitle(fragment: Fragment, title: CharSequence?) {
(fragment.activity as AppCompatActivity).supportActionBar?.setTitle(title) (fragment.activity as AppCompatActivity).supportActionBar?.title = title
} }
fun setTitle(fragment: Fragment, id: Int) { fun setTitle(fragment: Fragment, id: Int) {
@ -16,17 +19,5 @@ class FragmentTitle {
fun getTitle(fragment: Fragment): CharSequence? { fun getTitle(fragment: Fragment): CharSequence? {
return (fragment.activity as AppCompatActivity).supportActionBar?.title return (fragment.activity as AppCompatActivity).supportActionBar?.title
} }
fun setSubtitle(fragment: Fragment, title: CharSequence?) {
(fragment.activity as AppCompatActivity).supportActionBar?.setSubtitle(title)
}
fun setSubtitle(fragment: Fragment, id: Int) {
(fragment.activity as AppCompatActivity).supportActionBar?.setSubtitle(id)
}
fun getSubtitle(fragment: Fragment): CharSequence? {
return (fragment.activity as AppCompatActivity).supportActionBar?.subtitle
}
} }
} }

View File

@ -24,6 +24,9 @@ import org.moire.ultrasonic.subsonic.ImageLoaderProvider
import org.moire.ultrasonic.util.Constants import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.Util import org.moire.ultrasonic.util.Util
/**
* Displays the list of Artists from the media library
*/
class SelectArtistFragment : Fragment() { class SelectArtistFragment : Fragment() {
private val activeServerProvider: ActiveServerProvider by inject() private val activeServerProvider: ActiveServerProvider by inject()
private val serverSettingsModel: ServerSettingsModel by viewModel() private val serverSettingsModel: ServerSettingsModel by viewModel()
@ -166,79 +169,79 @@ class SelectArtistFragment : Fragment() {
downloadHandler.downloadRecursively( downloadHandler.downloadRecursively(
this, this,
artist.id, artist.id,
false, save = false,
false, append = false,
true, autoPlay = true,
false, shuffle = false,
false, background = false,
false, playNext = false,
false, unpin = false,
true isArtist = true
) )
R.id.artist_menu_play_next -> R.id.artist_menu_play_next ->
downloadHandler.downloadRecursively( downloadHandler.downloadRecursively(
this, this,
artist.id, artist.id,
false, save = false,
false, append = false,
true, autoPlay = true,
true, shuffle = true,
false, background = false,
true, playNext = true,
false, unpin = false,
true isArtist = true
) )
R.id.artist_menu_play_last -> R.id.artist_menu_play_last ->
downloadHandler.downloadRecursively( downloadHandler.downloadRecursively(
this, this,
artist.id, artist.id,
false, save = false,
true, append = true,
false, autoPlay = false,
false, shuffle = false,
false, background = false,
false, playNext = false,
false, unpin = false,
true isArtist = true
) )
R.id.artist_menu_pin -> R.id.artist_menu_pin ->
downloadHandler.downloadRecursively( downloadHandler.downloadRecursively(
this, this,
artist.id, artist.id,
true, save = true,
true, append = true,
false, autoPlay = false,
false, shuffle = false,
false, background = false,
false, playNext = false,
false, unpin = false,
true isArtist = true
) )
R.id.artist_menu_unpin -> R.id.artist_menu_unpin ->
downloadHandler.downloadRecursively( downloadHandler.downloadRecursively(
this, this,
artist.id, artist.id,
false, save = false,
false, append = false,
false, autoPlay = false,
false, shuffle = false,
false, background = false,
false, playNext = false,
true, unpin = true,
true isArtist = true
) )
R.id.artist_menu_download -> R.id.artist_menu_download ->
downloadHandler.downloadRecursively( downloadHandler.downloadRecursively(
this, this,
artist.id, artist.id,
false, save = false,
false, append = false,
false, autoPlay = false,
false, shuffle = false,
true, background = true,
false, playNext = false,
false, unpin = false,
true isArtist = true
) )
} }
return true return true

View File

@ -23,6 +23,9 @@ import org.moire.ultrasonic.service.MediaPlayerController
import org.moire.ultrasonic.util.Util import org.moire.ultrasonic.util.Util
import timber.log.Timber import timber.log.Timber
/**
* Displays the list of configured servers, they can be selected or edited
*/
class ServerSelectorFragment : Fragment() { class ServerSelectorFragment : Fragment() {
companion object { companion object {
const val SERVER_SELECTOR_MANAGE_MODE = "manageMode" const val SERVER_SELECTOR_MANAGE_MODE = "manageMode"

View File

@ -24,7 +24,6 @@ import org.koin.core.component.get
import org.koin.core.context.loadKoinModules import org.koin.core.context.loadKoinModules
import org.koin.core.context.unloadKoinModules import org.koin.core.context.unloadKoinModules
import org.koin.core.qualifier.named import org.koin.core.qualifier.named
import org.moire.ultrasonic.cache.Directories
import org.moire.ultrasonic.data.ActiveServerProvider import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.di.OFFLINE_MUSIC_SERVICE import org.moire.ultrasonic.di.OFFLINE_MUSIC_SERVICE
import org.moire.ultrasonic.di.ONLINE_MUSIC_SERVICE import org.moire.ultrasonic.di.ONLINE_MUSIC_SERVICE
@ -50,10 +49,4 @@ object MusicServiceFactory : KoinComponent {
unloadKoinModules(musicServiceModule) unloadKoinModules(musicServiceModule)
loadKoinModules(musicServiceModule) loadKoinModules(musicServiceModule)
} }
@JvmStatic
fun getServerId() = get<String>(named("ServerID"))
@JvmStatic
fun getDirectories() = get<Directories>()
} }

View File

@ -65,6 +65,7 @@ import org.moire.ultrasonic.util.Util
import timber.log.Timber import timber.log.Timber
/** /**
* This Music Service implementation connects to a server using the Subsonic REST API
* @author Sindre Mehus * @author Sindre Mehus
*/ */
open class RESTMusicService( open class RESTMusicService(

View File

@ -15,11 +15,14 @@ import org.moire.ultrasonic.util.EntryByDiscAndTrackComparator
import org.moire.ultrasonic.util.ModalBackgroundTask import org.moire.ultrasonic.util.ModalBackgroundTask
import org.moire.ultrasonic.util.Util import org.moire.ultrasonic.util.Util
/**
* Retrieves a list of songs and adds them to the now playing list
*/
class DownloadHandler( class DownloadHandler(
val mediaPlayerController: MediaPlayerController, val mediaPlayerController: MediaPlayerController,
val networkAndStorageChecker: NetworkAndStorageChecker val networkAndStorageChecker: NetworkAndStorageChecker
) { ) {
private val MAX_SONGS = 500 private val maxSongs = 500
fun download( fun download(
fragment: Fragment, fragment: Fragment,
@ -102,16 +105,16 @@ class DownloadHandler(
fragment, fragment,
id, id,
name, name,
false, isShare = false,
false, isDirectory = false,
save, save = save,
append, append = append,
autoplay, autoPlay = autoplay,
shuffle, shuffle = shuffle,
background, background = background,
playNext, playNext = playNext,
unpin, unpin = unpin,
false isArtist = false
) )
} }
@ -131,16 +134,16 @@ class DownloadHandler(
fragment, fragment,
id, id,
name, name,
true, isShare = true,
false, isDirectory = false,
save, save = save,
append, append = append,
autoplay, autoPlay = autoplay,
shuffle, shuffle = shuffle,
background, background = background,
playNext, playNext = playNext,
unpin, unpin = unpin,
false isArtist = false
) )
} }
@ -174,7 +177,7 @@ class DownloadHandler(
) )
} }
fun downloadRecursively( private fun downloadRecursively(
fragment: Fragment, fragment: Fragment,
id: String, id: String,
name: String?, name: String?,
@ -232,18 +235,22 @@ class DownloadHandler(
parent: MusicDirectory, parent: MusicDirectory,
songs: MutableList<MusicDirectory.Entry> songs: MutableList<MusicDirectory.Entry>
) { ) {
if (songs.size > MAX_SONGS) { if (songs.size > maxSongs) {
return return
} }
for (song in parent.getChildren(false, true)) { for (song in parent.getChildren(includeDirs = false, includeFiles = true)) {
if (!song.isVideo) { if (!song.isVideo) {
songs.add(song) songs.add(song)
} }
} }
val musicService = getMusicService(activity) val musicService = getMusicService(activity)
for ((id1, _, _, title) in parent.getChildren(true, false)) { for (
var root: MusicDirectory (id1, _, _, title) in parent.getChildren(
root = if ( includeDirs = true,
includeFiles = false
)
) {
val root: MusicDirectory = if (
!isOffline(activity) && !isOffline(activity) &&
Util.getShouldUseId3Tags(activity) Util.getShouldUseId3Tags(activity)
) musicService.getAlbum(id1, title, false, activity) ) musicService.getAlbum(id1, title, false, activity)
@ -257,7 +264,7 @@ class DownloadHandler(
id: String, id: String,
songs: MutableCollection<MusicDirectory.Entry> songs: MutableCollection<MusicDirectory.Entry>
) { ) {
if (songs.size > MAX_SONGS) { if (songs.size > maxSongs) {
return return
} }
val musicService = getMusicService(activity) val musicService = getMusicService(activity)

View File

@ -9,6 +9,9 @@ import org.moire.ultrasonic.util.ImageLoader
import org.moire.ultrasonic.util.LegacyImageLoader import org.moire.ultrasonic.util.LegacyImageLoader
import org.moire.ultrasonic.util.Util import org.moire.ultrasonic.util.Util
/**
* Handles the lifetime of the Image Loader
*/
class ImageLoaderProvider(val context: Context) { class ImageLoaderProvider(val context: Context) {
private var imageLoader: ImageLoader? = null private var imageLoader: ImageLoader? = null
@ -32,13 +35,13 @@ class ImageLoaderProvider(val context: Context) {
) )
val isNewImageLoaderEnabled = get(FeatureStorage::class.java) val isNewImageLoaderEnabled = get(FeatureStorage::class.java)
.isFeatureEnabled(Feature.NEW_IMAGE_DOWNLOADER) .isFeatureEnabled(Feature.NEW_IMAGE_DOWNLOADER)
if (isNewImageLoaderEnabled) { imageLoader = if (isNewImageLoaderEnabled) {
imageLoader = SubsonicImageLoaderProxy( SubsonicImageLoaderProxy(
legacyImageLoader, legacyImageLoader,
get(SubsonicImageLoader::class.java) get(SubsonicImageLoader::class.java)
) )
} else { } else {
imageLoader = legacyImageLoader legacyImageLoader
} }
imageLoader!!.startImageLoader() imageLoader!!.startImageLoader()
} }

View File

@ -5,6 +5,9 @@ import org.moire.ultrasonic.R
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
import org.moire.ultrasonic.util.Util import org.moire.ultrasonic.util.Util
/**
* Utility class for checking the availability of the network and storage
*/
class NetworkAndStorageChecker(val context: Context) { class NetworkAndStorageChecker(val context: Context) {
fun warnIfNetworkOrStorageUnavailable() { fun warnIfNetworkOrStorageUnavailable() {
if (!Util.isExternalStoragePresent()) { if (!Util.isExternalStoragePresent()) {

View File

@ -23,6 +23,9 @@ import org.moire.ultrasonic.util.TimeSpan
import org.moire.ultrasonic.util.TimeSpanPicker import org.moire.ultrasonic.util.TimeSpanPicker
import org.moire.ultrasonic.util.Util import org.moire.ultrasonic.util.Util
/**
* This class handles sharing items in the media library
*/
class ShareHandler(val context: Context) { class ShareHandler(val context: Context) {
private var shareDescription: EditText? = null private var shareDescription: EditText? = null
private var timeSpanPicker: TimeSpanPicker? = null private var timeSpanPicker: TimeSpanPicker? = null
@ -93,7 +96,7 @@ class ShareHandler(val context: Context) {
fragment.activity?.startActivity( fragment.activity?.startActivity(
Intent.createChooser( Intent.createChooser(
intent, intent,
context.getResources().getString(R.string.share_via) context.resources.getString(R.string.share_via)
) )
) )
} }

View File

@ -5,6 +5,9 @@ import org.moire.ultrasonic.R
import org.moire.ultrasonic.domain.MusicDirectory import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.util.Util import org.moire.ultrasonic.util.Util
/**
* This utility class helps starting video playback
*/
class VideoPlayer(val context: Context) { class VideoPlayer(val context: Context) {
fun playVideo(entry: MusicDirectory.Entry?) { fun playVideo(entry: MusicDirectory.Entry?) {
if (!Util.isNetworkConnected(context)) { if (!Util.isNetworkConnected(context)) {

View File

@ -1,7 +1,11 @@
package org.moire.ultrasonic.util package org.moire.ultrasonic.util
/**
* This class distributes Now Playing related events to its subscribers.
* It is a primitive implementation of a pub-sub event bus
*/
class NowPlayingEventDistributor { class NowPlayingEventDistributor {
var eventListenerList: MutableList<NowPlayingEventListener> = private var eventListenerList: MutableList<NowPlayingEventListener> =
listOf<NowPlayingEventListener>().toMutableList() listOf<NowPlayingEventListener>().toMutableList()
fun subscribe(listener: NowPlayingEventListener) { fun subscribe(listener: NowPlayingEventListener) {
@ -12,15 +16,15 @@ class NowPlayingEventDistributor {
eventListenerList.remove(listener) eventListenerList.remove(listener)
} }
fun RaiseShowNowPlayingEvent() { fun raiseShowNowPlayingEvent() {
eventListenerList.forEach { listener -> listener.onShowNowPlaying() } eventListenerList.forEach { listener -> listener.onShowNowPlaying() }
} }
fun RaiseHideNowPlayingEvent() { fun raiseHideNowPlayingEvent() {
eventListenerList.forEach { listener -> listener.onHideNowPlaying() } eventListenerList.forEach { listener -> listener.onHideNowPlaying() }
} }
fun RaiseNowPlayingDismissedEvent() { fun raiseNowPlayingDismissedEvent() {
eventListenerList.forEach { listener -> listener.onDismissNowPlaying() } eventListenerList.forEach { listener -> listener.onDismissNowPlaying() }
} }
} }

View File

@ -1,5 +1,8 @@
package org.moire.ultrasonic.util package org.moire.ultrasonic.util
/**
* Callback interface for Now Playing event subscribers
*/
interface NowPlayingEventListener { interface NowPlayingEventListener {
fun onDismissNowPlaying() fun onDismissNowPlaying()
fun onHideNowPlaying() fun onHideNowPlaying()

View File

@ -1,5 +1,9 @@
package org.moire.ultrasonic.util package org.moire.ultrasonic.util
/**
* This class distributes Theme change related events to its subscribers.
* It is a primitive implementation of a pub-sub event bus
*/
class ThemeChangedEventDistributor { class ThemeChangedEventDistributor {
var eventListenerList: MutableList<ThemeChangedEventListener> = var eventListenerList: MutableList<ThemeChangedEventListener> =
listOf<ThemeChangedEventListener>().toMutableList() listOf<ThemeChangedEventListener>().toMutableList()

View File

@ -1,5 +1,9 @@
package org.moire.ultrasonic.util package org.moire.ultrasonic.util
/**
* Callback interface for Theme change event subscribers
*/
interface ThemeChangedEventListener { interface ThemeChangedEventListener {
fun onThemeChanged() fun onThemeChanged()
} }

View File

@ -340,8 +340,8 @@ class SongView(context: Context) : UpdateView(context), Checkable {
fun maximizeOrMinimize() { fun maximizeOrMinimize() {
isMaximized = !isMaximized isMaximized = !isMaximized
viewHolder?.title?.setSingleLine(!isMaximized) viewHolder?.title?.isSingleLine = !isMaximized
viewHolder?.artist?.setSingleLine(!isMaximized) viewHolder?.artist?.isSingleLine = !isMaximized
} }
enum class ImageType { enum class ImageType {