25 Commits

Author SHA1 Message Date
bfa3231823 Добавлен выбор источника Обзора
Some checks failed
CI / build (push) Has been cancelled
2024-02-24 01:02:27 +03:00
abe5d0b378 Исправлена работа лайков и ссылок на профиль исполнителя. 2024-02-24 00:07:30 +03:00
7b1138c428 Исправлена работа лайков и ссылок на профиль исполнителя. 2024-02-24 00:07:15 +03:00
Hamy
b2b12c473c Merge pull request #1 from hammsterr/feature-yandex-ads
Подключение РСЯ
2024-02-12 01:00:19 +03:00
Dmitriy Chugunov
20cdcddd36 add yandex ads banner 2024-02-11 23:37:22 +03:00
c79fa89c1d Обновление
0.5.4.2
2024-01-30 15:14:45 +05:00
Hamy
2a995364a2 Update README.md 2023-09-20 15:27:25 +05:00
Hamy
0f017a781f Update README.md 2023-09-20 15:26:43 +05:00
Hamy
3e251a9b7a Update README.md 2023-09-20 15:26:22 +05:00
Hamy
5c7257de3f Update README.md 2023-09-20 15:25:54 +05:00
Hamy
873505776b Update README.md 2023-09-20 15:20:21 +05:00
6dc89ff95e Обновление 0.5.4.1
Добавлен прокси,
Перевод оставшихся слов и исправление орфографических ошибок.
Удаление трека из очереди свайпом
2023-08-25 21:50:48 +05:00
Hamy
013a7127e7 Update README.md 2023-08-10 17:08:42 +05:00
Hamy
ed050ec2f7 Update README.md 2023-08-10 17:05:57 +05:00
Hamy
e37cfc391f Добавил ссылочку в РуСтор 2023-08-10 17:03:49 +05:00
Hamy
777fbcdf4d Добавил описание 2023-08-10 17:01:31 +05:00
749d6dfb3f Merge branch 'master' of https://github.com/hammsterr/muza 2023-06-24 02:15:29 +05:00
45f972c0b4 Update build.gradle.kts 2023-06-24 02:15:02 +05:00
Hamy
a344495893 чутка подправил 2023-06-24 02:06:05 +05:00
Hamy
c654b89cc0 Мелкие правки 2023-06-24 02:03:13 +05:00
Hamy
b897faf071 Мелкие правки 2023-06-24 02:02:22 +05:00
Hamy
7843db0c9c Подровнял лого 2023-06-24 01:59:17 +05:00
Hamy
395a829621 Загрузил скриншоты 2023-06-24 01:56:23 +05:00
9b0bef4f0d Свежие скриншоты 2023-06-24 01:53:25 +05:00
0e0cd3ea07 Перевод
Мелкие шайтанские фокусы
2023-06-24 01:49:30 +05:00
287 changed files with 2392 additions and 1754 deletions

View File

@@ -59,7 +59,7 @@ body:
If your bug includes a crash, please use `adb logcat` or other ways to provide logs.
- type: input
id: vimusic-version
id: muza-version
attributes:
label: ViMusic version
placeholder: |

View File

