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
|
#### What's Fixed
|
||||||
- Fixed non-functioning "repeat all" repeat mode
|
- Fixed non-functioning "repeat all" repeat mode
|
||||||
|
|
||||||
|
#### Dev/Meta
|
||||||
|
- Started using dependency injection
|
||||||
|
|
||||||
## 3.0.2
|
## 3.0.2
|
||||||
|
|
||||||
#### What's New
|
#### What's New
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ package org.oxycblt.auxio
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.core.view.WindowCompat
|
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.state.InternalPlayer
|
||||||
import org.oxycblt.auxio.playback.system.PlaybackService
|
import org.oxycblt.auxio.playback.system.PlaybackService
|
||||||
import org.oxycblt.auxio.ui.UISettings
|
import org.oxycblt.auxio.ui.UISettings
|
||||||
import org.oxycblt.auxio.util.androidViewModels
|
|
||||||
import org.oxycblt.auxio.util.isNight
|
import org.oxycblt.auxio.util.isNight
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
||||||
|
|
@ -53,7 +53,7 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
private val playbackModel: PlaybackViewModel by androidViewModels()
|
private val playbackModel: PlaybackViewModel by viewModels()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class MainFragment :
|
||||||
ViewBindingFragment<FragmentMainBinding>(),
|
ViewBindingFragment<FragmentMainBinding>(),
|
||||||
ViewTreeObserver.OnPreDrawListener,
|
ViewTreeObserver.OnPreDrawListener,
|
||||||
NavController.OnDestinationChangedListener {
|
NavController.OnDestinationChangedListener {
|
||||||
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||||
private val navModel: NavigationViewModel by activityViewModels()
|
private val navModel: NavigationViewModel by activityViewModels()
|
||||||
private val selectionModel: SelectionViewModel by activityViewModels()
|
private val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
private val callback = DynamicBackPressedCallback()
|
private val callback = DynamicBackPressedCallback()
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ class AlbumDetailFragment :
|
||||||
ListFragment<Song, FragmentDetailBinding>(), AlbumDetailAdapter.Listener {
|
ListFragment<Song, FragmentDetailBinding>(), AlbumDetailAdapter.Listener {
|
||||||
private val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
override val navModel: NavigationViewModel 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()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
// Information about what album to display is initially within the navigation arguments
|
// 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.
|
// 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.music.library.Sort
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
|
||||||
import org.oxycblt.auxio.util.collect
|
import org.oxycblt.auxio.util.collect
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
@ -58,7 +57,7 @@ class ArtistDetailFragment :
|
||||||
ListFragment<Music, FragmentDetailBinding>(), DetailAdapter.Listener<Music> {
|
ListFragment<Music, FragmentDetailBinding>(), DetailAdapter.Listener<Music> {
|
||||||
private val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
override val navModel: NavigationViewModel 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()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
// Information about what artist to display is initially within the navigation arguments
|
// 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.
|
// 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 android.app.Application
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
@ -47,12 +50,15 @@ import org.oxycblt.auxio.util.*
|
||||||
* @param application [Application] context required to initialize certain information.
|
* @param application [Application] context required to initialize certain information.
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
class DetailViewModel(application: Application) :
|
@HiltViewModel
|
||||||
AndroidViewModel(application), MusicRepository.Listener {
|
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 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
|
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.music.library.Sort
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
|
||||||
import org.oxycblt.auxio.util.collect
|
import org.oxycblt.auxio.util.collect
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
@ -59,7 +58,7 @@ class GenreDetailFragment :
|
||||||
ListFragment<Music, FragmentDetailBinding>(), DetailAdapter.Listener<Music> {
|
ListFragment<Music, FragmentDetailBinding>(), DetailAdapter.Listener<Music> {
|
||||||
private val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
override val navModel: NavigationViewModel 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()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
// Information about what genre to display is initially within the navigation arguments
|
// 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.
|
// 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 android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.view.isInvisible
|
import androidx.core.view.isInvisible
|
||||||
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
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.music.format.AudioInfo
|
||||||
import org.oxycblt.auxio.playback.formatDurationMs
|
import org.oxycblt.auxio.playback.formatDurationMs
|
||||||
import org.oxycblt.auxio.ui.ViewBindingDialogFragment
|
import org.oxycblt.auxio.ui.ViewBindingDialogFragment
|
||||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -40,7 +40,7 @@ import org.oxycblt.auxio.util.collectImmediately
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class SongDetailDialog : ViewBindingDialogFragment<DialogSongDetailBinding>() {
|
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
|
// 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.
|
// as a UID, as that is the only safe way to parcel an song.
|
||||||
private val args: SongDetailDialogArgs by navArgs()
|
private val args: SongDetailDialogArgs by navArgs()
|
||||||
|
|
|
||||||
|
|
@ -68,10 +68,10 @@ import org.oxycblt.auxio.util.*
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class HomeFragment :
|
class HomeFragment :
|
||||||
SelectionFragment<FragmentHomeBinding>(), AppBarLayout.OnOffsetChangedListener {
|
SelectionFragment<FragmentHomeBinding>(), AppBarLayout.OnOffsetChangedListener {
|
||||||
private val homeModel: HomeViewModel by androidActivityViewModels()
|
private val homeModel: HomeViewModel by activityViewModels()
|
||||||
private val musicModel: MusicViewModel by activityViewModels()
|
private val musicModel: MusicViewModel by activityViewModels()
|
||||||
private val navModel: NavigationViewModel 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()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
private var storagePermissionLauncher: ActivityResultLauncher<String>? = null
|
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
|
package org.oxycblt.auxio.home
|
||||||
|
|
||||||
import android.app.Application
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import org.oxycblt.auxio.home.tabs.Tab
|
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.
|
* The ViewModel for managing the tab data and lists of the home view.
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
class HomeViewModel(application: Application) :
|
@HiltViewModel
|
||||||
AndroidViewModel(application), MusicRepository.Listener, HomeSettings.Listener {
|
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 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>())
|
private val _songsList = MutableStateFlow(listOf<Song>())
|
||||||
/** A list of [Song]s, sorted by the preferred [Sort], to be shown in the home view. */
|
/** 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.formatDurationMs
|
||||||
import org.oxycblt.auxio.playback.secsToMs
|
import org.oxycblt.auxio.playback.secsToMs
|
||||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -56,7 +55,7 @@ class AlbumListFragment :
|
||||||
FastScrollRecyclerView.PopupProvider {
|
FastScrollRecyclerView.PopupProvider {
|
||||||
private val homeModel: HomeViewModel by activityViewModels()
|
private val homeModel: HomeViewModel by activityViewModels()
|
||||||
override val navModel: NavigationViewModel 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()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
private val albumAdapter = AlbumAdapter(this)
|
private val albumAdapter = AlbumAdapter(this)
|
||||||
// Save memory by re-using the same formatter and string builder when creating popup text
|
// 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.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.playback.formatDurationMs
|
import org.oxycblt.auxio.playback.formatDurationMs
|
||||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
import org.oxycblt.auxio.util.nonZeroOrNull
|
import org.oxycblt.auxio.util.nonZeroOrNull
|
||||||
|
|
||||||
|
|
@ -57,7 +56,7 @@ class ArtistListFragment :
|
||||||
FastScrollRecyclerView.Listener {
|
FastScrollRecyclerView.Listener {
|
||||||
private val homeModel: HomeViewModel by activityViewModels()
|
private val homeModel: HomeViewModel by activityViewModels()
|
||||||
override val navModel: NavigationViewModel 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()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
private val artistAdapter = ArtistAdapter(this)
|
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.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.playback.formatDurationMs
|
import org.oxycblt.auxio.playback.formatDurationMs
|
||||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -56,7 +55,7 @@ class GenreListFragment :
|
||||||
FastScrollRecyclerView.Listener {
|
FastScrollRecyclerView.Listener {
|
||||||
private val homeModel: HomeViewModel by activityViewModels()
|
private val homeModel: HomeViewModel by activityViewModels()
|
||||||
override val navModel: NavigationViewModel 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()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
private val genreAdapter = GenreAdapter(this)
|
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.formatDurationMs
|
||||||
import org.oxycblt.auxio.playback.secsToMs
|
import org.oxycblt.auxio.playback.secsToMs
|
||||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,7 +58,7 @@ class SongListFragment :
|
||||||
FastScrollRecyclerView.Listener {
|
FastScrollRecyclerView.Listener {
|
||||||
private val homeModel: HomeViewModel by activityViewModels()
|
private val homeModel: HomeViewModel by activityViewModels()
|
||||||
override val navModel: NavigationViewModel 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()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
private val songAdapter = SongAdapter(this)
|
private val songAdapter = SongAdapter(this)
|
||||||
// Save memory by re-using the same formatter and string builder when creating popup text
|
// 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.RoomDatabase
|
||||||
import androidx.room.TypeConverter
|
import androidx.room.TypeConverter
|
||||||
import androidx.room.TypeConverters
|
import androidx.room.TypeConverters
|
||||||
import org.oxycblt.auxio.music.RealSong
|
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.music.format.Date
|
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.correctWhitespace
|
||||||
import org.oxycblt.auxio.music.parsing.splitEscaped
|
import org.oxycblt.auxio.music.parsing.splitEscaped
|
||||||
import org.oxycblt.auxio.util.*
|
import org.oxycblt.auxio.util.*
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ import androidx.core.database.getIntOrNull
|
||||||
import androidx.core.database.getStringOrNull
|
import androidx.core.database.getStringOrNull
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import org.oxycblt.auxio.music.MusicSettings
|
import org.oxycblt.auxio.music.MusicSettings
|
||||||
import org.oxycblt.auxio.music.RealSong
|
|
||||||
import org.oxycblt.auxio.music.format.Date
|
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.parseId3v2PositionField
|
||||||
import org.oxycblt.auxio.music.parsing.transformPositionField
|
import org.oxycblt.auxio.music.parsing.transformPositionField
|
||||||
import org.oxycblt.auxio.music.storage.Directory
|
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.MediaItem
|
||||||
import com.google.android.exoplayer2.MetadataRetriever
|
import com.google.android.exoplayer2.MetadataRetriever
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
import org.oxycblt.auxio.music.RealSong
|
|
||||||
import org.oxycblt.auxio.music.format.Date
|
import org.oxycblt.auxio.music.format.Date
|
||||||
import org.oxycblt.auxio.music.format.TextTags
|
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.parseId3v2PositionField
|
||||||
import org.oxycblt.auxio.music.parsing.parseVorbisPositionField
|
import org.oxycblt.auxio.music.parsing.parseVorbisPositionField
|
||||||
import org.oxycblt.auxio.music.storage.toAudioUri
|
import org.oxycblt.auxio.music.storage.toAudioUri
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* 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 android.content.Context
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
|
|
@ -25,10 +25,16 @@ import java.text.Collator
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import org.oxycblt.auxio.R
|
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.Date
|
||||||
import org.oxycblt.auxio.music.format.Disc
|
import org.oxycblt.auxio.music.format.Disc
|
||||||
import org.oxycblt.auxio.music.format.ReleaseType
|
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.parseId3GenreNames
|
||||||
import org.oxycblt.auxio.music.parsing.parseMultiValue
|
import org.oxycblt.auxio.music.parsing.parseMultiValue
|
||||||
import org.oxycblt.auxio.music.storage.Directory
|
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. */
|
/** Raw information about a [RealSong] obtained from the filesystem/Extractor instances. */
|
||||||
class Raw
|
class Raw(
|
||||||
constructor(
|
|
||||||
/**
|
/**
|
||||||
* The ID of the [RealSong]'s audio file, obtained from MediaStore. Note that this ID is
|
* 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.
|
* 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].
|
* These instances will be linked to this [RealArtist].
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @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 =
|
override val uid =
|
||||||
// Attempt to use a MusicBrainz ID first before falling back to a hashed UID.
|
// Attempt to use a MusicBrainz ID first before falling back to a hashed UID.
|
||||||
raw.musicBrainzId?.let { Music.UID.musicBrainz(MusicMode.ARTISTS, it) }
|
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].
|
* Library-backed implementation of [RealGenre].
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @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 uid = Music.UID.auxio(MusicMode.GENRES) { update(raw.name) }
|
||||||
override val rawName = raw.name
|
override val rawName = raw.name
|
||||||
override val rawSortName = rawName
|
override val rawSortName = rawName
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
package org.oxycblt.auxio.music.picker
|
package org.oxycblt.auxio.music.picker
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
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.Artist
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
|
||||||
import org.oxycblt.auxio.util.requireIs
|
import org.oxycblt.auxio.util.requireIs
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class ArtistPlaybackPickerDialog : ArtistPickerDialog() {
|
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
|
// 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.
|
// as UIDs, as that is the only safe way to parcel a Song.
|
||||||
private val args: ArtistPlaybackPickerDialogArgs by navArgs()
|
private val args: ArtistPlaybackPickerDialogArgs by navArgs()
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ package org.oxycblt.auxio.music.picker
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
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.music.Song
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.ui.ViewBindingDialogFragment
|
import org.oxycblt.auxio.ui.ViewBindingDialogFragment
|
||||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
import org.oxycblt.auxio.util.requireIs
|
import org.oxycblt.auxio.util.requireIs
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
@ -45,7 +45,7 @@ import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
class GenrePlaybackPickerDialog :
|
class GenrePlaybackPickerDialog :
|
||||||
ViewBindingDialogFragment<DialogMusicPickerBinding>(), ClickableListListener<Genre> {
|
ViewBindingDialogFragment<DialogMusicPickerBinding>(), ClickableListListener<Genre> {
|
||||||
private val pickerModel: PickerViewModel by viewModels()
|
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
|
// 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.
|
// as UIDs, as that is the only safe way to parcel a Song.
|
||||||
private val args: GenrePlaybackPickerDialogArgs by navArgs()
|
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.*
|
||||||
import org.oxycblt.auxio.music.extractor.*
|
import org.oxycblt.auxio.music.extractor.*
|
||||||
import org.oxycblt.auxio.music.library.Library
|
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.logD
|
||||||
import org.oxycblt.auxio.util.logE
|
import org.oxycblt.auxio.util.logE
|
||||||
import org.oxycblt.auxio.util.logW
|
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.MainNavigationAction
|
||||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||||
import org.oxycblt.auxio.ui.ViewBindingFragment
|
import org.oxycblt.auxio.ui.ViewBindingFragment
|
||||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
import org.oxycblt.auxio.util.getAttrColorCompat
|
import org.oxycblt.auxio.util.getAttrColorCompat
|
||||||
import org.oxycblt.auxio.util.getColorCompat
|
import org.oxycblt.auxio.util.getColorCompat
|
||||||
|
|
@ -39,7 +38,7 @@ import org.oxycblt.auxio.util.getColorCompat
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class PlaybackBarFragment : ViewBindingFragment<FragmentPlaybackBarBinding>() {
|
class PlaybackBarFragment : ViewBindingFragment<FragmentPlaybackBarBinding>() {
|
||||||
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||||
private val navModel: NavigationViewModel by activityViewModels()
|
private val navModel: NavigationViewModel by activityViewModels()
|
||||||
|
|
||||||
override fun onCreateBinding(inflater: LayoutInflater) =
|
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.MainNavigationAction
|
||||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||||
import org.oxycblt.auxio.ui.ViewBindingFragment
|
import org.oxycblt.auxio.ui.ViewBindingFragment
|
||||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
import org.oxycblt.auxio.util.showToast
|
import org.oxycblt.auxio.util.showToast
|
||||||
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
||||||
|
|
@ -54,7 +53,7 @@ class PlaybackPanelFragment :
|
||||||
ViewBindingFragment<FragmentPlaybackPanelBinding>(),
|
ViewBindingFragment<FragmentPlaybackPanelBinding>(),
|
||||||
Toolbar.OnMenuItemClickListener,
|
Toolbar.OnMenuItemClickListener,
|
||||||
StyledSeekBar.Listener {
|
StyledSeekBar.Listener {
|
||||||
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||||
private val navModel: NavigationViewModel by activityViewModels()
|
private val navModel: NavigationViewModel by activityViewModels()
|
||||||
private var equalizerLauncher: ActivityResultLauncher<Intent>? = null
|
private var equalizerLauncher: ActivityResultLauncher<Intent>? = null
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,11 @@
|
||||||
|
|
||||||
package org.oxycblt.auxio.playback
|
package org.oxycblt.auxio.playback
|
||||||
|
|
||||||
import android.app.Application
|
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
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.
|
* An [AndroidViewModel] that provides a safe UI frontend for the current playback state.
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
class PlaybackViewModel(application: Application) :
|
@HiltViewModel
|
||||||
AndroidViewModel(application), PlaybackStateManager.Listener {
|
class PlaybackViewModel
|
||||||
private val musicSettings = MusicSettings.from(application)
|
@Inject
|
||||||
private val playbackSettings = PlaybackSettings.from(application)
|
constructor(
|
||||||
|
private val persistenceRepository: PersistenceRepository,
|
||||||
|
private val playbackSettings: PlaybackSettings,
|
||||||
|
private val musicSettings: MusicSettings
|
||||||
|
) : ViewModel(), PlaybackStateManager.Listener {
|
||||||
private val playbackManager = PlaybackStateManager.get()
|
private val playbackManager = PlaybackStateManager.get()
|
||||||
private val persistenceRepository = PersistenceRepository.from(application)
|
|
||||||
private val musicRepository = MusicRepository.get()
|
private val musicRepository = MusicRepository.get()
|
||||||
private var lastPositionJob: Job? = null
|
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.music.Song
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.ui.ViewBindingFragment
|
import org.oxycblt.auxio.ui.ViewBindingFragment
|
||||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -42,7 +41,7 @@ import org.oxycblt.auxio.util.collectImmediately
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), EditableListListener<Song> {
|
class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), EditableListListener<Song> {
|
||||||
private val queueModel: QueueViewModel by activityViewModels()
|
private val queueModel: QueueViewModel by activityViewModels()
|
||||||
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||||
private val queueAdapter = QueueAdapter(this)
|
private val queueAdapter = QueueAdapter(this)
|
||||||
private var touchHelper: ItemTouchHelper? = null
|
private var touchHelper: ItemTouchHelper? = null
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import androidx.core.view.isInvisible
|
||||||
import androidx.core.view.postDelayed
|
import androidx.core.view.postDelayed
|
||||||
import androidx.core.widget.addTextChangedListener
|
import androidx.core.widget.addTextChangedListener
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.google.android.material.transition.MaterialSharedAxis
|
import com.google.android.material.transition.MaterialSharedAxis
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|
@ -56,10 +57,10 @@ import org.oxycblt.auxio.util.*
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
|
class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
|
||||||
private val searchModel: SearchViewModel by androidViewModels()
|
|
||||||
override val navModel: NavigationViewModel 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()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
|
private val searchModel: SearchViewModel by viewModels()
|
||||||
private val searchAdapter = SearchAdapter(this)
|
private val searchAdapter = SearchAdapter(this)
|
||||||
private var imm: InputMethodManager? = null
|
private var imm: InputMethodManager? = null
|
||||||
private var launchedKeyboard = false
|
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
|
package org.oxycblt.auxio.search
|
||||||
|
|
||||||
import android.app.Application
|
|
||||||
import androidx.annotation.IdRes
|
import androidx.annotation.IdRes
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
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.
|
* An [AndroidViewModel] that keeps performs search operations and tracks their results.
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
class SearchViewModel(application: Application) :
|
@HiltViewModel
|
||||||
AndroidViewModel(application), MusicRepository.Listener {
|
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 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 lastQuery: String? = null
|
||||||
private var currentSearchJob: Job? = 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.music.MusicViewModel
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
|
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
|
||||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
|
||||||
import org.oxycblt.auxio.util.showToast
|
import org.oxycblt.auxio.util.showToast
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -38,7 +37,7 @@ import org.oxycblt.auxio.util.showToast
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class RootPreferenceFragment : BasePreferenceFragment(R.xml.preferences_root) {
|
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()
|
private val musicModel: MusicViewModel by activityViewModels()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
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.os.Build
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowInsets
|
import android.view.WindowInsets
|
||||||
import androidx.activity.viewModels
|
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.core.graphics.Insets
|
import androidx.core.graphics.Insets
|
||||||
import androidx.core.graphics.drawable.DrawableCompat
|
import androidx.core.graphics.drawable.DrawableCompat
|
||||||
import androidx.fragment.app.Fragment
|
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.Lifecycle
|
||||||
import androidx.lifecycle.ViewModelProvider
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
|
@ -196,35 +190,6 @@ private fun Fragment.launch(
|
||||||
viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(state, block) }
|
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
|
* 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.
|
* can be used to prevent [View] elements from intersecting with the navigation bars.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue