all: cleanup code
Upgrade dependencies, fix deprecation issues, and just clean up code in general.
This commit is contained in:
parent
8f61d8479a
commit
67797d957e
35 changed files with 54 additions and 107 deletions
|
@ -94,7 +94,7 @@ dependencies {
|
|||
// --- THIRD PARTY ---
|
||||
|
||||
// ExoPlayer
|
||||
implementation "com.google.android.exoplayer:exoplayer-core:2.15.1"
|
||||
implementation "com.google.android.exoplayer:exoplayer-core:2.16.0"
|
||||
|
||||
// Image loading
|
||||
implementation 'io.coil-kt:coil:1.4.0'
|
||||
|
@ -105,7 +105,7 @@ dependencies {
|
|||
// --- DEBUG ---
|
||||
|
||||
// Lint
|
||||
ktlint 'com.pinterest:ktlint:0.42.1'
|
||||
ktlint 'com.pinterest:ktlint:0.43.0'
|
||||
}
|
||||
|
||||
task ktlint(type: JavaExec, group: "verification") {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
android:fullBackupContent="@xml/backup_descriptor"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/info_app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:roundIcon="@mipmap/ic_launcher"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Auxio.App">
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
|||
android:exported="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:launchMode="singleTask"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:roundIcon="@mipmap/ic_launcher"
|
||||
android:windowSoftInputMode="adjustPan">
|
||||
|
||||
<intent-filter>
|
||||
|
@ -54,7 +54,7 @@
|
|||
android:name=".playback.system.PlaybackService"
|
||||
android:foregroundServiceType="mediaPlayback"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round" />
|
||||
android:roundIcon="@mipmap/ic_launcher" />
|
||||
|
||||
<receiver
|
||||
android:name=".widgets.WidgetProvider"
|
||||
|
|
|
@ -170,7 +170,7 @@ class AlbumArtFetcher(private val context: Context) : Fetcher<Album> {
|
|||
|
||||
if (tracks == null || tracks.isEmpty) {
|
||||
// Unrecognized format. This is expected, as ExoPlayer only supports a
|
||||
// subset of formats.
|
||||
// subset of formats.
|
||||
return null
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ import org.oxycblt.auxio.music.Album
|
|||
import org.oxycblt.auxio.music.Artist
|
||||
import org.oxycblt.auxio.music.Genre
|
||||
import org.oxycblt.auxio.music.MusicParent
|
||||
import java.io.Closeable
|
||||
import java.lang.Exception
|
||||
|
||||
/**
|
||||
|
@ -139,13 +138,6 @@ class MosaicFetcher(private val context: Context) : Fetcher<MusicParent> {
|
|||
return mosaicBitmap
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate through a list of [Closeable]s, running [block] on each and closing it when done.
|
||||
*/
|
||||
private fun <T : Closeable> List<T>.useForEach(block: (T) -> Unit) {
|
||||
forEach { it.use(block) }
|
||||
}
|
||||
|
||||
override fun key(data: MusicParent): String = data.hashCode().toString()
|
||||
override fun handles(data: MusicParent) = data !is Album // Albums are not used here
|
||||
|
||||
|
|
|
@ -76,12 +76,12 @@ abstract class DetailFragment : Fragment() {
|
|||
* @param onMenuClick (Optional) a click listener for that menu
|
||||
*/
|
||||
protected fun setupToolbar(
|
||||
data: Music,
|
||||
music: Music,
|
||||
@MenuRes menu: Int = -1,
|
||||
onMenuClick: ((itemId: Int) -> Boolean)? = null
|
||||
) {
|
||||
binding.detailToolbar.apply {
|
||||
title = data.name
|
||||
title = music.name
|
||||
|
||||
if (menu != -1) {
|
||||
inflateMenu(menu)
|
||||
|
|
|
@ -47,7 +47,7 @@ import kotlin.math.abs
|
|||
|
||||
/**
|
||||
* A [RecyclerView] that enables better fast-scrolling. This is fundamentally a implementation of
|
||||
* Zhanghi's AndroidFastScroll but slimmed down for Auxio and with a couple of enhancements.
|
||||
* Hai Zhang's AndroidFastScroll but slimmed down for Auxio and with a couple of enhancements.
|
||||
*
|
||||
* Attributions as per the Apache 2.0 license:
|
||||
* ORIGINAL AUTHOR: Hai Zhang [https://github.com/zhanghai]
|
||||
|
|
|
@ -33,7 +33,9 @@ import org.oxycblt.auxio.util.logE
|
|||
import java.lang.Exception
|
||||
|
||||
/**
|
||||
* The main storage for music items. Use [MusicStore.getInstance] to get the single instance of it.
|
||||
* The main storage for music items.
|
||||
* Getting an instance of this object is more complicated as it loads asynchronously.
|
||||
* See the companion object for more.
|
||||
* @author OxygenCobalt
|
||||
*/
|
||||
class MusicStore private constructor() {
|
||||
|
@ -194,7 +196,8 @@ class MusicStore private constructor() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Maybe get a MusicStore instance.
|
||||
* Maybe get a MusicStore instance. This is useful if you are running code while the
|
||||
* loading process may still be going on.
|
||||
*
|
||||
* @return null if the music store instance is still loading or if the loading process has
|
||||
* encountered an error. An instance is returned otherwise.
|
||||
|
|
|
@ -246,7 +246,7 @@ class PlaybackBarLayout @JvmOverloads constructor(
|
|||
}
|
||||
|
||||
/**
|
||||
* Update the playback positon on this layout. This will be reflected in the compact view
|
||||
* Update the playback position on this layout. This will be reflected in the compact view
|
||||
* at the bottom of the screen.
|
||||
*/
|
||||
fun setPosition(position: Long) {
|
||||
|
|
|
@ -60,7 +60,7 @@ class PlaybackFragment : Fragment() {
|
|||
binding.playbackModel = playbackModel
|
||||
binding.detailModel = detailModel
|
||||
|
||||
binding.root.setOnApplyWindowInsetsListener { v, insets ->
|
||||
binding.root.setOnApplyWindowInsetsListener { _, insets ->
|
||||
val bars = insets.systemBarsCompat
|
||||
|
||||
binding.root.updatePadding(
|
||||
|
|
|
@ -22,7 +22,7 @@ import android.content.Context
|
|||
import android.media.AudioManager
|
||||
import androidx.media.AudioFocusRequestCompat
|
||||
import androidx.media.AudioManagerCompat
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer
|
||||
import com.google.android.exoplayer2.ExoPlayer
|
||||
import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
||||
import org.oxycblt.auxio.settings.SettingsManager
|
||||
import org.oxycblt.auxio.util.getSystemServiceSafe
|
||||
|
@ -35,7 +35,7 @@ import org.oxycblt.auxio.util.logD
|
|||
*/
|
||||
class AudioReactor(
|
||||
context: Context,
|
||||
private val player: SimpleExoPlayer
|
||||
private val player: ExoPlayer
|
||||
) : AudioManager.OnAudioFocusChangeListener {
|
||||
private val playbackManager = PlaybackStateManager.maybeGetInstance()
|
||||
private val settingsManager = SettingsManager.getInstance()
|
||||
|
|
|
@ -32,11 +32,11 @@ import android.os.IBinder
|
|||
import android.os.PowerManager
|
||||
import android.support.v4.media.session.MediaSessionCompat
|
||||
import com.google.android.exoplayer2.C
|
||||
import com.google.android.exoplayer2.ExoPlayer
|
||||
import com.google.android.exoplayer2.MediaItem
|
||||
import com.google.android.exoplayer2.PlaybackException
|
||||
import com.google.android.exoplayer2.Player
|
||||
import com.google.android.exoplayer2.RenderersFactory
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer
|
||||
import com.google.android.exoplayer2.audio.AudioAttributes
|
||||
import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer
|
||||
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
|
||||
|
@ -65,7 +65,7 @@ import org.oxycblt.auxio.widgets.WidgetProvider
|
|||
|
||||
/**
|
||||
* A service that manages the system-side aspects of playback, such as:
|
||||
* - The single [SimpleExoPlayer] instance.
|
||||
* - The single [ExoPlayer] instance.
|
||||
* - The Media Notification
|
||||
* - Headset management
|
||||
* - Widgets
|
||||
|
@ -77,7 +77,7 @@ import org.oxycblt.auxio.widgets.WidgetProvider
|
|||
class PlaybackService : Service(), Player.Listener, PlaybackStateManager.Callback, SettingsManager.Callback {
|
||||
|
||||
// Player components
|
||||
private lateinit var player: SimpleExoPlayer
|
||||
private lateinit var player: ExoPlayer
|
||||
private lateinit var mediaSession: MediaSessionCompat
|
||||
private lateinit var connector: PlaybackSessionConnector
|
||||
|
||||
|
@ -341,9 +341,9 @@ class PlaybackService : Service(), Player.Listener, PlaybackStateManager.Callbac
|
|||
// --- OTHER FUNCTIONS ---
|
||||
|
||||
/**
|
||||
* Create the [SimpleExoPlayer] instance.
|
||||
* Create the [ExoPlayer] instance.
|
||||
*/
|
||||
private fun newPlayer(): SimpleExoPlayer {
|
||||
private fun newPlayer(): ExoPlayer {
|
||||
// Since Auxio is a music player, only specify an audio renderer to save
|
||||
// battery/apk size/cache size
|
||||
val audioRenderer = RenderersFactory { handler, _, audioListener, _, _ ->
|
||||
|
@ -355,7 +355,7 @@ class PlaybackService : Service(), Player.Listener, PlaybackStateManager.Callbac
|
|||
// Enable constant bitrate seeking so that certain MP3s/AACs are seekable
|
||||
val extractorsFactory = DefaultExtractorsFactory().setConstantBitrateSeekingEnabled(true)
|
||||
|
||||
return SimpleExoPlayer.Builder(this, audioRenderer)
|
||||
return ExoPlayer.Builder(this, audioRenderer)
|
||||
.setMediaSourceFactory(DefaultMediaSourceFactory(this, extractorsFactory))
|
||||
.build()
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ class AboutFragment : Fragment() {
|
|||
): View {
|
||||
val binding = FragmentAboutBinding.inflate(layoutInflater)
|
||||
|
||||
binding.aboutContents.setOnApplyWindowInsetsListener { v, insets ->
|
||||
binding.aboutContents.setOnApplyWindowInsetsListener { _, insets ->
|
||||
binding.aboutContents.updatePadding(bottom = insets.systemBarsCompat.bottom)
|
||||
insets
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ class SettingsListFragment : PreferenceFragmentCompat() {
|
|||
view.findViewById<RecyclerView>(androidx.preference.R.id.recycler_view).apply {
|
||||
clipToPadding = false
|
||||
|
||||
setOnApplyWindowInsetsListener { v, insets ->
|
||||
setOnApplyWindowInsetsListener { _, insets ->
|
||||
updatePadding(bottom = insets.systemBarsCompat.bottom)
|
||||
|
||||
insets
|
||||
|
|
|
@ -65,11 +65,11 @@ class ActionMenu(
|
|||
|
||||
// Get viewmodels using the activity as the store owner
|
||||
private val detailModel: DetailViewModel by lazy {
|
||||
ViewModelProvider(activity).get(DetailViewModel::class.java)
|
||||
ViewModelProvider(activity)[DetailViewModel::class.java]
|
||||
}
|
||||
|
||||
private val playbackModel: PlaybackViewModel by lazy {
|
||||
ViewModelProvider(activity).get(PlaybackViewModel::class.java)
|
||||
ViewModelProvider(activity)[PlaybackViewModel::class.java]
|
||||
}
|
||||
|
||||
init {
|
||||
|
|
|
@ -23,9 +23,9 @@ import androidx.databinding.ViewDataBinding
|
|||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.LifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.OnLifecycleEvent
|
||||
import org.oxycblt.auxio.util.assertMainThread
|
||||
import org.oxycblt.auxio.util.inflater
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
|
@ -51,7 +51,7 @@ class MemberBinder<T : ViewDataBinding>(
|
|||
private val fragment: Fragment,
|
||||
private val inflate: (LayoutInflater) -> T,
|
||||
private val onDestroy: T.() -> Unit
|
||||
) : ReadOnlyProperty<Fragment, T>, LifecycleObserver {
|
||||
) : ReadOnlyProperty<Fragment, T>, LifecycleObserver, LifecycleEventObserver {
|
||||
private var fragmentBinding: T? = null
|
||||
|
||||
init {
|
||||
|
@ -82,6 +82,13 @@ class MemberBinder<T : ViewDataBinding>(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
|
||||
if (event == Lifecycle.Event.ON_DESTROY) {
|
||||
fragmentBinding?.onDestroy()
|
||||
fragmentBinding = null
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun Fragment.observeOwnerThroughCreation(
|
||||
crossinline viewOwner: LifecycleOwner.() -> Unit
|
||||
) {
|
||||
|
@ -95,11 +102,4 @@ class MemberBinder<T : ViewDataBinding>(
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Suppress("UNUSED")
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
|
||||
fun destroy() {
|
||||
fragmentBinding?.onDestroy()
|
||||
fragmentBinding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ import androidx.core.content.ContextCompat
|
|||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.shape.MaterialShapeDrawable
|
||||
import org.oxycblt.auxio.R
|
||||
|
||||
/**
|
||||
* Apply a [MaterialShapeDrawable] to this view, automatically initializing the elevation overlay
|
||||
|
|
|
@ -152,8 +152,6 @@ class WidgetProvider : AppWidgetProvider() {
|
|||
// We can't resize the widget until we can generate the views, so request an update
|
||||
// from PlaybackService.
|
||||
requestUpdate(context)
|
||||
} else {
|
||||
logD(newOptions?.getParcelableArrayList<SizeF>(AppWidgetManager.OPTION_APPWIDGET_SIZES) ?: "nothing")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/mtrl_btn_ripple_color">
|
||||
android:color="?attr/colorSurface">
|
||||
<item android:id="@android:id/background">
|
||||
<shape
|
||||
android:shape="rectangle"
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<ripple android:color="?attr/colorControlHighlight">
|
||||
<item android:id="@android:id/mask">
|
||||
<shape android:shape="rectangle"
|
||||
android:tint="?attr/colorSurface">
|
||||
<solid android:color="@android:color/white" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
</item>
|
||||
</layer-list>
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--Divider used by recyclerview header items https://stackoverflow.com/a/61157571/14143986-->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:left="-2dp"
|
||||
android:right="-2dp"
|
||||
android:top="-2dp">
|
||||
<shape android:shape="rectangle">
|
||||
<stroke
|
||||
android:width="@dimen/size_stroke_small"
|
||||
android:color="?attr/colorOutline" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
12
app/src/main/res/drawable/ui_play_pause_circle.xml
Normal file
12
app/src/main/res/drawable/ui_play_pause_circle.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/m3_button_ripple_color_selector">
|
||||
<item android:id="@android:id/background">
|
||||
<shape
|
||||
android:shape="rectangle"
|
||||
android:tint="@color/sel_accented">
|
||||
<corners android:radius="@dimen/spacing_large" />
|
||||
<solid android:color="@android:color/white" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid
|
||||
android:color="@android:color/transparent" />
|
||||
|
||||
<size android:width="@dimen/spacing_small" />
|
||||
</shape>
|
|
@ -15,7 +15,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="@drawable/ui_circle_ripple"
|
||||
android:background="@drawable/ui_accent_circle"
|
||||
android:padding="@dimen/spacing_medium"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_check"
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
Before Width: | Height: | Size: 6.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 9.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Info namespace | App labels -->
|
||||
<string name="info_channel_name">Musikwiedergabe</string>
|
||||
|
||||
|
@ -79,7 +79,7 @@
|
|||
<string name="set_song_mode">Wenn ein Lied ausgewählt wird</string>
|
||||
<string name="set_keep_shuffle">Zufällig-Einstellung merken</string>
|
||||
<string name="set_keep_shuffle_desc">Zufällig anlassen, wenn ein neues Lied abgespielt wird</string>
|
||||
<string name="set_rewind_prev">Zurückspulen bevor zurück gegangen wird</string>
|
||||
<string name="set_rewind_prev" tools:ignore="Typos">Zurückspulen bevor zurück gegangen wird</string>
|
||||
<string name="set_rewind_prev_desc">Zurückspulen bevor zum vorheriger Lied gegangen wird</string>
|
||||
|
||||
<string name="set_content">Inhalt</string>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
<resources>
|
||||
<color name="surface">@color/surface_night</color>
|
||||
<color name="surface_variant">@color/surface_day</color>
|
||||
<color name="control">#ffffff</color>
|
||||
<color name="nav_bar">#01151515</color>
|
||||
|
||||
<!--
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
<!-- Base app colors -->
|
||||
<color name="surface">#fafafa</color>
|
||||
<color name="surface_variant">@color/surface_night</color>
|
||||
<color name="control">#202020</color>
|
||||
<color name="nav_bar">#01fafafa</color>
|
||||
|
||||
<color name="surface_day">#fafafa</color>
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
<!-- Size Namespace | Width & Heights for UI elements -->
|
||||
<dimen name="size_btn_small">48dp</dimen>
|
||||
<dimen name="size_btn_medium">56dp</dimen>
|
||||
<dimen name="size_btn_large">64dp</dimen>
|
||||
|
||||
<dimen name="size_cover_compact">48dp</dimen>
|
||||
|
@ -18,7 +17,6 @@
|
|||
<dimen name="size_cover_huge_land">128dp</dimen>
|
||||
<dimen name="size_cover_huge">256dp</dimen>
|
||||
|
||||
<dimen name="size_stroke_small">1dp</dimen>
|
||||
<dimen name="size_stroke_large">2dp</dimen>
|
||||
|
||||
<dimen name="size_small_unb_ripple">20dp</dimen>
|
||||
|
|
|
@ -165,7 +165,7 @@
|
|||
<style name="Widget.Auxio.Button.Circular" parent="">
|
||||
<item name="android:minHeight">@dimen/size_btn_large</item>
|
||||
<item name="android:minWidth">@dimen/size_btn_large</item>
|
||||
<item name="android:background">@drawable/ui_circle_ripple</item>
|
||||
<item name="android:background">@drawable/ui_play_pause_circle</item>
|
||||
<item name="android:contentDescription">@string/desc_play_pause</item>
|
||||
<item name="android:tint">?attr/colorSurface</item>
|
||||
<item name="android:scaleType">fitCenter</item>
|
||||
|
|
|
@ -8,21 +8,6 @@
|
|||
the value will be overridden if you look at the wrong way.
|
||||
-->
|
||||
|
||||
<style name="TextAppearance.Auxio.DisplayLarge" parent="TextAppearance.Material3.DisplayLarge">
|
||||
<item name="fontFamily">@font/inter_semibold</item>
|
||||
<item name="android:fontFamily">@font/inter_semibold</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Auxio.DisplayMedium" parent="TextAppearance.Material3.DisplayMedium">
|
||||
<item name="fontFamily">@font/inter_semibold</item>
|
||||
<item name="android:fontFamily">@font/inter_semibold</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Auxio.DisplaySmall" parent="TextAppearance.Material3.DisplaySmall">
|
||||
<item name="fontFamily">@font/inter_semibold</item>
|
||||
<item name="android:fontFamily">@font/inter_semibold</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Auxio.HeadlineLarge" parent="TextAppearance.Material3.HeadlineLarge">
|
||||
<item name="fontFamily">@font/inter_semibold</item>
|
||||
<item name="android:fontFamily">@font/inter_semibold</item>
|
||||
|
|
Loading…
Reference in a new issue