musikr: remove trivial auxio dependence
There's still some thorny resource use left over, but this is a good starting point to start breaking off musikr from auxio.
This commit is contained in:
parent
3da9e6c5b3
commit
de1c091517
39 changed files with 324 additions and 203 deletions
|
@ -31,6 +31,7 @@ import org.oxycblt.auxio.list.ListFragment
|
|||
import org.oxycblt.auxio.list.menu.Menu
|
||||
import org.oxycblt.auxio.music.PlaylistDecision
|
||||
import org.oxycblt.auxio.music.PlaylistMessage
|
||||
import org.oxycblt.auxio.music.resolveNames
|
||||
import org.oxycblt.auxio.playback.PlaybackDecision
|
||||
import org.oxycblt.auxio.playback.formatDurationMs
|
||||
import org.oxycblt.auxio.util.collect
|
||||
|
@ -43,7 +44,6 @@ import org.oxycblt.musikr.Album
|
|||
import org.oxycblt.musikr.Music
|
||||
import org.oxycblt.musikr.MusicParent
|
||||
import org.oxycblt.musikr.Song
|
||||
import org.oxycblt.musikr.resolveNames
|
||||
import timber.log.Timber as L
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.oxycblt.auxio.list.ListFragment
|
|||
import org.oxycblt.auxio.list.menu.Menu
|
||||
import org.oxycblt.auxio.music.PlaylistDecision
|
||||
import org.oxycblt.auxio.music.PlaylistMessage
|
||||
import org.oxycblt.auxio.music.resolveNames
|
||||
import org.oxycblt.auxio.playback.PlaybackDecision
|
||||
import org.oxycblt.auxio.util.collect
|
||||
import org.oxycblt.auxio.util.collectImmediately
|
||||
|
@ -43,7 +44,6 @@ import org.oxycblt.musikr.Artist
|
|||
import org.oxycblt.musikr.Music
|
||||
import org.oxycblt.musikr.MusicParent
|
||||
import org.oxycblt.musikr.Song
|
||||
import org.oxycblt.musikr.resolveNames
|
||||
import timber.log.Timber as L
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.oxycblt.auxio.databinding.DialogSongDetailBinding
|
|||
import org.oxycblt.auxio.detail.list.SongProperty
|
||||
import org.oxycblt.auxio.detail.list.SongPropertyAdapter
|
||||
import org.oxycblt.auxio.list.adapter.UpdateInstructions
|
||||
import org.oxycblt.auxio.music.resolveNames
|
||||
import org.oxycblt.auxio.playback.formatDurationMs
|
||||
import org.oxycblt.auxio.playback.replaygain.formatDb
|
||||
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
|
||||
|
@ -40,7 +41,6 @@ import org.oxycblt.auxio.util.concatLocalized
|
|||
import org.oxycblt.musikr.Music
|
||||
import org.oxycblt.musikr.Song
|
||||
import org.oxycblt.musikr.metadata.AudioProperties
|
||||
import org.oxycblt.musikr.resolveNames
|
||||
import org.oxycblt.musikr.tag.Name
|
||||
import timber.log.Timber as L
|
||||
|
||||
|
|
|
@ -40,12 +40,12 @@ import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
|
|||
import org.oxycblt.auxio.list.adapter.SimpleDiffCallback
|
||||
import org.oxycblt.auxio.list.recycler.MaterialDragCallback
|
||||
import org.oxycblt.auxio.list.recycler.SongViewHolder
|
||||
import org.oxycblt.auxio.music.resolveNames
|
||||
import org.oxycblt.auxio.util.context
|
||||
import org.oxycblt.auxio.util.getAttrColorCompat
|
||||
import org.oxycblt.auxio.util.inflater
|
||||
import org.oxycblt.musikr.Playlist
|
||||
import org.oxycblt.musikr.Song
|
||||
import org.oxycblt.musikr.resolveNames
|
||||
import timber.log.Timber as L
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,7 +23,6 @@ import android.view.ViewGroup
|
|||
import androidx.annotation.StringRes
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.oxycblt.auxio.databinding.ItemSongPropertyBinding
|
||||
import org.oxycblt.auxio.list.Item
|
||||
import org.oxycblt.auxio.list.adapter.FlexibleListAdapter
|
||||
import org.oxycblt.auxio.list.adapter.SimpleDiffCallback
|
||||
import org.oxycblt.auxio.list.recycler.DialogRecyclerView
|
||||
|
@ -53,7 +52,7 @@ class SongPropertyAdapter :
|
|||
* @param value The value of the property.
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*/
|
||||
data class SongProperty(@StringRes val name: Int, val value: String) : Item
|
||||
data class SongProperty(@StringRes val name: Int, val value: String)
|
||||
|
||||
/**
|
||||
* A [RecyclerView.ViewHolder] that displays a [SongProperty]. Use [from] to create an instance.
|
||||
|
|
|
@ -22,9 +22,9 @@ import androidx.annotation.StringRes
|
|||
|
||||
// TODO: Consider breaking this up into sealed classes for individual adapters
|
||||
/** A marker for something that is a RecyclerView item. Has no functionality on it's own. */
|
||||
interface Item
|
||||
typealias Item = Any
|
||||
|
||||
interface Header : Item
|
||||
interface Header
|
||||
|
||||
/**
|
||||
* A "header" used for delimiting groups of data.
|
||||
|
@ -44,7 +44,7 @@ interface PlainHeader : Header {
|
|||
*/
|
||||
data class BasicHeader(@StringRes override val titleRes: Int) : PlainHeader
|
||||
|
||||
interface Divider<T> : Item {
|
||||
interface Divider<T> {
|
||||
val anchor: T?
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.oxycblt.auxio.databinding.DialogMenuBinding
|
|||
import org.oxycblt.auxio.detail.DetailViewModel
|
||||
import org.oxycblt.auxio.list.ListViewModel
|
||||
import org.oxycblt.auxio.music.MusicViewModel
|
||||
import org.oxycblt.auxio.music.resolveNames
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.playback.formatDurationMs
|
||||
import org.oxycblt.auxio.util.getPlural
|
||||
|
@ -37,7 +38,6 @@ import org.oxycblt.musikr.Artist
|
|||
import org.oxycblt.musikr.Genre
|
||||
import org.oxycblt.musikr.Playlist
|
||||
import org.oxycblt.musikr.Song
|
||||
import org.oxycblt.musikr.resolveNames
|
||||
|
||||
/**
|
||||
* [MenuDialogFragment] implementation for a [Song].
|
||||
|
|
|
@ -32,6 +32,8 @@ import org.oxycblt.auxio.list.PlainDivider
|
|||
import org.oxycblt.auxio.list.SelectableListListener
|
||||
import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
|
||||
import org.oxycblt.auxio.list.adapter.SimpleDiffCallback
|
||||
import org.oxycblt.auxio.music.areNamesTheSame
|
||||
import org.oxycblt.auxio.music.resolveNames
|
||||
import org.oxycblt.auxio.util.context
|
||||
import org.oxycblt.auxio.util.getPlural
|
||||
import org.oxycblt.auxio.util.inflater
|
||||
|
@ -40,8 +42,6 @@ import org.oxycblt.musikr.Artist
|
|||
import org.oxycblt.musikr.Genre
|
||||
import org.oxycblt.musikr.Playlist
|
||||
import org.oxycblt.musikr.Song
|
||||
import org.oxycblt.musikr.areNamesTheSame
|
||||
import org.oxycblt.musikr.resolveNames
|
||||
|
||||
/**
|
||||
* A [RecyclerView.ViewHolder] that displays a [Song]. Use [from] to create an instance.
|
||||
|
|
53
app/src/main/java/org/oxycblt/auxio/music/MusicUtil.kt
Normal file
53
app/src/main/java/org/oxycblt/auxio/music/MusicUtil.kt
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Auxio Project
|
||||
* MusicUtil.kt is part of Auxio.
|
||||
*
|
||||
* 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 kotlin.math.max
|
||||
import org.oxycblt.auxio.util.concatLocalized
|
||||
import org.oxycblt.musikr.Music
|
||||
|
||||
/**
|
||||
* Run [Name.resolve] on each instance in the given list and concatenate them into a [String] in a
|
||||
* localized manner.
|
||||
*
|
||||
* @param context [Context] required
|
||||
* @return A concatenated string.
|
||||
*/
|
||||
fun <T : Music> List<T>.resolveNames(context: Context) =
|
||||
concatLocalized(context) { it.name.resolve(context) }
|
||||
|
||||
/**
|
||||
* Returns if [Music.name] matches for each item in a list. Useful for scenarios where the display
|
||||
* information of an item must be compared without a context.
|
||||
*
|
||||
* @param other The list of items to compare to.
|
||||
* @return True if they are the same (by [Music.name]), false otherwise.
|
||||
*/
|
||||
fun <T : Music> List<T>.areNamesTheSame(other: List<T>): Boolean {
|
||||
for (i in 0 until max(size, other.size)) {
|
||||
val a = getOrNull(i) ?: return false
|
||||
val b = other.getOrNull(i) ?: return false
|
||||
if (a.name != b.name) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Auxio Project
|
||||
* ReplayGainPreAmp.kt is part of Auxio.
|
||||
*
|
||||
* 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
|
||||
|
||||
/**
|
||||
* The current ReplayGain pre-amp configuration.
|
||||
*
|
||||
* @param with The pre-amp (in dB) to use when ReplayGain tags are present.
|
||||
* @param without The pre-amp (in dB) to use when ReplayGain tags are not present.
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*/
|
||||
data class ReplayGainPreAmp(val with: Float, val without: Float)
|
|
@ -25,7 +25,6 @@ import javax.inject.Inject
|
|||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.list.Item
|
||||
import org.oxycblt.auxio.list.sort.Sort
|
||||
import org.oxycblt.auxio.music.MusicRepository
|
||||
import org.oxycblt.auxio.music.PlaylistDecision
|
||||
|
@ -354,4 +353,4 @@ sealed interface ChosenName {
|
|||
* [Playlist].
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*/
|
||||
data class PlaylistChoice(val playlist: Playlist, val alreadyAdded: Boolean) : Item
|
||||
data class PlaylistChoice(val playlist: Playlist, val alreadyAdded: Boolean)
|
||||
|
|
|
@ -27,6 +27,7 @@ import androidx.annotation.StringRes
|
|||
import androidx.media.utils.MediaConstants
|
||||
import org.oxycblt.auxio.BuildConfig
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.music.resolveNames
|
||||
import org.oxycblt.auxio.playback.formatDurationDs
|
||||
import org.oxycblt.auxio.util.getPlural
|
||||
import org.oxycblt.musikr.Album
|
||||
|
@ -36,7 +37,6 @@ import org.oxycblt.musikr.Music
|
|||
import org.oxycblt.musikr.MusicParent
|
||||
import org.oxycblt.musikr.Playlist
|
||||
import org.oxycblt.musikr.Song
|
||||
import org.oxycblt.musikr.resolveNames
|
||||
|
||||
sealed interface MediaSessionUID {
|
||||
data class Tab(val node: TabNode) : MediaSessionUID {
|
||||
|
|
|
@ -26,13 +26,13 @@ import dagger.hilt.android.AndroidEntryPoint
|
|||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.databinding.FragmentPlaybackBarBinding
|
||||
import org.oxycblt.auxio.detail.DetailViewModel
|
||||
import org.oxycblt.auxio.music.resolveNames
|
||||
import org.oxycblt.auxio.playback.state.RepeatMode
|
||||
import org.oxycblt.auxio.ui.ViewBindingFragment
|
||||
import org.oxycblt.auxio.util.collectImmediately
|
||||
import org.oxycblt.auxio.util.getAttrColorCompat
|
||||
import org.oxycblt.auxio.util.getColorCompat
|
||||
import org.oxycblt.musikr.Song
|
||||
import org.oxycblt.musikr.resolveNames
|
||||
import timber.log.Timber as L
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.oxycblt.auxio.R
|
|||
import org.oxycblt.auxio.databinding.FragmentPlaybackPanelBinding
|
||||
import org.oxycblt.auxio.detail.DetailViewModel
|
||||
import org.oxycblt.auxio.list.ListViewModel
|
||||
import org.oxycblt.auxio.music.resolveNames
|
||||
import org.oxycblt.auxio.playback.state.RepeatMode
|
||||
import org.oxycblt.auxio.playback.ui.StyledSeekBar
|
||||
import org.oxycblt.auxio.playback.ui.SwipeCoverView
|
||||
|
@ -44,7 +45,6 @@ import org.oxycblt.auxio.util.showToast
|
|||
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
||||
import org.oxycblt.musikr.MusicParent
|
||||
import org.oxycblt.musikr.Song
|
||||
import org.oxycblt.musikr.resolveNames
|
||||
import timber.log.Timber as L
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,8 +24,8 @@ import dagger.hilt.android.qualifiers.ApplicationContext
|
|||
import javax.inject.Inject
|
||||
import org.oxycblt.auxio.IntegerTable
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.music.ReplayGainPreAmp
|
||||
import org.oxycblt.auxio.playback.replaygain.ReplayGainMode
|
||||
import org.oxycblt.auxio.playback.replaygain.ReplayGainPreAmp
|
||||
import org.oxycblt.auxio.settings.Settings
|
||||
import timber.log.Timber as L
|
||||
|
||||
|
|
|
@ -32,11 +32,11 @@ import org.oxycblt.auxio.list.adapter.FlexibleListAdapter
|
|||
import org.oxycblt.auxio.list.adapter.PlayingIndicatorAdapter
|
||||
import org.oxycblt.auxio.list.recycler.MaterialDragCallback
|
||||
import org.oxycblt.auxio.list.recycler.SongViewHolder
|
||||
import org.oxycblt.auxio.music.resolveNames
|
||||
import org.oxycblt.auxio.util.context
|
||||
import org.oxycblt.auxio.util.getAttrColorCompat
|
||||
import org.oxycblt.auxio.util.inflater
|
||||
import org.oxycblt.musikr.Song
|
||||
import org.oxycblt.musikr.resolveNames
|
||||
import timber.log.Timber as L
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,6 +26,7 @@ import dagger.hilt.android.AndroidEntryPoint
|
|||
import javax.inject.Inject
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.databinding.DialogPreAmpBinding
|
||||
import org.oxycblt.auxio.music.ReplayGainPreAmp
|
||||
import org.oxycblt.auxio.playback.PlaybackSettings
|
||||
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
|
||||
import timber.log.Timber as L
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Auxio Project
|
||||
* ReplayGain.kt is part of Auxio.
|
||||
* Copyright (c) 2024 Auxio Project
|
||||
* ReplayGainMode.kt is part of Auxio.
|
||||
*
|
||||
* 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
|
||||
|
@ -18,10 +18,7 @@
|
|||
|
||||
package org.oxycblt.auxio.playback.replaygain
|
||||
|
||||
import android.content.Context
|
||||
import kotlin.math.abs
|
||||
import org.oxycblt.auxio.IntegerTable
|
||||
import org.oxycblt.auxio.R
|
||||
|
||||
/**
|
||||
* The current ReplayGain configuration.
|
||||
|
@ -55,34 +52,3 @@ enum class ReplayGainMode {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a ReplayGain adjustment to apply during song playback.
|
||||
*
|
||||
* @param track The track-specific adjustment that should be applied. Null if not available.
|
||||
* @param album A more general album-specific adjustment that should be applied. Null if not
|
||||
* available.
|
||||
*/
|
||||
data class ReplayGainAdjustment(val track: Float?, val album: Float?)
|
||||
|
||||
/**
|
||||
* The current ReplayGain pre-amp configuration.
|
||||
*
|
||||
* @param with The pre-amp (in dB) to use when ReplayGain tags are present.
|
||||
* @param without The pre-amp (in dB) to use when ReplayGain tags are not present.
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*/
|
||||
data class ReplayGainPreAmp(val with: Float, val without: Float)
|
||||
|
||||
/**
|
||||
* Format a decibel value in a human-readable format.
|
||||
*
|
||||
* @param context The context to resolve resources from.
|
||||
* @return A formatted decibel value. Will be prefixed by a + or - sign.
|
||||
*/
|
||||
fun Float.formatDb(context: Context) =
|
||||
if (this >= 0) {
|
||||
context.getString(R.string.fmt_db_pos, this)
|
||||
} else {
|
||||
context.getString(R.string.fmt_db_neg, abs(this))
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Auxio Project
|
||||
* ReplayGainUtil.kt is part of Auxio.
|
||||
*
|
||||
* 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.replaygain
|
||||
|
||||
import android.content.Context
|
||||
import kotlin.math.abs
|
||||
import org.oxycblt.auxio.R
|
||||
|
||||
/**
|
||||
* Format a decibel value in a human-readable format.
|
||||
*
|
||||
* @param context The context to resolve resources from.
|
||||
* @return A formatted decibel value. Will be prefixed by a + or - sign.
|
||||
*/
|
||||
fun Float.formatDb(context: Context) =
|
||||
if (this >= 0) {
|
||||
context.getString(R.string.fmt_db_pos, this)
|
||||
} else {
|
||||
context.getString(R.string.fmt_db_neg, abs(this))
|
||||
}
|
|
@ -36,6 +36,7 @@ import org.oxycblt.auxio.IntegerTable
|
|||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.image.BitmapProvider
|
||||
import org.oxycblt.auxio.image.ImageSettings
|
||||
import org.oxycblt.auxio.music.resolveNames
|
||||
import org.oxycblt.auxio.music.service.MediaSessionUID
|
||||
import org.oxycblt.auxio.music.service.toMediaDescription
|
||||
import org.oxycblt.auxio.playback.ActionMode
|
||||
|
@ -48,7 +49,6 @@ import org.oxycblt.auxio.util.newBroadcastPendingIntent
|
|||
import org.oxycblt.auxio.util.newMainPendingIntent
|
||||
import org.oxycblt.musikr.MusicParent
|
||||
import org.oxycblt.musikr.Song
|
||||
import org.oxycblt.musikr.resolveNames
|
||||
import timber.log.Timber as L
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,11 +18,8 @@
|
|||
|
||||
package org.oxycblt.auxio.util
|
||||
|
||||
import java.security.MessageDigest
|
||||
import java.util.UUID
|
||||
import kotlin.reflect.KClass
|
||||
import org.oxycblt.auxio.BuildConfig
|
||||
import org.oxycblt.musikr.tag.Date
|
||||
|
||||
/**
|
||||
* Sanitizes a value that is unlikely to be null. On debug builds, this aliases to [requireNotNull],
|
||||
|
@ -43,28 +40,6 @@ fun <T> unlikelyToBeNull(value: T?) =
|
|||
*/
|
||||
fun Int.positiveOrNull() = if (this > 0) this else null
|
||||
|
||||
/**
|
||||
* Aliases a check to ensure that the given number is non-zero.
|
||||
*
|
||||
* @return The same number if it's non-zero, null otherwise.
|
||||
*/
|
||||
fun Long.positiveOrNull() = if (this > 0) this else null
|
||||
|
||||
/**
|
||||
* Aliases a check to ensure that the given number is non-zero.
|
||||
*
|
||||
* @return The same number if it's non-zero, null otherwise.
|
||||
*/
|
||||
fun Float.nonZeroOrNull() = if (this != 0f) this else null
|
||||
|
||||
/**
|
||||
* Aliases a check to ensure a given value is in a specified range.
|
||||
*
|
||||
* @param range The valid range of values for this number.
|
||||
* @return The same number if it is in the range, null otherwise.
|
||||
*/
|
||||
fun Int.inRangeOrNull(range: IntRange) = if (range.contains(this)) this else null
|
||||
|
||||
/**
|
||||
* Lazily set up a reflected field. Automatically handles visibility changes. Adapted from Material
|
||||
* Files: https://github.com/zhanghai/MaterialFiles
|
||||
|
@ -75,6 +50,7 @@ fun Int.inRangeOrNull(range: IntRange) = if (range.contains(this)) this else nul
|
|||
fun lazyReflectedField(clazz: KClass<*>, field: String) = lazy {
|
||||
clazz.java.getDeclaredField(field).also { it.isAccessible = true }
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily set up a reflected method. Automatically handles visibility changes. Adapted from Material
|
||||
* Files: https://github.com/zhanghai/MaterialFiles
|
||||
|
@ -87,64 +63,3 @@ fun lazyReflectedMethod(clazz: KClass<*>, method: String, vararg params: KClass<
|
|||
it.isAccessible = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a [String] to a [UUID].
|
||||
*
|
||||
* @return A [UUID] converted from the [String] value, or null if the value was not valid.
|
||||
* @see UUID.fromString
|
||||
*/
|
||||
fun String.toUuidOrNull(): UUID? =
|
||||
try {
|
||||
UUID.fromString(this)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
null
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a [MessageDigest] with a lowercase [String].
|
||||
*
|
||||
* @param string The [String] to hash. If null, it will not be hashed.
|
||||
*/
|
||||
fun MessageDigest.update(string: String?) {
|
||||
if (string != null) {
|
||||
update(string.lowercase().toByteArray())
|
||||
} else {
|
||||
update(0)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a [MessageDigest] with the string representation of a [Date].
|
||||
*
|
||||
* @param date The [Date] to hash. If null, nothing will be done.
|
||||
*/
|
||||
fun MessageDigest.update(date: Date?) {
|
||||
if (date != null) {
|
||||
update(date.toString().toByteArray())
|
||||
} else {
|
||||
update(0)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a [MessageDigest] with the lowercase versions of all of the input [String]s.
|
||||
*
|
||||
* @param strings The [String]s to hash. If a [String] is null, it will not be hashed.
|
||||
*/
|
||||
fun MessageDigest.update(strings: List<String?>) {
|
||||
strings.forEach(::update)
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a [MessageDigest] with the little-endian bytes of a [Int].
|
||||
*
|
||||
* @param n The [Int] to write. If null, nothing will be done.
|
||||
*/
|
||||
fun MessageDigest.update(n: Int?) {
|
||||
if (n != null) {
|
||||
update(byteArrayOf(n.toByte(), n.shr(8).toByte(), n.shr(16).toByte(), n.shr(24).toByte()))
|
||||
} else {
|
||||
update(0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,12 +30,12 @@ import android.view.View
|
|||
import android.widget.RemoteViews
|
||||
import org.oxycblt.auxio.BuildConfig
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.music.resolveNames
|
||||
import org.oxycblt.auxio.playback.service.PlaybackActions
|
||||
import org.oxycblt.auxio.playback.state.RepeatMode
|
||||
import org.oxycblt.auxio.ui.UISettings
|
||||
import org.oxycblt.auxio.ui.UISettingsImpl
|
||||
import org.oxycblt.auxio.util.newBroadcastPendingIntent
|
||||
import org.oxycblt.musikr.resolveNames
|
||||
import timber.log.Timber as L
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,20 +18,13 @@
|
|||
|
||||
package org.oxycblt.musikr
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Parcelable
|
||||
import androidx.room.TypeConverter
|
||||
import java.security.MessageDigest
|
||||
import java.util.UUID
|
||||
import kotlin.math.max
|
||||
import kotlinx.parcelize.IgnoredOnParcel
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.oxycblt.auxio.list.Item
|
||||
import org.oxycblt.auxio.music.MusicType
|
||||
import org.oxycblt.auxio.playback.replaygain.ReplayGainAdjustment
|
||||
import org.oxycblt.auxio.util.concatLocalized
|
||||
import org.oxycblt.auxio.util.toUuidOrNull
|
||||
import org.oxycblt.musikr.cover.Cover
|
||||
import org.oxycblt.musikr.fs.Format
|
||||
import org.oxycblt.musikr.fs.Path
|
||||
|
@ -39,6 +32,8 @@ import org.oxycblt.musikr.tag.Date
|
|||
import org.oxycblt.musikr.tag.Disc
|
||||
import org.oxycblt.musikr.tag.Name
|
||||
import org.oxycblt.musikr.tag.ReleaseType
|
||||
import org.oxycblt.musikr.tag.ReplayGainAdjustment
|
||||
import org.oxycblt.musikr.util.toUuidOrNull
|
||||
|
||||
/**
|
||||
* Abstract music data. This contains universal information about all concrete music
|
||||
|
@ -46,7 +41,7 @@ import org.oxycblt.musikr.tag.ReleaseType
|
|||
*
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*/
|
||||
sealed interface Music : Item {
|
||||
sealed interface Music {
|
||||
/**
|
||||
* A unique identifier for this music item.
|
||||
*
|
||||
|
@ -189,7 +184,7 @@ sealed interface Music : Item {
|
|||
* Creates a MusicBrainz-style [UID] with a [UUID] derived from the MusicBrainz ID
|
||||
* extracted from a file.
|
||||
*
|
||||
* @param item The analogous [MusicType] of the item that created this [UID].
|
||||
* @param item The [Item] that created this [UID].
|
||||
* @param mbid The analogous MusicBrainz ID for this item that was extracted from a
|
||||
* file.
|
||||
* @return A new MusicBrainz-style [UID].
|
||||
|
@ -372,32 +367,3 @@ interface Playlist : MusicParent {
|
|||
/** Useful information to quickly obtain a (single) cover for a Genre. */
|
||||
val cover: Cover
|
||||
}
|
||||
|
||||
/**
|
||||
* Run [Name.resolve] on each instance in the given list and concatenate them into a [String] in a
|
||||
* localized manner.
|
||||
*
|
||||
* @param context [Context] required
|
||||
* @return A concatenated string.
|
||||
*/
|
||||
fun <T : Music> List<T>.resolveNames(context: Context) =
|
||||
concatLocalized(context) { it.name.resolve(context) }
|
||||
|
||||
/**
|
||||
* Returns if [Music.name] matches for each item in a list. Useful for scenarios where the display
|
||||
* information of an item must be compared without a context.
|
||||
*
|
||||
* @param other The list of items to compare to.
|
||||
* @return True if they are the same (by [Music.name]), false otherwise.
|
||||
*/
|
||||
fun <T : Music> List<T>.areNamesTheSame(other: List<T>): Boolean {
|
||||
for (i in 0 until max(size, other.size)) {
|
||||
val a = getOrNull(i) ?: return false
|
||||
val b = other.getOrNull(i) ?: return false
|
||||
if (a.name != b.name) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.oxycblt.musikr.cover
|
||||
|
||||
import org.oxycblt.auxio.list.sort.Sort
|
||||
import org.oxycblt.musikr.Song
|
||||
|
||||
sealed interface Cover {
|
||||
|
@ -31,8 +30,6 @@ sealed interface Cover {
|
|||
}
|
||||
|
||||
companion object {
|
||||
private val FALLBACK_SORT = Sort(Sort.Mode.ByName, Sort.Direction.ASCENDING)
|
||||
|
||||
fun nil() = Multi(listOf())
|
||||
|
||||
fun single(key: String) = Single(key)
|
||||
|
@ -40,10 +37,11 @@ sealed interface Cover {
|
|||
fun multi(songs: Collection<Song>) = order(songs).run { Multi(this) }
|
||||
|
||||
private fun order(songs: Collection<Song>) =
|
||||
FALLBACK_SORT.songs(songs)
|
||||
songs
|
||||
.mapNotNull { it.cover }
|
||||
.groupBy { it.key }
|
||||
.entries
|
||||
.sortedByDescending { it.key }
|
||||
.sortedByDescending { it.value.size }
|
||||
.map { it.value.first() }
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
package org.oxycblt.musikr.fs
|
||||
|
||||
import android.webkit.MimeTypeMap
|
||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||
import org.oxycblt.musikr.util.unlikelyToBeNull
|
||||
|
||||
sealed interface Format {
|
||||
val mimeType: String
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
|
||||
package org.oxycblt.musikr.graph
|
||||
|
||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||
import org.oxycblt.musikr.Music
|
||||
import org.oxycblt.musikr.tag.interpret.PreAlbum
|
||||
import org.oxycblt.musikr.tag.interpret.PreArtist
|
||||
import org.oxycblt.musikr.tag.interpret.PreGenre
|
||||
import org.oxycblt.musikr.tag.interpret.PreSong
|
||||
import org.oxycblt.musikr.util.unlikelyToBeNull
|
||||
import timber.log.Timber as L
|
||||
|
||||
data class MusicGraph(
|
||||
|
|
|
@ -21,11 +21,11 @@ package org.oxycblt.musikr.metadata
|
|||
import android.content.Context
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||
import org.oxycblt.ktaglib.FileRef
|
||||
import org.oxycblt.ktaglib.KTagLib
|
||||
import org.oxycblt.ktaglib.Metadata
|
||||
import org.oxycblt.musikr.fs.query.DeviceFile
|
||||
import org.oxycblt.musikr.util.unlikelyToBeNull
|
||||
|
||||
interface MetadataExtractor {
|
||||
suspend fun extract(file: DeviceFile): Metadata?
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.oxycblt.musikr.model
|
||||
|
||||
import org.oxycblt.auxio.util.update
|
||||
import org.oxycblt.musikr.Album
|
||||
import org.oxycblt.musikr.Artist
|
||||
import org.oxycblt.musikr.Music
|
||||
|
@ -26,6 +25,7 @@ import org.oxycblt.musikr.Song
|
|||
import org.oxycblt.musikr.cover.Cover
|
||||
import org.oxycblt.musikr.tag.Date
|
||||
import org.oxycblt.musikr.tag.interpret.PreAlbum
|
||||
import org.oxycblt.musikr.util.update
|
||||
|
||||
interface AlbumCore {
|
||||
val preAlbum: PreAlbum
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.oxycblt.musikr.model
|
||||
|
||||
import org.oxycblt.auxio.util.update
|
||||
import org.oxycblt.musikr.Album
|
||||
import org.oxycblt.musikr.Artist
|
||||
import org.oxycblt.musikr.Genre
|
||||
|
@ -26,6 +25,7 @@ import org.oxycblt.musikr.Music
|
|||
import org.oxycblt.musikr.Song
|
||||
import org.oxycblt.musikr.cover.Cover
|
||||
import org.oxycblt.musikr.tag.interpret.PreArtist
|
||||
import org.oxycblt.musikr.util.update
|
||||
|
||||
interface ArtistCore {
|
||||
val preArtist: PreArtist
|
||||
|
|
|
@ -18,13 +18,13 @@
|
|||
|
||||
package org.oxycblt.musikr.model
|
||||
|
||||
import org.oxycblt.auxio.util.update
|
||||
import org.oxycblt.musikr.Artist
|
||||
import org.oxycblt.musikr.Genre
|
||||
import org.oxycblt.musikr.Music
|
||||
import org.oxycblt.musikr.Song
|
||||
import org.oxycblt.musikr.cover.Cover
|
||||
import org.oxycblt.musikr.tag.interpret.PreGenre
|
||||
import org.oxycblt.musikr.util.update
|
||||
|
||||
interface GenreCore {
|
||||
val preGenre: PreGenre
|
||||
|
|
|
@ -25,7 +25,7 @@ import java.io.BufferedWriter
|
|||
import java.io.InputStream
|
||||
import java.io.InputStreamReader
|
||||
import java.io.OutputStream
|
||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||
import org.oxycblt.auxio.music.resolveNames
|
||||
import org.oxycblt.musikr.Playlist
|
||||
import org.oxycblt.musikr.fs.Components
|
||||
import org.oxycblt.musikr.fs.Path
|
||||
|
@ -34,8 +34,8 @@ import org.oxycblt.musikr.fs.path.VolumeManager
|
|||
import org.oxycblt.musikr.playlist.ExportConfig
|
||||
import org.oxycblt.musikr.playlist.ImportedPlaylist
|
||||
import org.oxycblt.musikr.playlist.PossiblePaths
|
||||
import org.oxycblt.musikr.resolveNames
|
||||
import org.oxycblt.musikr.tag.util.correctWhitespace
|
||||
import org.oxycblt.musikr.util.unlikelyToBeNull
|
||||
import timber.log.Timber as L
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,8 +23,8 @@ import java.text.ParseException
|
|||
import java.text.SimpleDateFormat
|
||||
import kotlin.math.max
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.util.inRangeOrNull
|
||||
import org.oxycblt.auxio.util.positiveOrNull
|
||||
import org.oxycblt.musikr.util.inRangeOrNull
|
||||
import org.oxycblt.musikr.util.positiveOrNull
|
||||
import timber.log.Timber as L
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,7 +20,6 @@ package org.oxycblt.musikr.tag
|
|||
|
||||
import android.content.Context
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.list.Item
|
||||
|
||||
/**
|
||||
* A disc identifier for a song.
|
||||
|
@ -28,7 +27,7 @@ import org.oxycblt.auxio.list.Item
|
|||
* @param number The disc number.
|
||||
* @param name The name of the disc group, if any. Null if not present.
|
||||
*/
|
||||
class Disc(val number: Int, val name: String?) : Item, Comparable<Disc> {
|
||||
class Disc(val number: Int, val name: String?) : Comparable<Disc> {
|
||||
// We don't want to group discs by differing subtitles, so only compare by the number
|
||||
override fun equals(other: Any?) = other is Disc && number == other.number
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Auxio Project
|
||||
* ReplayGainAdjustment.kt is part of Auxio.
|
||||
*
|
||||
* 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.musikr.tag
|
||||
|
||||
/**
|
||||
* Represents a ReplayGain adjustment to apply during song playback.
|
||||
*
|
||||
* @param track The track-specific adjustment that should be applied. Null if not available.
|
||||
* @param album A more general album-specific adjustment that should be applied. Null if not
|
||||
* available.
|
||||
*/
|
||||
data class ReplayGainAdjustment(val track: Float?, val album: Float?)
|
|
@ -20,8 +20,6 @@ package org.oxycblt.musikr.tag.interpret
|
|||
|
||||
import android.net.Uri
|
||||
import java.util.UUID
|
||||
import org.oxycblt.auxio.playback.replaygain.ReplayGainAdjustment
|
||||
import org.oxycblt.auxio.util.update
|
||||
import org.oxycblt.musikr.Music
|
||||
import org.oxycblt.musikr.cover.Cover
|
||||
import org.oxycblt.musikr.fs.Format
|
||||
|
@ -31,6 +29,8 @@ import org.oxycblt.musikr.tag.Date
|
|||
import org.oxycblt.musikr.tag.Disc
|
||||
import org.oxycblt.musikr.tag.Name
|
||||
import org.oxycblt.musikr.tag.ReleaseType
|
||||
import org.oxycblt.musikr.tag.ReplayGainAdjustment
|
||||
import org.oxycblt.musikr.util.update
|
||||
|
||||
data class PreSong(
|
||||
val musicBrainzId: UUID?,
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
package org.oxycblt.musikr.tag.interpret
|
||||
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.playback.replaygain.ReplayGainAdjustment
|
||||
import org.oxycblt.auxio.util.toUuidOrNull
|
||||
import org.oxycblt.musikr.Interpretation
|
||||
import org.oxycblt.musikr.fs.Format
|
||||
import org.oxycblt.musikr.fs.query.DeviceFile
|
||||
|
@ -28,8 +26,10 @@ import org.oxycblt.musikr.pipeline.RawSong
|
|||
import org.oxycblt.musikr.tag.Disc
|
||||
import org.oxycblt.musikr.tag.Name
|
||||
import org.oxycblt.musikr.tag.ReleaseType
|
||||
import org.oxycblt.musikr.tag.ReplayGainAdjustment
|
||||
import org.oxycblt.musikr.tag.parse.ParsedTags
|
||||
import org.oxycblt.musikr.tag.util.parseId3GenreNames
|
||||
import org.oxycblt.musikr.util.toUuidOrNull
|
||||
|
||||
interface TagInterpreter {
|
||||
fun interpret(song: RawSong, interpretation: Interpretation): PreSong
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
package org.oxycblt.musikr.tag.parse
|
||||
|
||||
import androidx.core.text.isDigitsOnly
|
||||
import org.oxycblt.auxio.util.nonZeroOrNull
|
||||
import org.oxycblt.ktaglib.Metadata
|
||||
import org.oxycblt.musikr.tag.Date
|
||||
import org.oxycblt.musikr.tag.util.parseId3v2PositionField
|
||||
import org.oxycblt.musikr.tag.util.parseXiphPositionField
|
||||
import org.oxycblt.musikr.util.nonZeroOrNull
|
||||
|
||||
// Song
|
||||
fun Metadata.musicBrainzId() =
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
package org.oxycblt.musikr.tag.util
|
||||
|
||||
import org.oxycblt.auxio.util.positiveOrNull
|
||||
import org.oxycblt.musikr.util.positiveOrNull
|
||||
|
||||
/**
|
||||
* Parse an ID3v2-style position + total [String] field. These fields consist of a number and an
|
||||
|
|
133
app/src/main/java/org/oxycblt/musikr/util/LangUtil.kt
Normal file
133
app/src/main/java/org/oxycblt/musikr/util/LangUtil.kt
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Auxio Project
|
||||
* LangUtil.kt is part of Auxio.
|
||||
*
|
||||
* 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.musikr.util
|
||||
|
||||
import java.security.MessageDigest
|
||||
import java.util.UUID
|
||||
import org.oxycblt.auxio.BuildConfig
|
||||
import org.oxycblt.musikr.tag.Date
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Sanitizes a value that is unlikely to be null. On debug builds, this aliases to [requireNotNull],
|
||||
* otherwise, it aliases to the unchecked dereference operator (!!). This can be used as a minor
|
||||
* optimization in certain cases.
|
||||
*/
|
||||
fun <T> unlikelyToBeNull(value: T?) =
|
||||
if (BuildConfig.DEBUG) {
|
||||
requireNotNull(value)
|
||||
} else {
|
||||
value!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Aliases a check to ensure that the given number is non-zero.
|
||||
*
|
||||
* @return The given number if it's non-zero, null otherwise.
|
||||
*/
|
||||
fun Int.positiveOrNull() = if (this > 0) this else null
|
||||
|
||||
/**
|
||||
* Aliases a check to ensure that the given number is non-zero.
|
||||
*
|
||||
* @return The same number if it's non-zero, null otherwise.
|
||||
*/
|
||||
fun Float.nonZeroOrNull() = if (this != 0f) this else null
|
||||
|
||||
/**
|
||||
* Aliases a check to ensure a given value is in a specified range.
|
||||
*
|
||||
* @param range The valid range of values for this number.
|
||||
* @return The same number if it is in the range, null otherwise.
|
||||
*/
|
||||
fun Int.inRangeOrNull(range: IntRange) = if (range.contains(this)) this else null
|
||||
|
||||
/**
|
||||
* Convert a [String] to a [UUID].
|
||||
*
|
||||
* @return A [UUID] converted from the [String] value, or null if the value was not valid.
|
||||
* @see UUID.fromString
|
||||
*/
|
||||
fun String.toUuidOrNull(): UUID? =
|
||||
try {
|
||||
UUID.fromString(this)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
null
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a [MessageDigest] with a lowercase [String].
|
||||
*
|
||||
* @param string The [String] to hash. If null, it will not be hashed.
|
||||
*/
|
||||
fun MessageDigest.update(string: String?) {
|
||||
if (string != null) {
|
||||
update(string.lowercase().toByteArray())
|
||||
} else {
|
||||
update(0)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a [MessageDigest] with the string representation of a [Date].
|
||||
*
|
||||
* @param date The [Date] to hash. If null, nothing will be done.
|
||||
*/
|
||||
fun MessageDigest.update(date: Date?) {
|
||||
if (date != null) {
|
||||
update(date.toString().toByteArray())
|
||||
} else {
|
||||
update(0)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a [MessageDigest] with the lowercase versions of all of the input [String]s.
|
||||
*
|
||||
* @param strings The [String]s to hash. If a [String] is null, it will not be hashed.
|
||||
*/
|
||||
fun MessageDigest.update(strings: List<String?>) {
|
||||
strings.forEach(::update)
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a [MessageDigest] with the little-endian bytes of a [Int].
|
||||
*
|
||||
* @param n The [Int] to write. If null, nothing will be done.
|
||||
*/
|
||||
fun MessageDigest.update(n: Int?) {
|
||||
if (n != null) {
|
||||
update(byteArrayOf(n.toByte(), n.shr(8).toByte(), n.shr(16).toByte(), n.shr(24).toByte()))
|
||||
} else {
|
||||
update(0)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily set up a reflected method. Automatically handles visibility changes. Adapted from Material
|
||||
* Files: https://github.com/zhanghai/MaterialFiles
|
||||
*
|
||||
* @param clazz The [KClass] to reflect into.
|
||||
* @param method The name of the method to obtain.
|
||||
*/
|
||||
fun lazyReflectedMethod(clazz: KClass<*>, method: String, vararg params: KClass<*>) = lazy {
|
||||
clazz.java.getDeclaredMethod(method, *params.map { it.java }.toTypedArray()).also {
|
||||
it.isAccessible = true
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue