all: remove dependence on androidviewmodel
Entirely remove dependence on AndroidViewModel, replacing it with dependency injection.
This commit is contained in:
parent
ccbd77918b
commit
138a2c3c1c
35 changed files with 282 additions and 102 deletions
|
@ -12,6 +12,9 @@ track/disc fields
|
|||
#### What's Fixed
|
||||
- Fixed non-functioning "repeat all" repeat mode
|
||||
|
||||
#### Dev/Meta
|
||||
- Started using dependency injection
|
||||
|
||||
## 3.0.2
|
||||
|
||||
#### What's New
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.oxycblt.auxio
|
|||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.view.WindowCompat
|
||||
|
@ -31,7 +32,6 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
|
|||
import org.oxycblt.auxio.playback.state.InternalPlayer
|
||||
import org.oxycblt.auxio.playback.system.PlaybackService
|
||||
import org.oxycblt.auxio.ui.UISettings
|
||||
import org.oxycblt.auxio.util.androidViewModels
|
||||
import org.oxycblt.auxio.util.isNight
|
||||
import org.oxycblt.auxio.util.logD
|
||||
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
||||
|
@ -53,7 +53,7 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat
|
|||
*/
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : AppCompatActivity() {
|
||||
private val playbackModel: PlaybackViewModel by androidViewModels()
|
||||
private val playbackModel: PlaybackViewModel by viewModels()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
|
|
@ -58,7 +58,7 @@ class MainFragment :
|
|||
ViewBindingFragment<FragmentMainBinding>(),
|
||||
ViewTreeObserver.OnPreDrawListener,
|
||||
NavController.OnDestinationChangedListener {
|
||||
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
private val navModel: NavigationViewModel by activityViewModels()
|
||||
private val selectionModel: SelectionViewModel by activityViewModels()
|
||||
private val callback = DynamicBackPressedCallback()
|
||||
|
|
|
@ -54,7 +54,7 @@ class AlbumDetailFragment :
|
|||
ListFragment<Song, FragmentDetailBinding>(), AlbumDetailAdapter.Listener {
|
||||
private val detailModel: DetailViewModel by activityViewModels()
|
||||
override val navModel: NavigationViewModel by activityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||
// Information about what album to display is initially within the navigation arguments
|
||||
// as a UID, as that is the only safe way to parcel an album.
|
||||
|
|
|
@ -42,7 +42,6 @@ import org.oxycblt.auxio.music.Song
|
|||
import org.oxycblt.auxio.music.library.Sort
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.collect
|
||||
import org.oxycblt.auxio.util.collectImmediately
|
||||
import org.oxycblt.auxio.util.logD
|
||||
|
@ -58,7 +57,7 @@ class ArtistDetailFragment :
|
|||
ListFragment<Music, FragmentDetailBinding>(), DetailAdapter.Listener<Music> {
|
||||
private val detailModel: DetailViewModel by activityViewModels()
|
||||
override val navModel: NavigationViewModel by activityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||
// Information about what artist to display is initially within the navigation arguments
|
||||
// as a UID, as that is the only safe way to parcel an artist.
|
||||
|
|
|
@ -20,7 +20,10 @@ package org.oxycblt.auxio.detail
|
|||
import android.app.Application
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
@ -47,12 +50,15 @@ import org.oxycblt.auxio.util.*
|
|||
* @param application [Application] context required to initialize certain information.
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*/
|
||||
class DetailViewModel(application: Application) :
|
||||
AndroidViewModel(application), MusicRepository.Listener {
|
||||
@HiltViewModel
|
||||
class DetailViewModel
|
||||
@Inject
|
||||
constructor(
|
||||
private val audioInfoProvider: AudioInfo.Provider,
|
||||
private val musicSettings: MusicSettings,
|
||||
private val playbackSettings: PlaybackSettings
|
||||
) : ViewModel(), MusicRepository.Listener {
|
||||
private val musicRepository = MusicRepository.get()
|
||||
private val musicSettings = MusicSettings.from(application)
|
||||
private val playbackSettings = PlaybackSettings.from(application)
|
||||
private val audioInfoProvider = AudioInfo.Provider.from(application)
|
||||
|
||||
private var currentSongJob: Job? = null
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@ import org.oxycblt.auxio.music.Song
|
|||
import org.oxycblt.auxio.music.library.Sort
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.collect
|
||||
import org.oxycblt.auxio.util.collectImmediately
|
||||
import org.oxycblt.auxio.util.logD
|
||||
|
@ -59,7 +58,7 @@ class GenreDetailFragment :
|
|||
ListFragment<Music, FragmentDetailBinding>(), DetailAdapter.Listener<Music> {
|
||||
private val detailModel: DetailViewModel by activityViewModels()
|
||||
override val navModel: NavigationViewModel by activityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||
// Information about what genre to display is initially within the navigation arguments
|
||||
// as a UID, as that is the only safe way to parcel an genre.
|
||||
|
|
|
@ -22,6 +22,7 @@ import android.text.format.Formatter
|
|||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
@ -31,7 +32,6 @@ import org.oxycblt.auxio.music.Song
|
|||
import org.oxycblt.auxio.music.format.AudioInfo
|
||||
import org.oxycblt.auxio.playback.formatDurationMs
|
||||
import org.oxycblt.auxio.ui.ViewBindingDialogFragment
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.collectImmediately
|
||||
|
||||
/**
|
||||
|
@ -40,7 +40,7 @@ import org.oxycblt.auxio.util.collectImmediately
|
|||
*/
|
||||
@AndroidEntryPoint
|
||||
class SongDetailDialog : ViewBindingDialogFragment<DialogSongDetailBinding>() {
|
||||
private val detailModel: DetailViewModel by androidActivityViewModels()
|
||||
private val detailModel: DetailViewModel by activityViewModels()
|
||||
// Information about what song to display is initially within the navigation arguments
|
||||
// as a UID, as that is the only safe way to parcel an song.
|
||||
private val args: SongDetailDialogArgs by navArgs()
|
||||
|
|
|
@ -68,10 +68,10 @@ import org.oxycblt.auxio.util.*
|
|||
@AndroidEntryPoint
|
||||
class HomeFragment :
|
||||
SelectionFragment<FragmentHomeBinding>(), AppBarLayout.OnOffsetChangedListener {
|
||||
private val homeModel: HomeViewModel by androidActivityViewModels()
|
||||
private val homeModel: HomeViewModel by activityViewModels()
|
||||
private val musicModel: MusicViewModel by activityViewModels()
|
||||
private val navModel: NavigationViewModel by activityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||
private var storagePermissionLauncher: ActivityResultLauncher<String>? = null
|
||||
|
||||
|
|
31
app/src/main/java/org/oxycblt/auxio/home/HomeModule.kt
Normal file
31
app/src/main/java/org/oxycblt/auxio/home/HomeModule.kt
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Auxio Project
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.home
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class HomeModule {
|
||||
@Provides fun settings(@ApplicationContext context: Context) = HomeSettings.from(context)
|
||||
}
|
|
@ -17,8 +17,9 @@
|
|||
|
||||
package org.oxycblt.auxio.home
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.ViewModel
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import org.oxycblt.auxio.home.tabs.Tab
|
||||
|
@ -32,12 +33,15 @@ import org.oxycblt.auxio.util.logD
|
|||
* The ViewModel for managing the tab data and lists of the home view.
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*/
|
||||
class HomeViewModel(application: Application) :
|
||||
AndroidViewModel(application), MusicRepository.Listener, HomeSettings.Listener {
|
||||
@HiltViewModel
|
||||
class HomeViewModel
|
||||
@Inject
|
||||
constructor(
|
||||
private val homeSettings: HomeSettings,
|
||||
private val playbackSettings: PlaybackSettings,
|
||||
private val musicSettings: MusicSettings
|
||||
) : ViewModel(), MusicRepository.Listener, HomeSettings.Listener {
|
||||
private val musicRepository = MusicRepository.get()
|
||||
private val homeSettings = HomeSettings.from(application)
|
||||
private val musicSettings = MusicSettings.from(application)
|
||||
private val playbackSettings = PlaybackSettings.from(application)
|
||||
|
||||
private val _songsList = MutableStateFlow(listOf<Song>())
|
||||
/** A list of [Song]s, sorted by the preferred [Sort], to be shown in the home view. */
|
||||
|
|
|
@ -42,7 +42,6 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
|
|||
import org.oxycblt.auxio.playback.formatDurationMs
|
||||
import org.oxycblt.auxio.playback.secsToMs
|
||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.collectImmediately
|
||||
|
||||
/**
|
||||
|
@ -56,7 +55,7 @@ class AlbumListFragment :
|
|||
FastScrollRecyclerView.PopupProvider {
|
||||
private val homeModel: HomeViewModel by activityViewModels()
|
||||
override val navModel: NavigationViewModel by activityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||
private val albumAdapter = AlbumAdapter(this)
|
||||
// Save memory by re-using the same formatter and string builder when creating popup text
|
||||
|
|
|
@ -42,7 +42,6 @@ import org.oxycblt.auxio.music.library.Sort
|
|||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.playback.formatDurationMs
|
||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.collectImmediately
|
||||
import org.oxycblt.auxio.util.nonZeroOrNull
|
||||
|
||||
|
@ -57,7 +56,7 @@ class ArtistListFragment :
|
|||
FastScrollRecyclerView.Listener {
|
||||
private val homeModel: HomeViewModel by activityViewModels()
|
||||
override val navModel: NavigationViewModel by activityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||
private val artistAdapter = ArtistAdapter(this)
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ import org.oxycblt.auxio.music.library.Sort
|
|||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.playback.formatDurationMs
|
||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.collectImmediately
|
||||
|
||||
/**
|
||||
|
@ -56,7 +55,7 @@ class GenreListFragment :
|
|||
FastScrollRecyclerView.Listener {
|
||||
private val homeModel: HomeViewModel by activityViewModels()
|
||||
override val navModel: NavigationViewModel by activityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||
private val genreAdapter = GenreAdapter(this)
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
|
|||
import org.oxycblt.auxio.playback.formatDurationMs
|
||||
import org.oxycblt.auxio.playback.secsToMs
|
||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.collectImmediately
|
||||
|
||||
/**
|
||||
|
@ -59,7 +58,7 @@ class SongListFragment :
|
|||
FastScrollRecyclerView.Listener {
|
||||
private val homeModel: HomeViewModel by activityViewModels()
|
||||
override val navModel: NavigationViewModel by activityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||
private val songAdapter = SongAdapter(this)
|
||||
// Save memory by re-using the same formatter and string builder when creating popup text
|
||||
|
|
31
app/src/main/java/org/oxycblt/auxio/image/ImageModule.kt
Normal file
31
app/src/main/java/org/oxycblt/auxio/image/ImageModule.kt
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Auxio Project
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.image
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class ImageModule {
|
||||
@Provides fun settings(@ApplicationContext context: Context) = ImageSettings.from(context)
|
||||
}
|
34
app/src/main/java/org/oxycblt/auxio/music/MusicModule.kt
Normal file
34
app/src/main/java/org/oxycblt/auxio/music/MusicModule.kt
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Auxio Project
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.music
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import org.oxycblt.auxio.music.format.AudioInfo
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class MusicModule {
|
||||
@Provides fun settings(@ApplicationContext context: Context) = MusicSettings.from(context)
|
||||
@Provides
|
||||
fun audioInfoProvider(@ApplicationContext context: Context) = AudioInfo.Provider.from(context)
|
||||
}
|
|
@ -28,9 +28,9 @@ import androidx.room.Room
|
|||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverter
|
||||
import androidx.room.TypeConverters
|
||||
import org.oxycblt.auxio.music.RealSong
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.music.format.Date
|
||||
import org.oxycblt.auxio.music.library.RealSong
|
||||
import org.oxycblt.auxio.music.parsing.correctWhitespace
|
||||
import org.oxycblt.auxio.music.parsing.splitEscaped
|
||||
import org.oxycblt.auxio.util.*
|
||||
|
|
|
@ -28,8 +28,8 @@ import androidx.core.database.getIntOrNull
|
|||
import androidx.core.database.getStringOrNull
|
||||
import java.io.File
|
||||
import org.oxycblt.auxio.music.MusicSettings
|
||||
import org.oxycblt.auxio.music.RealSong
|
||||
import org.oxycblt.auxio.music.format.Date
|
||||
import org.oxycblt.auxio.music.library.RealSong
|
||||
import org.oxycblt.auxio.music.parsing.parseId3v2PositionField
|
||||
import org.oxycblt.auxio.music.parsing.transformPositionField
|
||||
import org.oxycblt.auxio.music.storage.Directory
|
||||
|
|
|
@ -22,9 +22,9 @@ import androidx.core.text.isDigitsOnly
|
|||
import com.google.android.exoplayer2.MediaItem
|
||||
import com.google.android.exoplayer2.MetadataRetriever
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import org.oxycblt.auxio.music.RealSong
|
||||
import org.oxycblt.auxio.music.format.Date
|
||||
import org.oxycblt.auxio.music.format.TextTags
|
||||
import org.oxycblt.auxio.music.library.RealSong
|
||||
import org.oxycblt.auxio.music.parsing.parseId3v2PositionField
|
||||
import org.oxycblt.auxio.music.parsing.parseVorbisPositionField
|
||||
import org.oxycblt.auxio.music.storage.toAudioUri
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.music
|
||||
package org.oxycblt.auxio.music.library
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.VisibleForTesting
|
||||
|
@ -25,10 +25,16 @@ import java.text.Collator
|
|||
import java.util.UUID
|
||||
import kotlin.math.max
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.music.Album
|
||||
import org.oxycblt.auxio.music.Artist
|
||||
import org.oxycblt.auxio.music.Genre
|
||||
import org.oxycblt.auxio.music.Music
|
||||
import org.oxycblt.auxio.music.MusicMode
|
||||
import org.oxycblt.auxio.music.MusicSettings
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.music.format.Date
|
||||
import org.oxycblt.auxio.music.format.Disc
|
||||
import org.oxycblt.auxio.music.format.ReleaseType
|
||||
import org.oxycblt.auxio.music.library.Sort
|
||||
import org.oxycblt.auxio.music.parsing.parseId3GenreNames
|
||||
import org.oxycblt.auxio.music.parsing.parseMultiValue
|
||||
import org.oxycblt.auxio.music.storage.Directory
|
||||
|
@ -225,8 +231,7 @@ class RealSong(raw: Raw, musicSettings: MusicSettings) : Song {
|
|||
}
|
||||
|
||||
/** Raw information about a [RealSong] obtained from the filesystem/Extractor instances. */
|
||||
class Raw
|
||||
constructor(
|
||||
class Raw(
|
||||
/**
|
||||
* The ID of the [RealSong]'s audio file, obtained from MediaStore. Note that this ID is
|
||||
* highly unstable and should only be used for accessing the audio file.
|
||||
|
@ -438,7 +443,7 @@ class RealAlbum(val raw: Raw, override val songs: List<RealSong>) : Album {
|
|||
* These instances will be linked to this [RealArtist].
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*/
|
||||
class RealArtist constructor(private val raw: Raw, songAlbums: List<Music>) : Artist {
|
||||
class RealArtist(private val raw: Raw, songAlbums: List<Music>) : Artist {
|
||||
override val uid =
|
||||
// Attempt to use a MusicBrainz ID first before falling back to a hashed UID.
|
||||
raw.musicBrainzId?.let { Music.UID.musicBrainz(MusicMode.ARTISTS, it) }
|
||||
|
@ -569,7 +574,7 @@ class RealArtist constructor(private val raw: Raw, songAlbums: List<Music>) : Ar
|
|||
* Library-backed implementation of [RealGenre].
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*/
|
||||
class RealGenre constructor(private val raw: Raw, override val songs: List<RealSong>) : Genre {
|
||||
class RealGenre(private val raw: Raw, override val songs: List<RealSong>) : Genre {
|
||||
override val uid = Music.UID.auxio(MusicMode.GENRES) { update(raw.name) }
|
||||
override val rawName = raw.name
|
||||
override val rawSortName = rawName
|
|
@ -18,6 +18,7 @@
|
|||
package org.oxycblt.auxio.music.picker
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
@ -25,7 +26,6 @@ import org.oxycblt.auxio.databinding.DialogMusicPickerBinding
|
|||
import org.oxycblt.auxio.music.Artist
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.requireIs
|
||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||
|
||||
|
@ -35,7 +35,7 @@ import org.oxycblt.auxio.util.unlikelyToBeNull
|
|||
*/
|
||||
@AndroidEntryPoint
|
||||
class ArtistPlaybackPickerDialog : ArtistPickerDialog() {
|
||||
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
// Information about what Song to show choices for is initially within the navigation arguments
|
||||
// as UIDs, as that is the only safe way to parcel a Song.
|
||||
private val args: ArtistPlaybackPickerDialogArgs by navArgs()
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.oxycblt.auxio.music.picker
|
|||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
|
@ -32,7 +33,6 @@ import org.oxycblt.auxio.music.Genre
|
|||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.ui.ViewBindingDialogFragment
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.collectImmediately
|
||||
import org.oxycblt.auxio.util.requireIs
|
||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||
|
@ -45,7 +45,7 @@ import org.oxycblt.auxio.util.unlikelyToBeNull
|
|||
class GenrePlaybackPickerDialog :
|
||||
ViewBindingDialogFragment<DialogMusicPickerBinding>(), ClickableListListener<Genre> {
|
||||
private val pickerModel: PickerViewModel by viewModels()
|
||||
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
// Information about what Song to show choices for is initially within the navigation arguments
|
||||
// as UIDs, as that is the only safe way to parcel a Song.
|
||||
private val args: GenrePlaybackPickerDialogArgs by navArgs()
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.oxycblt.auxio.BuildConfig
|
|||
import org.oxycblt.auxio.music.*
|
||||
import org.oxycblt.auxio.music.extractor.*
|
||||
import org.oxycblt.auxio.music.library.Library
|
||||
import org.oxycblt.auxio.music.library.RealSong
|
||||
import org.oxycblt.auxio.util.logD
|
||||
import org.oxycblt.auxio.util.logE
|
||||
import org.oxycblt.auxio.util.logW
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.oxycblt.auxio.playback.state.RepeatMode
|
|||
import org.oxycblt.auxio.ui.MainNavigationAction
|
||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||
import org.oxycblt.auxio.ui.ViewBindingFragment
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.collectImmediately
|
||||
import org.oxycblt.auxio.util.getAttrColorCompat
|
||||
import org.oxycblt.auxio.util.getColorCompat
|
||||
|
@ -39,7 +38,7 @@ import org.oxycblt.auxio.util.getColorCompat
|
|||
*/
|
||||
@AndroidEntryPoint
|
||||
class PlaybackBarFragment : ViewBindingFragment<FragmentPlaybackBarBinding>() {
|
||||
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
private val navModel: NavigationViewModel by activityViewModels()
|
||||
|
||||
override fun onCreateBinding(inflater: LayoutInflater) =
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Auxio Project
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.playback
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import org.oxycblt.auxio.playback.persist.PersistenceRepository
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class PlaybackModule {
|
||||
@Provides fun settings(@ApplicationContext context: Context) = PlaybackSettings.from(context)
|
||||
|
||||
@Provides
|
||||
fun persistenceRepository(@ApplicationContext context: Context) =
|
||||
PersistenceRepository.from(context)
|
||||
}
|
|
@ -39,7 +39,6 @@ import org.oxycblt.auxio.playback.ui.StyledSeekBar
|
|||
import org.oxycblt.auxio.ui.MainNavigationAction
|
||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||
import org.oxycblt.auxio.ui.ViewBindingFragment
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.collectImmediately
|
||||
import org.oxycblt.auxio.util.showToast
|
||||
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
||||
|
@ -54,7 +53,7 @@ class PlaybackPanelFragment :
|
|||
ViewBindingFragment<FragmentPlaybackPanelBinding>(),
|
||||
Toolbar.OnMenuItemClickListener,
|
||||
StyledSeekBar.Listener {
|
||||
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
private val navModel: NavigationViewModel by activityViewModels()
|
||||
private var equalizerLauncher: ActivityResultLauncher<Intent>? = null
|
||||
|
||||
|
|
|
@ -17,9 +17,11 @@
|
|||
|
||||
package org.oxycblt.auxio.playback
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
@ -34,12 +36,15 @@ import org.oxycblt.auxio.playback.state.*
|
|||
* An [AndroidViewModel] that provides a safe UI frontend for the current playback state.
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*/
|
||||
class PlaybackViewModel(application: Application) :
|
||||
AndroidViewModel(application), PlaybackStateManager.Listener {
|
||||
private val musicSettings = MusicSettings.from(application)
|
||||
private val playbackSettings = PlaybackSettings.from(application)
|
||||
@HiltViewModel
|
||||
class PlaybackViewModel
|
||||
@Inject
|
||||
constructor(
|
||||
private val persistenceRepository: PersistenceRepository,
|
||||
private val playbackSettings: PlaybackSettings,
|
||||
private val musicSettings: MusicSettings
|
||||
) : ViewModel(), PlaybackStateManager.Listener {
|
||||
private val playbackManager = PlaybackStateManager.get()
|
||||
private val persistenceRepository = PersistenceRepository.from(application)
|
||||
private val musicRepository = MusicRepository.get()
|
||||
private var lastPositionJob: Job? = null
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ import org.oxycblt.auxio.list.adapter.BasicListInstructions
|
|||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.ui.ViewBindingFragment
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.collectImmediately
|
||||
|
||||
/**
|
||||
|
@ -42,7 +41,7 @@ import org.oxycblt.auxio.util.collectImmediately
|
|||
@AndroidEntryPoint
|
||||
class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), EditableListListener<Song> {
|
||||
private val queueModel: QueueViewModel by activityViewModels()
|
||||
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
private val queueAdapter = QueueAdapter(this)
|
||||
private var touchHelper: ItemTouchHelper? = null
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import androidx.core.view.isInvisible
|
|||
import androidx.core.view.postDelayed
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
@ -56,10 +57,10 @@ import org.oxycblt.auxio.util.*
|
|||
*/
|
||||
@AndroidEntryPoint
|
||||
class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
|
||||
private val searchModel: SearchViewModel by androidViewModels()
|
||||
override val navModel: NavigationViewModel by activityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||
private val searchModel: SearchViewModel by viewModels()
|
||||
private val searchAdapter = SearchAdapter(this)
|
||||
private var imm: InputMethodManager? = null
|
||||
private var launchedKeyboard = false
|
||||
|
|
32
app/src/main/java/org/oxycblt/auxio/search/SearchModule.kt
Normal file
32
app/src/main/java/org/oxycblt/auxio/search/SearchModule.kt
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Auxio Project
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.search
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class SearchModule {
|
||||
@Provides fun engine(@ApplicationContext context: Context) = SearchEngine.from(context)
|
||||
@Provides fun settings(@ApplicationContext context: Context) = SearchSettings.from(context)
|
||||
}
|
|
@ -17,10 +17,12 @@
|
|||
|
||||
package org.oxycblt.auxio.search
|
||||
|
||||
import android.app.Application
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
@ -39,12 +41,15 @@ import org.oxycblt.auxio.util.logD
|
|||
* An [AndroidViewModel] that keeps performs search operations and tracks their results.
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*/
|
||||
class SearchViewModel(application: Application) :
|
||||
AndroidViewModel(application), MusicRepository.Listener {
|
||||
@HiltViewModel
|
||||
class SearchViewModel
|
||||
@Inject
|
||||
constructor(
|
||||
private val searchEngine: SearchEngine,
|
||||
private val searchSettings: SearchSettings,
|
||||
private val playbackSettings: PlaybackSettings,
|
||||
) : ViewModel(), MusicRepository.Listener {
|
||||
private val musicRepository = MusicRepository.get()
|
||||
private val searchSettings = SearchSettings.from(application)
|
||||
private val playbackSettings = PlaybackSettings.from(application)
|
||||
private var searchEngine = SearchEngine.from(application)
|
||||
private var lastQuery: String? = null
|
||||
private var currentSearchJob: Job? = null
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.oxycblt.auxio.R
|
|||
import org.oxycblt.auxio.music.MusicViewModel
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.showToast
|
||||
|
||||
/**
|
||||
|
@ -38,7 +37,7 @@ import org.oxycblt.auxio.util.showToast
|
|||
*/
|
||||
@AndroidEntryPoint
|
||||
class RootPreferenceFragment : BasePreferenceFragment(R.xml.preferences_root) {
|
||||
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
private val musicModel: MusicViewModel by activityViewModels()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
|
31
app/src/main/java/org/oxycblt/auxio/ui/UIModule.kt
Normal file
31
app/src/main/java/org/oxycblt/auxio/ui/UIModule.kt
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Auxio Project
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.ui
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import org.oxycblt.auxio.image.ImageSettings
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class UIModule {
|
||||
fun settings(@ApplicationContext context: Context) = ImageSettings.from(context)
|
||||
}
|
|
@ -23,18 +23,12 @@ import android.graphics.drawable.Drawable
|
|||
import android.os.Build
|
||||
import android.view.View
|
||||
import android.view.WindowInsets
|
||||
import androidx.activity.viewModels
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
@ -196,35 +190,6 @@ private fun Fragment.launch(
|
|||
viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(state, block) }
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension to [viewModels] that automatically provides an
|
||||
* [ViewModelProvider.AndroidViewModelFactory]. Use whenever an [AndroidViewModel] is used.
|
||||
*/
|
||||
inline fun <reified T : AndroidViewModel> Fragment.androidViewModels() =
|
||||
viewModels<T> { ViewModelProvider.AndroidViewModelFactory(requireActivity().application) }
|
||||
|
||||
/**
|
||||
* An extension to [viewModels] that automatically provides an
|
||||
* [ViewModelProvider.AndroidViewModelFactory]. Use whenever an [AndroidViewModel] is used. Note
|
||||
* that this implementation is for an [AppCompatActivity], and thus makes this functionally
|
||||
* equivalent in scope to [androidActivityViewModels].
|
||||
*/
|
||||
inline fun <reified T : AndroidViewModel> AppCompatActivity.androidViewModels() =
|
||||
viewModels<T> { ViewModelProvider.AndroidViewModelFactory(application) }
|
||||
|
||||
/**
|
||||
* An extension to [activityViewModels] that automatically provides an
|
||||
* [ViewModelProvider.AndroidViewModelFactory]. Use whenever an [AndroidViewModel] is used.
|
||||
*/
|
||||
inline fun <reified T : AndroidViewModel> Fragment.androidActivityViewModels() =
|
||||
activityViewModels<T> {
|
||||
ViewModelProvider.AndroidViewModelFactory(requireActivity().application)
|
||||
}
|
||||
|
||||
/** The [Context] provided to an [AndroidViewModel]. */
|
||||
inline val AndroidViewModel.context: Context
|
||||
get() = getApplication()
|
||||
|
||||
/**
|
||||
* Get the "System Bar" [Insets] in this [WindowInsets] instance in a version-compatible manner This
|
||||
* can be used to prevent [View] elements from intersecting with the navigation bars.
|
||||
|
|
Loading…
Reference in a new issue