@@ -1,21 +1,37 @@
<div align="center">
<img src="./app/src/main/ic_launcher-playstore.png" width="128" height="128" style="display: block; margin: 0 auto"/>
<img src="./app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp" width="128" height="128" style="display: block; margin: 0 auto"/>
<h1>Muza</h1>
<p>Стриминговый музыкальный плеер на Android</p>
<img alt="GitHub all releases" src="https://img.shields.io/github/downloads/hammsterr/muza/total?style=plastic&logo=github&logoColor=rgb&label=%D0%97%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BE%D0%BA&labelColor=rgb&color=rgb">
</div>
---
<p align="center">
<img src="./fastlane/metadata/android/en-US/images/phoneScreenshots/1.jpg" width="30%" />
<img src="./fastlane/metadata/android/en-US/images/phoneScreenshots/2.jpg" width="30%" />
<img src="./fastlane/metadata/android/en-US/images/phoneScreenshots/3.jpg" width="30%" />
<img src="./fastlane/metadata/android/en-US/images/phoneScreenshots/4.jpg" width="30%" />
<img src="./fastlane/metadata/android/en-US/images/phoneScreenshots/5.jpg" width="30%" />
<img src="./fastlane/metadata/android/en-US/images/phoneScreenshots/6.jpg" width="30%" />
<img src="./ScreenShots/01.jpg" width="30%" />
<img src="./ScreenShots/1.jpg" width="30%" />
<img src="./ScreenShots/2.jpg" width="30%" />
<img src="./ScreenShots/3.jpg" width="30%" />
<img src="./ScreenShots/4.jpg" width="30%" />
<img src="./ScreenShots/5.jpg" width="30%" />
</p>
## Описание
Muza - это удобное и простое в использовании музыкальное приложение, которое позволяет слушать любимую музыку бесплатно и без каких-либо ограничений.
С помощью Muza вы можете создавать плейлисты, составлять музыкальные коллекции и наслаждаться звучанием того, что действительно нравится.
Мы предоставляем доступ к миллионам треков разных жанров и стилей, чтобы каждый пользователь мог найти здесь что-то для себя.
Кроме того, в приложении доступна функция чтения текстов песен, которая поможет подпевать и понимать глубинный смысл написанных слов.
С Muza с каждым днем вы будете открывать для себя что-то новое и интересное и делиться своими впечатлениями с друзьями.
Будьте на связи с любимой музыкой везде и всегда с Muza!
## Функции
- Воспроизведение (почти) любой песни или видео с YouTube Music
- Фоновое воспроизведение
@@ -37,6 +53,7 @@
## Скачать
[<img src="https://i.ibb.co/jMwfXFd/rustore-light.png" alt="Скачать из RuStore" height="60">](https://apps.rustore.ru/app/it.hamy.muza)
[<img src="https://github.com/machiav3lli/oandbackupx/blob/034b226cea5c1b30eb4f6a6f313e4dadcbb0ece4/badge_github.png"
alt="Скачать из Гитхаба"
height="80">](https://github.com/hammsterr/muza/releases/latest)

BIN
ScreenShots/01.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

BIN
ScreenShots/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 KiB

BIN
ScreenShots/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

BIN
ScreenShots/3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 KiB

BIN
ScreenShots/4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

BIN
ScreenShots/5.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

View File

@@ -8,11 +8,11 @@ android {
compileSdk = 33
defaultConfig {
applicationId = "it.vfsfitvnm.vimusic"
applicationId = "it.hamy.muza"
minSdk = 21
targetSdk = 33
versionCode = 20
versionName = "0.5.4"
versionName = "0.5.4.1rus"
}
splits {
@@ -22,7 +22,7 @@ android {
}
}
namespace = "it.vfsfitvnm.vimusic"
namespace = "it.hamy.muza"
buildTypes {
debug {
@@ -33,7 +33,7 @@ android {
release {
isMinifyEnabled = true
isShrinkResources = true
manifestPlaceholders["appName"] = "ViMusic"
manifestPlaceholders["appName"] = "Muza"
signingConfig = signingConfigs.getByName("debug")
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
@@ -74,6 +74,8 @@ dependencies {
implementation(projects.composeRouting)
implementation(projects.composeReordering)
implementation(libs.compose.activity)
implementation(libs.compose.foundation)
implementation(libs.compose.ui)
@@ -85,8 +87,14 @@ dependencies {
implementation(libs.palette)
implementation(libs.exoplayer)
implementation(libs.exoplayer.okhttp)
implementation(libs.room)
implementation("androidx.media3:media3-datasource-okhttp:1.0.0-alpha03")
implementation ("com.yandex.android:mobileads:6.4.0")
implementation("com.google.android.gms:play-services-ads-identifier:18.0.1")
kapt(libs.room.compiler)
implementation(projects.innertube)

View File

@@ -31,4 +31,6 @@
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
-dontwarn org.openjsse.net.ssl.OpenJSSE
-dontwarn org.slf4j.impl.StaticLoggerBinder
-dontwarn org.slf4j.impl.StaticLoggerBinder
-keep class com.yandex** { *; }

View File

@@ -1,11 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove"/>
<queries>
<intent>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic
package it.hamy.muza
import android.content.ContentValues
import android.content.Context
@@ -31,30 +31,31 @@ import androidx.room.migration.Migration
import androidx.sqlite.db.SimpleSQLiteQuery
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.sqlite.db.SupportSQLiteQuery
import it.vfsfitvnm.vimusic.enums.AlbumSortBy
import it.vfsfitvnm.vimusic.enums.ArtistSortBy
import it.vfsfitvnm.vimusic.enums.PlaylistSortBy
import it.vfsfitvnm.vimusic.enums.SongSortBy
import it.vfsfitvnm.vimusic.enums.SortOrder
import it.vfsfitvnm.vimusic.models.Album
import it.vfsfitvnm.vimusic.models.Artist
import it.vfsfitvnm.vimusic.models.SongWithContentLength
import it.vfsfitvnm.vimusic.models.Event
import it.vfsfitvnm.vimusic.models.Format
import it.vfsfitvnm.vimusic.models.Info
import it.vfsfitvnm.vimusic.models.Lyrics
import it.vfsfitvnm.vimusic.models.Playlist
import it.vfsfitvnm.vimusic.models.PlaylistPreview
import it.vfsfitvnm.vimusic.models.PlaylistWithSongs
import it.vfsfitvnm.vimusic.models.QueuedMediaItem
import it.vfsfitvnm.vimusic.models.SearchQuery
import it.vfsfitvnm.vimusic.models.Song
import it.vfsfitvnm.vimusic.models.SongAlbumMap
import it.vfsfitvnm.vimusic.models.SongArtistMap
import it.vfsfitvnm.vimusic.models.SongPlaylistMap
import it.vfsfitvnm.vimusic.models.SortedSongPlaylistMap
import it.hamy.muza.enums.AlbumSortBy
import it.hamy.muza.enums.ArtistSortBy
import it.hamy.muza.enums.PlaylistSortBy
import it.hamy.muza.enums.SongSortBy
import it.hamy.muza.enums.SortOrder
import it.hamy.muza.models.Album
import it.hamy.muza.models.Artist
import it.hamy.muza.models.SongWithContentLength
import it.hamy.muza.models.Event
import it.hamy.muza.models.Format
import it.hamy.muza.models.Info
import it.hamy.muza.models.Lyrics
import it.hamy.muza.models.Playlist
import it.hamy.muza.models.PlaylistPreview
import it.hamy.muza.models.PlaylistWithSongs
import it.hamy.muza.models.QueuedMediaItem
import it.hamy.muza.models.SearchQuery
import it.hamy.muza.models.Song
import it.hamy.muza.models.SongAlbumMap
import it.hamy.muza.models.SongArtistMap
import it.hamy.muza.models.SongPlaylistMap
import it.hamy.muza.models.SortedSongPlaylistMap
import kotlin.jvm.Throws
import kotlinx.coroutines.flow.Flow
import it.hamy.muza.models.EventWithSong
@Dao
interface Database {
@@ -316,6 +317,11 @@ interface Database {
@RewriteQueriesToDropUnusedColumns
fun trending(now: Long = System.currentTimeMillis()): Flow<Song?>
@Transaction
@Query("SELECT * FROM Event ORDER BY timestamp DESC")
fun events(): Flow<List<EventWithSong>>
@Query("SELECT COUNT (*) FROM Event")
fun eventsCount(): Flow<Int>

View File

@@ -0,0 +1,14 @@
package it.hamy.muza
import it.hamy.muza.preferences.PreferencesHolder
object Dependencies {
lateinit var application: MainApplication
private set
internal fun init(application: MainApplication) {
this.application = application
}
}
open class GlobalPreferencesHolder : PreferencesHolder(Dependencies.application, "preferences")

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic
package it.hamy.muza
import android.content.ComponentName
import android.content.Context
@@ -58,42 +58,52 @@ import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import com.valentinilk.shimmer.LocalShimmerTheme
import com.valentinilk.shimmer.defaultShimmerTheme
import it.vfsfitvnm.compose.persist.PersistMap
import it.vfsfitvnm.compose.persist.PersistMapOwner
import it.vfsfitvnm.innertube.Innertube
import it.vfsfitvnm.innertube.models.bodies.BrowseBody
import it.vfsfitvnm.innertube.requests.playlistPage
import it.vfsfitvnm.innertube.requests.song
import it.vfsfitvnm.vimusic.enums.ColorPaletteMode
import it.vfsfitvnm.vimusic.enums.ColorPaletteName
import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
import it.vfsfitvnm.vimusic.service.PlayerService
import it.vfsfitvnm.vimusic.ui.components.BottomSheetMenu
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
import it.vfsfitvnm.vimusic.ui.components.rememberBottomSheetState
import it.vfsfitvnm.vimusic.ui.screens.albumRoute
import it.vfsfitvnm.vimusic.ui.screens.artistRoute
import it.vfsfitvnm.vimusic.ui.screens.home.HomeScreen
import it.vfsfitvnm.vimusic.ui.screens.player.Player
import it.vfsfitvnm.vimusic.ui.screens.playlistRoute
import it.vfsfitvnm.vimusic.ui.styling.Appearance
import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.colorPaletteOf
import it.vfsfitvnm.vimusic.ui.styling.dynamicColorPaletteOf
import it.vfsfitvnm.vimusic.ui.styling.typographyOf
import it.vfsfitvnm.vimusic.utils.applyFontPaddingKey
import it.vfsfitvnm.vimusic.utils.asMediaItem
import it.vfsfitvnm.vimusic.utils.colorPaletteModeKey
import it.vfsfitvnm.vimusic.utils.colorPaletteNameKey
import it.vfsfitvnm.vimusic.utils.forcePlay
import it.vfsfitvnm.vimusic.utils.getEnum
import it.vfsfitvnm.vimusic.utils.intent
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid6
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid8
import it.vfsfitvnm.vimusic.utils.preferences
import it.vfsfitvnm.vimusic.utils.thumbnailRoundnessKey
import it.vfsfitvnm.vimusic.utils.useSystemFontKey
import it.hamy.compose.persist.PersistMap
import it.hamy.compose.persist.PersistMapOwner
import it.hamy.innertube.utils.ProxyPreferenceItem
import it.hamy.innertube.utils.ProxyPreferences
import it.hamy.muza.utils.isProxyEnabledKey
import it.hamy.muza.utils.proxyHostNameKey
import it.hamy.muza.utils.proxyModeKey
import it.hamy.muza.utils.proxyPortKey
import java.net.Proxy
import it.hamy.innertube.Innertube
import it.hamy.innertube.models.bodies.BrowseBody
import it.hamy.innertube.requests.playlistPage
import it.hamy.innertube.requests.song
import it.hamy.muza.enums.ColorPaletteMode
import it.hamy.muza.enums.ColorPaletteName
import it.hamy.muza.enums.ThumbnailRoundness
import it.hamy.muza.service.PlayerService
import it.hamy.muza.ui.components.BottomSheetMenu
import it.hamy.muza.ui.components.LocalMenuState
import it.hamy.muza.ui.components.rememberBottomSheetState
import it.hamy.muza.ui.screens.albumRoute
import it.hamy.muza.ui.screens.artistRoute
import it.hamy.muza.ui.screens.home.HomeScreen
import it.hamy.muza.ui.screens.player.Player
import it.hamy.muza.ui.screens.playlistRoute
import it.hamy.muza.ui.styling.Appearance
import it.hamy.muza.ui.styling.Dimensions
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.ui.styling.colorPaletteOf
import it.hamy.muza.ui.styling.dynamicColorPaletteOf
import it.hamy.muza.ui.styling.typographyOf
import it.hamy.muza.utils.applyFontPaddingKey
import it.hamy.muza.utils.asMediaItem
import it.hamy.muza.utils.colorPaletteModeKey
import it.hamy.muza.utils.colorPaletteNameKey
import it.hamy.muza.utils.forcePlay
import it.hamy.muza.utils.getEnum
import it.hamy.muza.utils.intent
import it.hamy.muza.utils.isAtLeastAndroid6
import it.hamy.muza.utils.isAtLeastAndroid8
import it.hamy.muza.utils.preferences
import it.hamy.muza.utils.thumbnailRoundnessKey
import it.hamy.muza.utils.useSystemFontKey
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.filterNotNull
@@ -118,6 +128,7 @@ class MainActivity : ComponentActivity(), PersistMapOwner {
override lateinit var persistMap: PersistMap
override fun onStart() {
super.onStart()
bindService(intent<PlayerService>(), serviceConnection, Context.BIND_AUTO_CREATE)
@@ -127,6 +138,7 @@ class MainActivity : ComponentActivity(), PersistMapOwner {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@Suppress("DEPRECATION", "UNCHECKED_CAST")
persistMap = lastCustomNonConfigurationInstance as? PersistMap ?: PersistMap()
@@ -134,6 +146,17 @@ class MainActivity : ComponentActivity(), PersistMapOwner {
val launchedFromNotification = intent?.extras?.getBoolean("expandPlayerBottomSheet") == true
with(preferences){
if(getBoolean(isProxyEnabledKey,false)) {
val hostName = getString(proxyHostNameKey,null)
val proxyPort = getInt(proxyPortKey, 8080)
val proxyMode = getEnum(proxyModeKey, Proxy.Type.HTTP)
hostName?.let { hName->
ProxyPreferences.preference = ProxyPreferenceItem(hName,proxyPort,proxyMode)
}
}
}
setContent {
val coroutineScope = rememberCoroutineScope()
val isSystemInDarkTheme = isSystemInDarkTheme()
@@ -146,7 +169,7 @@ class MainActivity : ComponentActivity(), PersistMapOwner {
val colorPaletteName = getEnum(colorPaletteNameKey, ColorPaletteName.Dynamic)
val colorPaletteMode = getEnum(colorPaletteModeKey, ColorPaletteMode.System)
val thumbnailRoundness =
getEnum(thumbnailRoundnessKey, ThumbnailRoundness.Light)
getEnum(thumbnailRoundnessKey, ThumbnailRoundness.Слабое)
val useSystemFont = getBoolean(useSystemFontKey, false)
val applyFontPadding = getBoolean(applyFontPaddingKey, false)
@@ -245,7 +268,7 @@ class MainActivity : ComponentActivity(), PersistMapOwner {
thumbnailRoundnessKey -> {
val thumbnailRoundness =
sharedPreferences.getEnum(key, ThumbnailRoundness.Light)
sharedPreferences.getEnum(key, ThumbnailRoundness.Слабое)
appearance = appearance.copy(
thumbnailShape = thumbnailRoundness.shape()

View File

@@ -1,18 +1,25 @@
package it.vfsfitvnm.vimusic
package it.hamy.muza
import android.app.Application
import coil.ImageLoader
import coil.ImageLoaderFactory
import coil.disk.DiskCache
import it.vfsfitvnm.vimusic.enums.CoilDiskCacheMaxSize
import it.vfsfitvnm.vimusic.utils.coilDiskCacheMaxSizeKey
import it.vfsfitvnm.vimusic.utils.getEnum
import it.vfsfitvnm.vimusic.utils.preferences
import com.yandex.mobile.ads.common.MobileAds
import it.hamy.muza.enums.CoilDiskCacheMaxSize
import it.hamy.muza.utils.coilDiskCacheMaxSizeKey
import it.hamy.muza.utils.getEnum
import it.hamy.muza.utils.preferences
class MainApplication : Application(), ImageLoaderFactory {
override fun onCreate() {
super.onCreate()
DatabaseInitializer()
Dependencies.init(this)
MobileAds.initialize(this) {
/**
* Инициализация либы яндекса
*/
}
}
override fun newImageLoader(): ImageLoader {

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.enums
package it.hamy.muza.enums
enum class AlbumSortBy {
Title,

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.enums
package it.hamy.muza.enums
enum class ArtistSortBy {
Name,

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.enums
package it.hamy.muza.enums
enum class BuiltInPlaylist {
Favorites,

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.enums
package it.hamy.muza.enums
enum class CoilDiskCacheMaxSize {
`128MB`,

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.enums
package it.hamy.muza.enums
enum class ColorPaletteMode {
Light,

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.enums
package it.hamy.muza.enums
enum class ColorPaletteName {
Default,

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.enums
package it.hamy.muza.enums
enum class ExoPlayerDiskCacheMaxSize {
`32MB`,

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.enums
package it.hamy.muza.enums
enum class PlaylistSortBy {
Name,

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.enums
package it.hamy.muza.enums
enum class SongSortBy {
PlayTime,

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.enums
package it.hamy.muza.enums
enum class SortOrder {
Ascending,

View File

@@ -0,0 +1,24 @@
package it.hamy.muza.enums
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.unit.dp
enum class ThumbnailRoundness {
Отключено,
Слабое,
Среднее,
Сильное,
Максимальное;
fun shape(): Shape {
return when (this) {
Отключено -> RectangleShape
Слабое -> RoundedCornerShape(2.dp)
Среднее -> RoundedCornerShape(4.dp)
Сильное -> RoundedCornerShape(8.dp)
Максимальное -> RoundedCornerShape(14.dp)
}
}
}

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.Entity

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.Entity

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.ColumnInfo

View File

@@ -0,0 +1,16 @@
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.Embedded
import androidx.room.Relation
@Immutable
data class EventWithSong(
@Embedded val event: Event,
@Relation(
entity = Song::class,
parentColumn = "songId",
entityColumn = "id"
)
val song: Song
)

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.Entity

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
data class Info(
val id: String,

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.Entity

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.Entity

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.Embedded

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.Embedded

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.media3.common.MediaItem

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.Entity

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.Entity

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.ColumnInfo

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.ColumnInfo

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.ColumnInfo

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.Embedded

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.models
package it.hamy.muza.models
import androidx.compose.runtime.Immutable
import androidx.room.ColumnInfo

View File

@@ -0,0 +1,27 @@
package it.hamy.muza.preferences
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import it.hamy.muza.GlobalPreferencesHolder
import it.hamy.muza.R
import kotlin.time.Duration
import kotlin.time.Duration.Companion.days
object DataPreferences : GlobalPreferencesHolder() {
var topListLength by int(10)
var topListPeriod by enum(TopListPeriod.AllTime)
var quickPicksSource by enum(QuickPicksSource.Trending)
enum class TopListPeriod(val displayName: @Composable () -> String, val duration: Duration? = null) {
PastDay(displayName = { "Day" }, duration = 1.days),
PastWeek(displayName = { "Week" }, duration = 7.days),
PastMonth(displayName = { "Month" }, duration = 30.days),
PastYear(displayName = { "Year" }, 365.days),
AllTime(displayName = { "AllTime" })
}
enum class QuickPicksSource(val displayName: @Composable () -> String) {
Trending(displayName = { "Trend" }),
LastInteraction(displayName = { "LastInteraction" })
}
}

View File

@@ -0,0 +1,100 @@
package it.hamy.muza.preferences
import android.app.Application
import android.content.Context
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.snapshots.Snapshot
import androidx.core.content.edit
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
private val coroutineScope = CoroutineScope(Dispatchers.IO)
fun <T : Any> sharedPreferencesProperty(
getValue: SharedPreferences.(key: String) -> T,
setValue: SharedPreferences.Editor.(key: String, value: T) -> Unit,
defaultValue: T
) = object : ReadWriteProperty<PreferencesHolder, T> {
private var state = mutableStateOf(defaultValue)
private var listener: OnSharedPreferenceChangeListener? = null
override fun getValue(thisRef: PreferencesHolder, property: KProperty<*>): T {
if (listener == null && !Snapshot.current.readOnly) {
state.value = thisRef.getValue(property.name)
listener = OnSharedPreferenceChangeListener { preferences, key ->
if (key == property.name) preferences.getValue(property.name)
.let { if (it != state && !Snapshot.current.readOnly) state.value = it }
}
thisRef.registerOnSharedPreferenceChangeListener(listener)
}
return state.value
}
override fun setValue(thisRef: PreferencesHolder, property: KProperty<*>, value: T) =
coroutineScope.launch {
thisRef.edit(commit = true) {
setValue(property.name, value)
}
}.let { }
}
/**
* A snapshottable, thread-safe, compose-first, extensible SharedPreferences wrapper that supports
* virtually all types, and if it doesn't, one could simply type `fun myNewType(...) = sharedPreferencesProperty(...)`
* and start implementing. Starts off as given defaultValue until we are allowed to subscribe to SharedPreferences
* @sample AppearancePreferences
*/
open class PreferencesHolder(
application: Application,
name: String,
mode: Int = Context.MODE_PRIVATE
) : SharedPreferences by application.getSharedPreferences(name, mode) {
fun boolean(defaultValue: Boolean) = sharedPreferencesProperty(
getValue = { getBoolean(it, defaultValue) },
setValue = { k, v -> putBoolean(k, v) },
defaultValue
)
fun string(defaultValue: String) = sharedPreferencesProperty(
getValue = { getString(it, null) ?: defaultValue },
setValue = { k, v -> putString(k, v) },
defaultValue
)
fun int(defaultValue: Int) = sharedPreferencesProperty(
getValue = { getInt(it, defaultValue) },
setValue = { k, v -> putInt(k, v) },
defaultValue
)
fun float(defaultValue: Float) = sharedPreferencesProperty(
getValue = { getFloat(it, defaultValue) },
setValue = { k, v -> putFloat(k, v) },
defaultValue
)
fun long(defaultValue: Long) = sharedPreferencesProperty(
getValue = { getLong(it, defaultValue) },
setValue = { k, v -> putLong(k, v) },
defaultValue
)
inline fun <reified T : Enum<T>> enum(defaultValue: T) = sharedPreferencesProperty(
getValue = {
getString(it, null)?.let { runCatching { enumValueOf<T>(it) }.getOrNull() } ?: defaultValue
},
setValue = { k, v -> putString(k, v.name) },
defaultValue
)
fun stringSet(defaultValue: Set<String>) = sharedPreferencesProperty(
getValue = { getStringSet(it, null) ?: defaultValue },
setValue = { k, v -> putStringSet(k, v) },
defaultValue
)
}

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.service
package it.hamy.muza.service
import android.content.Context
import android.content.res.Configuration
@@ -9,7 +9,7 @@ import androidx.core.graphics.applyCanvas
import coil.imageLoader
import coil.request.Disposable
import coil.request.ImageRequest
import it.vfsfitvnm.vimusic.utils.thumbnail
import it.hamy.muza.utils.thumbnail
context(Context)
class BitmapProvider(

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.service
package it.hamy.muza.service
import androidx.media3.common.PlaybackException

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.service
package it.hamy.muza.service
import android.media.MediaDescription as BrowserMediaDescription
import android.media.browse.MediaBrowser.MediaItem as BrowserMediaItem
@@ -17,17 +17,17 @@ import androidx.core.net.toUri
import androidx.core.os.bundleOf
import androidx.media3.common.Player
import androidx.media3.datasource.cache.Cache
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.models.Album
import it.vfsfitvnm.vimusic.models.PlaylistPreview
import it.vfsfitvnm.vimusic.models.Song
import it.vfsfitvnm.vimusic.models.SongWithContentLength
import it.vfsfitvnm.vimusic.utils.asMediaItem
import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex
import it.vfsfitvnm.vimusic.utils.forceSeekToNext
import it.vfsfitvnm.vimusic.utils.forceSeekToPrevious
import it.vfsfitvnm.vimusic.utils.intent
import it.hamy.muza.Database
import it.hamy.muza.R
import it.hamy.muza.models.Album
import it.hamy.muza.models.PlaylistPreview
import it.hamy.muza.models.Song
import it.hamy.muza.models.SongWithContentLength
import it.hamy.muza.utils.asMediaItem
import it.hamy.muza.utils.forcePlayAtIndex
import it.hamy.muza.utils.forceSeekToNext
import it.hamy.muza.utils.forceSeekToPrevious
import it.hamy.muza.utils.intent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.service
package it.hamy.muza.service
import android.os.Binder as AndroidBinder
import android.annotation.SuppressLint
@@ -43,7 +43,14 @@ import androidx.media3.common.Player
import androidx.media3.common.Timeline
import androidx.media3.database.StandaloneDatabaseProvider
import androidx.media3.datasource.DataSource
import androidx.media3.datasource.DefaultHttpDataSource
import androidx.media3.datasource.okhttp.OkHttpDataSource
import it.hamy.innertube.utils.ProxyPreferences
import okhttp3.OkHttpClient
import java.net.InetSocketAddress
import java.net.Proxy
import java.time.Duration
import androidx.media3.datasource.ResolvingDataSource
import androidx.media3.datasource.cache.Cache
import androidx.media3.datasource.cache.CacheDataSource
@@ -67,45 +74,45 @@ import androidx.media3.exoplayer.source.MediaSource
import androidx.media3.extractor.ExtractorsFactory
import androidx.media3.extractor.mkv.MatroskaExtractor
import androidx.media3.extractor.mp4.FragmentedMp4Extractor
import it.vfsfitvnm.innertube.Innertube
import it.vfsfitvnm.innertube.models.NavigationEndpoint
import it.vfsfitvnm.innertube.models.bodies.PlayerBody
import it.vfsfitvnm.innertube.requests.player
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.MainActivity
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.enums.ExoPlayerDiskCacheMaxSize
import it.vfsfitvnm.vimusic.models.Event
import it.vfsfitvnm.vimusic.models.QueuedMediaItem
import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.utils.InvincibleService
import it.vfsfitvnm.vimusic.utils.RingBuffer
import it.vfsfitvnm.vimusic.utils.TimerJob
import it.vfsfitvnm.vimusic.utils.YouTubeRadio
import it.vfsfitvnm.vimusic.utils.activityPendingIntent
import it.vfsfitvnm.vimusic.utils.broadCastPendingIntent
import it.vfsfitvnm.vimusic.utils.exoPlayerDiskCacheMaxSizeKey
import it.vfsfitvnm.vimusic.utils.findNextMediaItemById
import it.vfsfitvnm.vimusic.utils.forcePlayFromBeginning
import it.vfsfitvnm.vimusic.utils.forceSeekToNext
import it.vfsfitvnm.vimusic.utils.forceSeekToPrevious
import it.vfsfitvnm.vimusic.utils.getEnum
import it.vfsfitvnm.vimusic.utils.intent
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid13
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid6
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid8
import it.vfsfitvnm.vimusic.utils.isInvincibilityEnabledKey
import it.vfsfitvnm.vimusic.utils.isShowingThumbnailInLockscreenKey
import it.vfsfitvnm.vimusic.utils.mediaItems
import it.vfsfitvnm.vimusic.utils.persistentQueueKey
import it.vfsfitvnm.vimusic.utils.preferences
import it.vfsfitvnm.vimusic.utils.queueLoopEnabledKey
import it.vfsfitvnm.vimusic.utils.resumePlaybackWhenDeviceConnectedKey
import it.vfsfitvnm.vimusic.utils.shouldBePlaying
import it.vfsfitvnm.vimusic.utils.skipSilenceKey
import it.vfsfitvnm.vimusic.utils.timer
import it.vfsfitvnm.vimusic.utils.trackLoopEnabledKey
import it.vfsfitvnm.vimusic.utils.volumeNormalizationKey
import it.hamy.innertube.Innertube
import it.hamy.innertube.models.NavigationEndpoint
import it.hamy.innertube.models.bodies.PlayerBody
import it.hamy.innertube.requests.player
import it.hamy.muza.Database
import it.hamy.muza.MainActivity
import it.hamy.muza.R
import it.hamy.muza.enums.ExoPlayerDiskCacheMaxSize
import it.hamy.muza.models.Event
import it.hamy.muza.models.QueuedMediaItem
import it.hamy.muza.query
import it.hamy.muza.utils.InvincibleService
import it.hamy.muza.utils.RingBuffer
import it.hamy.muza.utils.TimerJob
import it.hamy.muza.utils.YouTubeRadio
import it.hamy.muza.utils.activityPendingIntent
import it.hamy.muza.utils.broadCastPendingIntent
import it.hamy.muza.utils.exoPlayerDiskCacheMaxSizeKey
import it.hamy.muza.utils.findNextMediaItemById
import it.hamy.muza.utils.forcePlayFromBeginning
import it.hamy.muza.utils.forceSeekToNext
import it.hamy.muza.utils.forceSeekToPrevious
import it.hamy.muza.utils.getEnum
import it.hamy.muza.utils.intent
import it.hamy.muza.utils.isAtLeastAndroid13
import it.hamy.muza.utils.isAtLeastAndroid6
import it.hamy.muza.utils.isAtLeastAndroid8
import it.hamy.muza.utils.isInvincibilityEnabledKey
import it.hamy.muza.utils.isShowingThumbnailInLockscreenKey
import it.hamy.muza.utils.mediaItems
import it.hamy.muza.utils.persistentQueueKey
import it.hamy.muza.utils.preferences
import it.hamy.muza.utils.queueLoopEnabledKey
import it.hamy.muza.utils.resumePlaybackWhenDeviceConnectedKey
import it.hamy.muza.utils.shouldBePlaying
import it.hamy.muza.utils.skipSilenceKey
import it.hamy.muza.utils.timer
import it.hamy.muza.utils.trackLoopEnabledKey
import it.hamy.muza.utils.volumeNormalizationKey
import kotlin.math.roundToInt
import kotlin.system.exitProcess
import kotlinx.coroutines.CoroutineScope
@@ -737,12 +744,24 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
}
}
private fun okHttpClient() : OkHttpClient{
ProxyPreferences.preference?.let{
return OkHttpClient.Builder()
.proxy(Proxy(it.proxyMode,InetSocketAddress(it.proxyHost,it.proxyPort)))
.connectTimeout(Duration.ofSeconds(16))
.readTimeout(Duration.ofSeconds(8))
.build()
}
return OkHttpClient.Builder()
.connectTimeout(Duration.ofSeconds(16))
.readTimeout(Duration.ofSeconds(8))
.build()
}
private fun createCacheDataSource(): DataSource.Factory {
return CacheDataSource.Factory().setCache(cache).apply {
setUpstreamDataSourceFactory(
DefaultHttpDataSource.Factory()
.setConnectTimeoutMs(16000)
.setReadTimeoutMs(8000)
OkHttpDataSource.Factory(okHttpClient())
.setUserAgent("Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0")
)
}
@@ -791,7 +810,7 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
mediaItem?.let(Database::insert)
Database.insert(
it.vfsfitvnm.vimusic.models.Format(
it.hamy.muza.models.Format(
songId = videoId,
itag = format.itag,
mimeType = format.mimeType,
@@ -991,10 +1010,10 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
)
companion object {
val pause = Action("it.vfsfitvnm.vimusic.pause")
val play = Action("it.vfsfitvnm.vimusic.play")
val next = Action("it.vfsfitvnm.vimusic.next")
val previous = Action("it.vfsfitvnm.vimusic.previous")
val pause = Action("it.hamy.muza.pause")
val play = Action("it.hamy.muza.play")
val next = Action("it.hamy.muza.next")
val previous = Action("it.hamy.muza.previous")
}
}

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components
package it.hamy.muza.ui.components
import androidx.activity.compose.BackHandler
import androidx.compose.animation.core.Animatable

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components
package it.hamy.muza.ui.components
import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components
package it.hamy.muza.ui.components
import androidx.compose.animation.core.Animatable
import androidx.compose.foundation.Canvas

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components
package it.hamy.muza.ui.components
import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.animation.core.animateDp

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components
package it.hamy.muza.ui.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column

View File

@@ -0,0 +1,87 @@
package it.hamy.muza.ui.components
import android.os.CountDownTimer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
import com.yandex.mobile.ads.banner.BannerAdEventListener
import com.yandex.mobile.ads.banner.BannerAdSize
import com.yandex.mobile.ads.banner.BannerAdView
import com.yandex.mobile.ads.common.AdRequest
import com.yandex.mobile.ads.common.AdRequestError
import com.yandex.mobile.ads.common.AdTheme
import com.yandex.mobile.ads.common.ImpressionData
@Composable
fun YandexAdsBanner(id: String) {
AndroidView(modifier = Modifier.fillMaxSize(), factory = { context ->
BannerAdView(context).apply {
/**
* ID блока рекламы
*/
setAdUnitId(id)
/**
* Размер блока рекламы
*/
setAdSize(BannerAdSize.inlineSize(context, 110, 110))
/**
* Билдер запроса
*/
val adRequest = AdRequest.Builder()
.setPreferredTheme(AdTheme.DARK)
.build()
val timer = object : CountDownTimer(4000, 1000) {
override fun onTick(millisUntilFinished: Long) {
// Здесь можно выполнить действия, которые нужно сделать каждую секунду
}
override fun onFinish() {
// Здесь вызывается метод loadAd(adRequest) после истечения таймера
loadAd(adRequest)
// Здесь можно повторить таймер, чтобы он всегда повторялся
//start()
}
}
/**
* Слушатель экшнов
*/
setBannerAdEventListener(object : BannerAdEventListener {
override fun onAdLoaded() {
// Запускаем таймер
timer.start()
}
override fun onAdFailedToLoad(p0: AdRequestError) {
/**
* Тут дебажим ошибки
*/
}
override fun onAdClicked() {
}
override fun onLeftApplication() {
}
override fun onReturnedToApplication() {
loadAd(adRequest)
}
override fun onImpression(p0: ImpressionData?) {
}
})
/**
* Запуск баннера
*/
loadAd(adRequest)
}
})
}

View File

@@ -0,0 +1,90 @@
package it.hamy.muza.ui.components
import android.os.CountDownTimer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
import com.yandex.mobile.ads.banner.BannerAdEventListener
import com.yandex.mobile.ads.banner.BannerAdSize
import com.yandex.mobile.ads.banner.BannerAdView
import com.yandex.mobile.ads.common.AdRequest
import com.yandex.mobile.ads.common.AdRequestError
import com.yandex.mobile.ads.common.AdTheme
import com.yandex.mobile.ads.common.ImpressionData
@Composable
fun YandexAdsBannerQuickPicksCenter(id: String) {
AndroidView(modifier = Modifier.fillMaxSize(), factory = { context ->
BannerAdView(context).apply {
/**
* ID блока рекламы
*/
setAdUnitId(id)
/**
* Размер блока рекламы
*/
setAdSize(BannerAdSize.inlineSize(context, 260, 60))
/**
* Билдер запроса
*/
val adRequest = AdRequest.Builder()
.setPreferredTheme(AdTheme.DARK)
.build()
val timer = object : CountDownTimer(4000, 1000) {
override fun onTick(millisUntilFinished: Long) {
// Здесь можно выполнить действия, которые нужно сделать каждую секунду
}
override fun onFinish() {
// Здесь вызывается метод loadAd(adRequest) после истечения таймера
loadAd(adRequest)
// Здесь можно повторить таймер, чтобы он всегда повторялся
//start()
}
}
/**
* Слушатель экшнов
*/
setBannerAdEventListener(object : BannerAdEventListener {
override fun onAdLoaded() {
// Запускаем таймер
timer.start()
}
override fun onAdFailedToLoad(p0: AdRequestError) {
/**
* Тут дебажим ошибки
*/
loadAd(adRequest)
}
override fun onAdClicked() {
}
override fun onLeftApplication() {
}
override fun onReturnedToApplication() {
loadAd(adRequest)
}
override fun onImpression(p0: ImpressionData?) {
}
})
/**
* Запуск баннера
*/
loadAd(adRequest)
}
})
}

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
@@ -48,12 +48,12 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.center
import it.vfsfitvnm.vimusic.utils.drawCircle
import it.vfsfitvnm.vimusic.utils.medium
import it.vfsfitvnm.vimusic.utils.secondary
import it.vfsfitvnm.vimusic.utils.semiBold
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.utils.center
import it.hamy.muza.utils.drawCircle
import it.hamy.muza.utils.medium
import it.hamy.muza.utils.secondary
import it.hamy.muza.utils.semiBold
import kotlinx.coroutines.delay
@Composable
@@ -62,8 +62,8 @@ fun TextFieldDialog(
onDismiss: () -> Unit,
onDone: (String) -> Unit,
modifier: Modifier = Modifier,
cancelText: String = "Cancel",
doneText: String = "Done",
cancelText: String = "Отмена",
doneText: String = "Готово",
initialTextInput: String = "",
singleLine: Boolean = true,
maxLines: Int = 1,
@@ -167,8 +167,8 @@ fun ConfirmationDialog(
onDismiss: () -> Unit,
onConfirm: () -> Unit,
modifier: Modifier = Modifier,
cancelText: String = "Cancel",
confirmText: String = "Confirm",
cancelText: String = "Отменить",
confirmText: String = "Продолжить",
onCancel: () -> Unit = onDismiss
) {
val (_, typography) = LocalAppearance.current
@@ -324,7 +324,7 @@ inline fun <T> ValueSelectorDialog(
.padding(end = 24.dp)
) {
DialogTextButton(
text = "Cancel",
text = "Отмена",
onClick = onDismiss,
modifier = Modifier
)

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@@ -10,9 +10,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.color
import it.vfsfitvnm.vimusic.utils.medium
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.utils.color
import it.hamy.muza.utils.medium
@Composable
fun DialogTextButton(

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
@@ -24,11 +24,11 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.utils.ScrollingInfo
import it.vfsfitvnm.vimusic.utils.scrollingInfo
import it.vfsfitvnm.vimusic.utils.smoothScrollToTop
import it.hamy.muza.LocalPlayerAwareWindowInsets
import it.hamy.muza.R
import it.hamy.muza.utils.ScrollingInfo
import it.hamy.muza.utils.scrollingInfo
import it.hamy.muza.utils.smoothScrollToTop
import kotlinx.coroutines.launch
@ExperimentalAnimationApi

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
@@ -16,10 +16,10 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.shimmer
import it.vfsfitvnm.vimusic.utils.medium
import it.hamy.muza.ui.styling.Dimensions
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.ui.styling.shimmer
import it.hamy.muza.utils.medium
import kotlin.random.Random
@Composable

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.BoxWithConstraints
@@ -14,11 +14,11 @@ import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import com.valentinilk.shimmer.shimmer
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.px
import it.vfsfitvnm.vimusic.ui.styling.shimmer
import it.vfsfitvnm.vimusic.utils.isLandscape
import it.vfsfitvnm.vimusic.utils.thumbnail
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.ui.styling.px
import it.hamy.muza.ui.styling.shimmer
import it.hamy.muza.utils.isLandscape
import it.hamy.muza.utils.thumbnail
@Composable
inline fun LayoutWithAdaptiveThumbnail(

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import android.content.Intent
import androidx.activity.compose.BackHandler
@@ -43,34 +43,33 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.media3.common.MediaItem
import it.vfsfitvnm.innertube.models.NavigationEndpoint
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.enums.PlaylistSortBy
import it.vfsfitvnm.vimusic.enums.SortOrder
import it.vfsfitvnm.vimusic.models.Info
import it.vfsfitvnm.vimusic.models.Playlist
import it.vfsfitvnm.vimusic.models.Song
import it.vfsfitvnm.vimusic.models.SongPlaylistMap
import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.transaction
import it.vfsfitvnm.vimusic.ui.items.SongItem
import it.vfsfitvnm.vimusic.ui.screens.albumRoute
import it.vfsfitvnm.vimusic.ui.screens.artistRoute
import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.favoritesIcon
import it.vfsfitvnm.vimusic.ui.styling.px
import it.vfsfitvnm.vimusic.utils.addNext
import it.vfsfitvnm.vimusic.utils.asMediaItem
import it.vfsfitvnm.vimusic.utils.enqueue
import it.vfsfitvnm.vimusic.utils.forcePlay
import it.vfsfitvnm.vimusic.utils.formatAsDuration
import it.vfsfitvnm.vimusic.utils.medium
import it.vfsfitvnm.vimusic.utils.semiBold
import it.vfsfitvnm.vimusic.utils.thumbnail
import kotlin.system.measureTimeMillis
import it.hamy.innertube.models.NavigationEndpoint
import it.hamy.muza.Database
import it.hamy.muza.LocalPlayerServiceBinder
import it.hamy.muza.R
import it.hamy.muza.enums.PlaylistSortBy
import it.hamy.muza.enums.SortOrder
import it.hamy.muza.models.Info
import it.hamy.muza.models.Playlist
import it.hamy.muza.models.Song
import it.hamy.muza.models.SongPlaylistMap
import it.hamy.muza.query
import it.hamy.muza.transaction
import it.hamy.muza.ui.items.SongItem
import it.hamy.muza.ui.screens.albumRoute
import it.hamy.muza.ui.screens.artistRoute
import it.hamy.muza.ui.styling.Dimensions
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.ui.styling.favoritesIcon
import it.hamy.muza.ui.styling.px
import it.hamy.muza.utils.addNext
import it.hamy.muza.utils.asMediaItem
import it.hamy.muza.utils.enqueue
import it.hamy.muza.utils.forcePlay
import it.hamy.muza.utils.formatAsDuration
import it.hamy.muza.utils.medium
import it.hamy.muza.utils.semiBold
import it.hamy.muza.utils.thumbnail
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.withContext
@@ -90,7 +89,7 @@ fun InHistoryMediaItemMenu(
if (isHiding) {
ConfirmationDialog(
text = "Do you really want to hide this song? Its playback time and cache will be wiped.\nThis action is irreversible.",
text = "Вы действительно хотите скрыть эту песню? Время воспроизведения и кэш будут удалены.\n" + "Это действие необратимо",
onDismiss = { isHiding = false },
onConfirm = {
onDismiss()
@@ -331,7 +330,7 @@ fun MediaItemMenu(
if (isCreatingNewPlaylist && onAddToPlaylist != null) {
TextFieldDialog(
hintText = "Enter the playlist name",
hintText = "Введите название плейлиста",
onDismiss = { isCreatingNewPlaylist = false },
onDone = { text ->
onDismiss()
@@ -366,7 +365,7 @@ fun MediaItemMenu(
if (onAddToPlaylist != null) {
SecondaryTextButton(
text = "New playlist",
text = "Новый плейлист",
onClick = { isCreatingNewPlaylist = true },
alternative = true
)
@@ -378,7 +377,7 @@ fun MediaItemMenu(
MenuEntry(
icon = R.drawable.playlist,
text = playlistPreview.playlist.name,
secondaryText = "${playlistPreview.songCount} songs",
secondaryText = "${playlistPreview.songCount} песен",
onClick = {
onDismiss()
onAddToPlaylist(playlistPreview.playlist, playlistPreview.songCount)
@@ -464,7 +463,7 @@ fun MediaItemMenu(
onStartRadio?.let { onStartRadio ->
MenuEntry(
icon = R.drawable.radio,
text = "Start radio",
text = "Включить радио",
onClick = {
onDismiss()
onStartRadio()
@@ -475,7 +474,7 @@ fun MediaItemMenu(
onPlayNext?.let { onPlayNext ->
MenuEntry(
icon = R.drawable.play_skip_forward,
text = "Play next",
text = "Следующая",
onClick = {
onDismiss()
onPlayNext()
@@ -486,7 +485,7 @@ fun MediaItemMenu(
onEnqueue?.let { onEnqueue ->
MenuEntry(
icon = R.drawable.enqueue,
text = "Enqueue",
text = "В очередь",
onClick = {
onDismiss()
onEnqueue()
@@ -497,7 +496,7 @@ fun MediaItemMenu(
onGoToEqualizer?.let { onGoToEqualizer ->
MenuEntry(
icon = R.drawable.equalizer,
text = "Equalizer",
text = "Эквалайзер",
onClick = {
onDismiss()
onGoToEqualizer()
@@ -521,9 +520,9 @@ fun MediaItemMenu(
if (isShowingSleepTimerDialog) {
if (sleepTimerMillisLeft != null) {
ConfirmationDialog(
text = "Do you want to stop the sleep timer?",
cancelText = "No",
confirmText = "Stop",
text = "Вы хотите отключить таймер сна?",
cancelText = "нет",
confirmText = "отключить",
onDismiss = { isShowingSleepTimerDialog = false },
onConfirm = {
binder?.cancelSleepTimer()
@@ -539,7 +538,7 @@ fun MediaItemMenu(
}
BasicText(
text = "Set sleep timer",
text = "Установить таймер сна",
style = typography.s.semiBold,
modifier = Modifier
.padding(vertical = 8.dp, horizontal = 24.dp)
@@ -571,13 +570,13 @@ fun MediaItemMenu(
Box(contentAlignment = Alignment.Center) {
BasicText(
text = "88h 88m",
text = "88ч 88м",
style = typography.s.semiBold,
modifier = Modifier
.alpha(0f)
)
BasicText(
text = "${amount / 6}h ${(amount % 6) * 10}m",
text = "${amount / 6}ч ${(amount % 6) * 10}м",
style = typography.s.semiBold
)
}
@@ -604,12 +603,12 @@ fun MediaItemMenu(
.fillMaxWidth()
) {
DialogTextButton(
text = "Cancel",
text = "Отмена",
onClick = { isShowingSleepTimerDialog = false }
)
DialogTextButton(
text = "Set",
text = "Установить",
enabled = amount > 0,
primary = true,
onClick = {
@@ -624,12 +623,12 @@ fun MediaItemMenu(
MenuEntry(
icon = R.drawable.alarm,
text = "Sleep timer",
text = "Таймер сна",
onClick = { isShowingSleepTimerDialog = true },
trailingContent = sleepTimerMillisLeft?.let {
{
BasicText(
text = "${formatAsDuration(it)} left",
text = "Осталось ${formatAsDuration(it)}",
style = typography.xxs.medium,
modifier = modifier
.background(
@@ -647,7 +646,7 @@ fun MediaItemMenu(
if (onAddToPlaylist != null) {
MenuEntry(
icon = R.drawable.playlist,
text = "Add to playlist",
text = "Добавить в плейлист",
onClick = { isViewingPlaylists = true },
trailingContent = {
Image(
@@ -667,7 +666,7 @@ fun MediaItemMenu(
albumInfo?.let { (albumId) ->
MenuEntry(
icon = R.drawable.disc,
text = "Go to album",
text = "Перейти в альбом",
onClick = {
onDismiss()
onGoToAlbum(albumId)
@@ -680,7 +679,7 @@ fun MediaItemMenu(
artistsInfo?.forEach { (authorId, authorName) ->
MenuEntry(
icon = R.drawable.person,
text = "More of $authorName",
text = "Больше от $authorName",
onClick = {
onDismiss()
onGoToArtist(authorId)
@@ -692,7 +691,7 @@ fun MediaItemMenu(
onRemoveFromQueue?.let { onRemoveFromQueue ->
MenuEntry(
icon = R.drawable.trash,
text = "Remove from queue",
text = "Убрать из очереди",
onClick = {
onDismiss()
onRemoveFromQueue()
@@ -703,7 +702,7 @@ fun MediaItemMenu(
onRemoveFromPlaylist?.let { onRemoveFromPlaylist ->
MenuEntry(
icon = R.drawable.trash,
text = "Remove from playlist",
text = "Удалить из плейлиста",
onClick = {
onDismiss()
onRemoveFromPlaylist()
@@ -714,7 +713,7 @@ fun MediaItemMenu(
onHideFromDatabase?.let { onHideFromDatabase ->
MenuEntry(
icon = R.drawable.trash,
text = "Hide",
text = "Скрыть",
onClick = onHideFromDatabase
)
}
@@ -722,7 +721,7 @@ fun MediaItemMenu(
onRemoveFromQuickPicks?.let {
MenuEntry(
icon = R.drawable.trash,
text = "Hide from \"Quick picks\"",
text = "Скрыть из \"Обзора\"",
onClick = {
onDismiss()
onRemoveFromQuickPicks()

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
@@ -22,9 +22,9 @@ import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.medium
import it.vfsfitvnm.vimusic.utils.secondary
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.utils.medium
import it.hamy.muza.utils.secondary
@Composable
inline fun Menu(

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import androidx.compose.animation.animateColor
import androidx.compose.animation.core.animateFloat
@@ -32,13 +32,13 @@ import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.layout
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.center
import it.vfsfitvnm.vimusic.utils.color
import it.vfsfitvnm.vimusic.utils.isLandscape
import it.vfsfitvnm.vimusic.utils.semiBold
import it.hamy.muza.LocalPlayerAwareWindowInsets
import it.hamy.muza.ui.styling.Dimensions
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.utils.center
import it.hamy.muza.utils.color
import it.hamy.muza.utils.isLandscape
import it.hamy.muza.utils.semiBold
@Composable
inline fun NavigationRail(

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
@@ -14,8 +14,8 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.primaryButton
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.ui.styling.primaryButton
@Composable
fun PrimaryButton(

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedContentScope
@@ -15,7 +15,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.IntOffset
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.hamy.muza.ui.styling.LocalAppearance
@ExperimentalAnimationApi
@Composable

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
@@ -14,8 +14,8 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.primaryButton
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.ui.styling.primaryButton
@Composable
fun SecondaryButton(

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@@ -9,9 +9,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.primaryButton
import it.vfsfitvnm.vimusic.utils.medium
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.ui.styling.primaryButton
import it.hamy.muza.utils.medium
@Composable
fun SecondaryTextButton(

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import androidx.compose.animation.animateColor
import androidx.compose.animation.core.animateDp
@@ -14,8 +14,8 @@ import androidx.compose.ui.geometry.center
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.drawCircle
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.utils.drawCircle
@Composable
fun Switch(

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.components.themed
package it.hamy.muza.ui.components.themed
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Spacer
@@ -10,8 +10,8 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.shimmer
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.ui.styling.shimmer
import kotlin.random.Random
@Composable

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.items
package it.hamy.muza.ui.items
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Spacer
@@ -13,14 +13,14 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import it.vfsfitvnm.vimusic.models.Album
import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.shimmer
import it.vfsfitvnm.vimusic.utils.secondary
import it.vfsfitvnm.vimusic.utils.semiBold
import it.vfsfitvnm.vimusic.utils.thumbnail
import it.vfsfitvnm.innertube.Innertube
import it.hamy.muza.models.Album
import it.hamy.muza.ui.components.themed.TextPlaceholder
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.ui.styling.shimmer
import it.hamy.muza.utils.secondary
import it.hamy.muza.utils.semiBold
import it.hamy.muza.utils.thumbnail
import it.hamy.innertube.Innertube
@Composable
fun AlbumItem(

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.items
package it.hamy.muza.ui.items
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Spacer
@@ -15,14 +15,14 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import it.vfsfitvnm.vimusic.models.Artist
import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.shimmer
import it.vfsfitvnm.vimusic.utils.secondary
import it.vfsfitvnm.vimusic.utils.semiBold
import it.vfsfitvnm.vimusic.utils.thumbnail
import it.vfsfitvnm.innertube.Innertube
import it.hamy.muza.models.Artist
import it.hamy.muza.ui.components.themed.TextPlaceholder
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.ui.styling.shimmer
import it.hamy.muza.utils.secondary
import it.hamy.muza.utils.semiBold
import it.hamy.muza.utils.thumbnail
import it.hamy.innertube.Innertube
@Composable
fun ArtistItem(

View File

@@ -1,10 +1,9 @@
package it.vfsfitvnm.vimusic.ui.items
package it.hamy.muza.ui.items
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
@@ -13,7 +12,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.hamy.muza.ui.styling.Dimensions
@Composable
inline fun ItemContainer(

View File

@@ -1,4 +1,4 @@
package it.vfsfitvnm.vimusic.ui.items
package it.hamy.muza.ui.items
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
@@ -27,19 +27,19 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.models.PlaylistPreview
import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.onOverlay
import it.vfsfitvnm.vimusic.ui.styling.overlay
import it.vfsfitvnm.vimusic.ui.styling.shimmer
import it.vfsfitvnm.vimusic.utils.color
import it.vfsfitvnm.vimusic.utils.medium
import it.vfsfitvnm.vimusic.utils.secondary
import it.vfsfitvnm.vimusic.utils.semiBold
import it.vfsfitvnm.vimusic.utils.thumbnail
import it.vfsfitvnm.innertube.Innertube
import it.hamy.muza.Database
import it.hamy.muza.models.PlaylistPreview
import it.hamy.muza.ui.components.themed.TextPlaceholder
import it.hamy.muza.ui.styling.LocalAppearance
import it.hamy.muza.ui.styling.onOverlay
import it.hamy.muza.ui.styling.overlay
import it.hamy.muza.ui.styling.shimmer
import it.hamy.muza.utils.color
import it.hamy.muza.utils.medium
import it.hamy.muza.utils.secondary
import it.hamy.muza.utils.semiBold
import it.hamy.muza.utils.thumbnail
import it.hamy.innertube.Innertube
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map

Some files were not shown because too many files have changed in this diff Show More