├── .github
├── dependabot.yml
└── workflows
│ ├── crowdin-contributors.yml
│ ├── mr-checks.yml
│ └── release.yml
├── .gitignore
├── .idea
├── deploymentTargetSelector.xml
├── icon.svg
└── migrations.xml
├── LICENSE
├── PRIVACY_POLICY.md
├── README.md
├── androidApp
├── .gitignore
├── build.gradle.kts
└── src
│ └── androidMain
│ ├── AndroidManifest.xml
│ ├── ic_launcher-playstore.png
│ ├── kotlin
│ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ ├── AndroidDi.kt
│ │ ├── App.kt
│ │ ├── EmptyActivityLifecycleCallback.kt
│ │ ├── MainActivity.kt
│ │ └── audio
│ │ ├── MusicService.kt
│ │ ├── auto
│ │ ├── Auto.kt
│ │ ├── AutoMediaSessionCallback.kt
│ │ ├── AutoRepository.kt
│ │ ├── AutoRepositoryImpl.kt
│ │ ├── Mapper.kt
│ │ └── MediaLibrary.kt
│ │ └── player
│ │ ├── PlayQueueSyncActivityCallback.kt
│ │ └── ProgressSyncActivityCallback.kt
│ └── res
│ ├── drawable-hdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── drawable-mdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable-xhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── drawable-xxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── drawable-xxxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── drawable
│ └── ic_launcher_background.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── values
│ ├── ic_launcher_background.xml
│ ├── strings.xml
│ └── styles.xml
│ └── xml
│ ├── automotive_app_desc.xml
│ └── network_security_config.xml
├── app
├── .gitignore
├── build.gradle.kts
└── src
│ └── commonMain
│ ├── composeResources
│ ├── drawable-hdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ ├── drawable-mdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ ├── drawable-xhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ ├── drawable-xxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ └── drawable-xxxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ └── kotlin
│ └── ru
│ └── stersh
│ └── youamp
│ ├── ApiProviderImpl.kt
│ ├── Di.kt
│ ├── app
│ ├── data
│ │ ├── AvatarUrlRepositoryImpl.kt
│ │ └── ServerExistRepositoryImpl.kt
│ ├── domain
│ │ ├── AvatarUrlRepository.kt
│ │ └── ServerExistRepository.kt
│ └── ui
│ │ ├── MainScreen.kt
│ │ ├── MainViewModel.kt
│ │ ├── Navigation.kt
│ │ ├── StateUi.kt
│ │ └── YouampApp.kt
│ └── player
│ ├── ApiSonicPlayQueueSyncer.kt
│ └── ScrobbleSender.kt
├── assets
└── bage
│ └── get_it_on_github.png
├── build.gradle.kts
├── buildSrc
├── .gitignore
├── build.gradle.kts
└── src
│ └── main
│ └── kotlin
│ └── ru
│ └── stersh
│ └── youamp
│ └── AppBuildInfo.kt
├── core
├── api
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ ├── androidMain
│ │ └── AndroidManifest.xml
│ │ └── commonMain
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── core
│ │ └── api
│ │ ├── ApiDefaults.kt
│ │ ├── ApiProvider.kt
│ │ └── NoActiveServerSettingsFound.kt
├── db
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ ├── androidMain
│ │ ├── AndroidManifest.xml
│ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── core
│ │ │ └── db
│ │ │ └── Database.kt
│ │ ├── commonMain
│ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── core
│ │ │ └── db
│ │ │ ├── AppDatabase.kt
│ │ │ ├── Di.kt
│ │ │ └── server
│ │ │ ├── SubsonicServerDao.kt
│ │ │ └── SubsonicServerDb.kt
│ │ ├── desktopMain
│ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── core
│ │ │ └── db
│ │ │ └── Database.kt
│ │ └── iosMain
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── core
│ │ └── db
│ │ └── Database.kt
├── player
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ ├── androidMain
│ │ ├── AndroidManifest.xml
│ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── core
│ │ │ └── player
│ │ │ ├── AndroidPlayer.kt
│ │ │ ├── Di.kt
│ │ │ ├── Mapper.kt
│ │ │ └── PlayerConcurrency.kt
│ │ ├── commonMain
│ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── core
│ │ │ └── player
│ │ │ ├── Di.kt
│ │ │ ├── MediaItem.kt
│ │ │ ├── Player.kt
│ │ │ ├── PlayerProgress.kt
│ │ │ ├── RepeatMode.kt
│ │ │ └── ShuffleMode.kt
│ │ └── desktopMain
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── core
│ │ └── player
│ │ ├── DesktopPlayer.kt
│ │ └── Di.desktop.kt
├── properties
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ ├── androidMain
│ │ └── AndroidManifest.xml
│ │ └── commonMain
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── core
│ │ ├── Di.kt
│ │ └── properties
│ │ └── app
│ │ ├── AppProperties.kt
│ │ ├── AppPropertiesStorage.kt
│ │ └── AppPropertiesStorageImpl.kt
├── ui
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ ├── androidMain
│ │ ├── AndroidManifest.xml
│ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── core
│ │ │ └── ui
│ │ │ └── Theme.android.kt
│ │ ├── commonMain
│ │ ├── composeResources
│ │ │ ├── font
│ │ │ │ ├── montserrat_bold.ttf
│ │ │ │ ├── montserrat_italic.ttf
│ │ │ │ ├── montserrat_light.ttf
│ │ │ │ ├── montserrat_medium.ttf
│ │ │ │ └── montserrat_regular.ttf
│ │ │ ├── values-ca-rES
│ │ │ │ └── strings.xml
│ │ │ ├── values-de-rDE
│ │ │ │ └── strings.xml
│ │ │ ├── values-fr-rFR
│ │ │ │ └── strings.xml
│ │ │ ├── values-it-rIT
│ │ │ │ └── strings.xml
│ │ │ ├── values-pt-rBR
│ │ │ │ └── strings.xml
│ │ │ ├── values-ru-rRU
│ │ │ │ └── strings.xml
│ │ │ ├── values-zh-rCN
│ │ │ │ └── strings.xml
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── core
│ │ │ └── ui
│ │ │ ├── Album.kt
│ │ │ ├── Artist.kt
│ │ │ ├── Artwork.kt
│ │ │ ├── Avatar.kt
│ │ │ ├── BackNavigationButton.kt
│ │ │ ├── Color.kt
│ │ │ ├── Dp.kt
│ │ │ ├── DragAndDropLazyColumn.kt
│ │ │ ├── Empty.kt
│ │ │ ├── Error.kt
│ │ │ ├── Header.kt
│ │ │ ├── HeaderButtons.kt
│ │ │ ├── MovePosition.kt
│ │ │ ├── PlayAllButton.kt
│ │ │ ├── PlayButton.kt
│ │ │ ├── Playlist.kt
│ │ │ ├── ProgressSlider.kt
│ │ │ ├── RoundedIcon.kt
│ │ │ ├── SectionTitle.kt
│ │ │ ├── Skeleton.kt
│ │ │ ├── Song.kt
│ │ │ ├── SongMenu.kt
│ │ │ ├── SongPlayAnimation.kt
│ │ │ ├── StateLayout.kt
│ │ │ ├── Text.kt
│ │ │ ├── Theme.kt
│ │ │ ├── Type.kt
│ │ │ ├── Utils.kt
│ │ │ ├── VerticalGrid.kt
│ │ │ └── WindowSizeClass.kt
│ │ └── desktopMain
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── core
│ │ └── ui
│ │ └── Theme.desktop.kt
└── utils
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ ├── androidMain
│ └── AndroidManifest.xml
│ └── commonMain
│ └── kotlin
│ └── ru
│ └── stersh
│ └── youamp
│ └── core
│ └── utils
│ ├── Flow.kt
│ ├── List.kt
│ ├── Paginator.kt
│ └── Time.kt
├── crowdin.yml
├── desktopApp
├── .gitignore
├── build.gradle.kts
└── src
│ ├── commonMain
│ └── composeResources
│ │ ├── drawable-hdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── drawable-mdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── drawable-xhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── drawable-xxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ └── drawable-xxxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ └── desktopMain
│ └── kotlin
│ └── ru
│ └── stersh
│ └── youamp
│ ├── DesktopDi.kt
│ └── Main.kt
├── fastlane
└── metadata
│ └── android
│ ├── ca
│ ├── full_description.txt
│ └── short_description.txt
│ ├── de-DE
│ ├── full_description.txt
│ └── short_description.txt
│ ├── en-US
│ ├── full_description.txt
│ ├── images
│ │ ├── featureGraphic.png
│ │ ├── icon.png
│ │ └── phoneScreenshots
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ ├── 3.png
│ │ │ ├── 4.png
│ │ │ ├── 5.png
│ │ │ ├── 6.png
│ │ │ ├── 7.png
│ │ │ └── 8.png
│ ├── short_description.txt
│ ├── title.txt
│ └── video.txt
│ ├── fr-FR
│ ├── full_description.txt
│ └── short_description.txt
│ ├── it-IT
│ ├── full_description.txt
│ └── short_description.txt
│ ├── pt-BR
│ ├── full_description.txt
│ └── short_description.txt
│ ├── ru-RU
│ ├── full_description.txt
│ └── short_description.txt
│ └── zh-CN
│ ├── full_description.txt
│ └── short_description.txt
├── feature
├── about
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ ├── androidMain
│ │ └── AndroidManifest.xml
│ │ └── commonMain
│ │ ├── composeResources
│ │ ├── values-ca-rES
│ │ │ └── strings.xml
│ │ ├── values-de-rDE
│ │ │ └── strings.xml
│ │ ├── values-fr-rFR
│ │ │ └── strings.xml
│ │ ├── values-it-rIT
│ │ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ ├── values-ru-rRU
│ │ │ └── strings.xml
│ │ ├── values-ru
│ │ │ └── strings.xml
│ │ ├── values-zh-rCN
│ │ │ └── strings.xml
│ │ └── values
│ │ │ └── strings.xml
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── feature
│ │ └── about
│ │ ├── Di.kt
│ │ └── ui
│ │ ├── AboutAppViewModel.kt
│ │ ├── AboutScreen.kt
│ │ ├── AboutStateUi.kt
│ │ ├── AppIcon.kt
│ │ └── Mapper.kt
├── album
│ ├── favorites
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src
│ │ │ ├── androidMain
│ │ │ └── AndroidManifest.xml
│ │ │ └── commonMain
│ │ │ ├── composeResources
│ │ │ ├── values-ca-rES
│ │ │ │ └── strings.xml
│ │ │ ├── values-de-rDE
│ │ │ │ └── strings.xml
│ │ │ ├── values-fr-rFR
│ │ │ │ └── strings.xml
│ │ │ ├── values-pt-rBR
│ │ │ │ └── strings.xml
│ │ │ ├── values-ru-rRU
│ │ │ │ └── strings.xml
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── feature
│ │ │ └── album
│ │ │ └── favorites
│ │ │ ├── Di.kt
│ │ │ ├── data
│ │ │ └── FavoriteAlbumsRepositoryImpl.kt
│ │ │ ├── domain
│ │ │ ├── Album.kt
│ │ │ ├── FavoriteAlbumsRepository.kt
│ │ │ └── Favorites.kt
│ │ │ └── ui
│ │ │ ├── FavoriteAlbumsScreen.kt
│ │ │ ├── FavoriteAlbumsViewModel.kt
│ │ │ ├── Mapper.kt
│ │ │ └── State.kt
│ ├── info
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src
│ │ │ ├── androidMain
│ │ │ └── AndroidManifest.xml
│ │ │ └── commonMain
│ │ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── feature
│ │ │ └── album
│ │ │ └── info
│ │ │ ├── Di.kt
│ │ │ ├── data
│ │ │ ├── AlbumFavoriteRepositoryImpl.kt
│ │ │ └── AlbumInfoRepositoryImpl.kt
│ │ │ ├── domain
│ │ │ ├── AlbumFavoriteRepository.kt
│ │ │ ├── AlbumInfo.kt
│ │ │ ├── AlbumInfoRepository.kt
│ │ │ └── AlbumSong.kt
│ │ │ └── ui
│ │ │ ├── AlbumInfoScreen.kt
│ │ │ ├── AlbumInfoStateUi.kt
│ │ │ ├── AlbumInfoViewModel.kt
│ │ │ └── Mapper.kt
│ └── list
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src
│ │ ├── androidMain
│ │ └── AndroidManifest.xml
│ │ └── commonMain
│ │ ├── composeResources
│ │ ├── values-ca-rES
│ │ │ └── strings.xml
│ │ ├── values-de-rDE
│ │ │ └── strings.xml
│ │ ├── values-fr-rFR
│ │ │ └── strings.xml
│ │ ├── values-it-rIT
│ │ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ ├── values-ru-rRU
│ │ │ └── strings.xml
│ │ └── values
│ │ │ └── strings.xml
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── feature
│ │ └── album
│ │ └── list
│ │ ├── Di.kt
│ │ ├── data
│ │ └── AlbumsRepositoryImpl.kt
│ │ ├── domain
│ │ ├── Album.kt
│ │ └── AlbumsRepository.kt
│ │ └── ui
│ │ ├── AlbumsScreen.kt
│ │ ├── AlbumsViewModel.kt
│ │ ├── Mapper.kt
│ │ └── State.kt
├── artist
│ ├── favorites
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src
│ │ │ ├── androidMain
│ │ │ └── AndroidManifest.xml
│ │ │ └── commonMain
│ │ │ ├── composeResources
│ │ │ ├── values-ca-rES
│ │ │ │ └── strings.xml
│ │ │ ├── values-de-rDE
│ │ │ │ └── strings.xml
│ │ │ ├── values-fr-rFR
│ │ │ │ └── strings.xml
│ │ │ ├── values-pt-rBR
│ │ │ │ └── strings.xml
│ │ │ ├── values-ru-rRU
│ │ │ │ └── strings.xml
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── feature
│ │ │ └── artist
│ │ │ └── favorites
│ │ │ ├── Di.kt
│ │ │ ├── data
│ │ │ └── FavoriteArtistsRepositoryImpl.kt
│ │ │ ├── domain
│ │ │ ├── Artist.kt
│ │ │ ├── FavoriteArtistsRepository.kt
│ │ │ └── Favorites.kt
│ │ │ └── ui
│ │ │ ├── FavoriteArtistScreen.kt
│ │ │ ├── FavoriteArtistViewModel.kt
│ │ │ ├── Mapper.kt
│ │ │ └── State.kt
│ ├── info
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src
│ │ │ ├── androidMain
│ │ │ └── AndroidManifest.xml
│ │ │ └── commonMain
│ │ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── feature
│ │ │ └── artist
│ │ │ └── info
│ │ │ ├── Di.kt
│ │ │ ├── data
│ │ │ ├── ArtistFavoriteRepositoryImpl.kt
│ │ │ └── ArtistInfoRepositoryImpl.kt
│ │ │ ├── domain
│ │ │ ├── ArtistAlbum.kt
│ │ │ ├── ArtistFavoriteRepository.kt
│ │ │ ├── ArtistInfo.kt
│ │ │ └── ArtistInfoRepository.kt
│ │ │ └── ui
│ │ │ ├── ArtistInfoScreen.kt
│ │ │ ├── ArtistInfoViewModel.kt
│ │ │ ├── Mapper.kt
│ │ │ └── State.kt
│ └── list
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src
│ │ ├── androidMain
│ │ └── AndroidManifest.xml
│ │ └── commonMain
│ │ ├── composeResources
│ │ ├── values-ca-rES
│ │ │ └── strings.xml
│ │ ├── values-de-rDE
│ │ │ └── strings.xml
│ │ ├── values-fr-rFR
│ │ │ └── strings.xml
│ │ ├── values-it-rIT
│ │ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ ├── values-ru-rRU
│ │ │ └── strings.xml
│ │ └── values
│ │ │ └── strings.xml
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── feature
│ │ └── artist
│ │ └── list
│ │ ├── Di.kt
│ │ ├── data
│ │ └── ArtistsRepositoryImpl.kt
│ │ ├── domain
│ │ ├── Artist.kt
│ │ └── ArtistsRepository.kt
│ │ └── ui
│ │ ├── ArtistsScreen.kt
│ │ ├── ArtistsViewModel.kt
│ │ ├── Mapper.kt
│ │ └── State.kt
├── explore
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ └── commonMain
│ │ ├── composeResources
│ │ ├── values-ca-rES
│ │ │ └── strings.xml
│ │ ├── values-de-rDE
│ │ │ └── strings.xml
│ │ ├── values-fr-rFR
│ │ │ └── strings.xml
│ │ ├── values-it-rIT
│ │ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ ├── values-ru-rRU
│ │ │ └── strings.xml
│ │ └── values
│ │ │ └── strings.xml
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── feature
│ │ └── explore
│ │ ├── Di.kt
│ │ ├── data
│ │ └── ExploreRepositoryImpl.kt
│ │ ├── domain
│ │ ├── Explore.kt
│ │ ├── ExploreRepository.kt
│ │ └── Song.kt
│ │ └── ui
│ │ ├── ExploreScreen.kt
│ │ ├── ExploreViewModel.kt
│ │ ├── Mapper.kt
│ │ ├── State.kt
│ │ └── components
│ │ └── SearchBar.kt
├── library
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ └── commonMain
│ │ ├── composeResources
│ │ ├── values-ca-rES
│ │ │ └── strings.xml
│ │ ├── values-de-rDE
│ │ │ └── strings.xml
│ │ ├── values-fr-rFR
│ │ │ └── strings.xml
│ │ ├── values-it-rIT
│ │ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ ├── values-ru-rRU
│ │ │ └── strings.xml
│ │ └── values
│ │ │ └── strings.xml
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── feature
│ │ └── library
│ │ ├── Di.kt
│ │ ├── data
│ │ └── LibraryRepositoryImpl.kt
│ │ ├── domain
│ │ ├── Library.kt
│ │ └── LibraryRepository.kt
│ │ └── ui
│ │ ├── LibraryScreen.kt
│ │ ├── LibraryViewModel.kt
│ │ ├── Mapper.kt
│ │ └── State.kt
├── main
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ └── commonMain
│ │ ├── composeResources
│ │ ├── values-ca-rES
│ │ │ └── strings.xml
│ │ ├── values-de-rDE
│ │ │ └── strings.xml
│ │ ├── values-fr-rFR
│ │ │ └── strings.xml
│ │ ├── values-it-rIT
│ │ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ ├── values-ru-rRU
│ │ │ └── strings.xml
│ │ ├── values-zh-rCN
│ │ │ └── strings.xml
│ │ └── values
│ │ │ └── strings.xml
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── feature
│ │ └── main
│ │ ├── Di.kt
│ │ ├── data
│ │ └── ServerInfoRepositoryImpl.kt
│ │ ├── domain
│ │ ├── ServerInfo.kt
│ │ └── ServerInfoRepository.kt
│ │ └── ui
│ │ ├── MainDestination.kt
│ │ ├── MainScreen.kt
│ │ ├── MainViewModel.kt
│ │ └── Toolbar.kt
├── personal
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ └── commonMain
│ │ ├── composeResources
│ │ ├── values-ca-rES
│ │ │ └── strings.xml
│ │ ├── values-de-rDE
│ │ │ └── strings.xml
│ │ ├── values-fr-rFR
│ │ │ └── strings.xml
│ │ ├── values-it-rIT
│ │ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ ├── values-ru-rRU
│ │ │ └── strings.xml
│ │ └── values
│ │ │ └── strings.xml
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── feature
│ │ └── personal
│ │ ├── Di.kt
│ │ ├── data
│ │ └── PersonalRepositoryImpl.kt
│ │ ├── domain
│ │ ├── Album.kt
│ │ ├── Artist.kt
│ │ ├── Personal.kt
│ │ ├── PersonalRepository.kt
│ │ ├── Playlist.kt
│ │ └── Song.kt
│ │ └── ui
│ │ ├── Mapper.kt
│ │ ├── PersonalScreen.kt
│ │ ├── PersonalViewModel.kt
│ │ └── State.kt
├── player
│ ├── mini
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src
│ │ │ └── commonMain
│ │ │ ├── composeResources
│ │ │ ├── values-ca-rES
│ │ │ │ └── strings.xml
│ │ │ ├── values-de-rDE
│ │ │ │ └── strings.xml
│ │ │ ├── values-fr-rFR
│ │ │ │ └── strings.xml
│ │ │ ├── values-it-rIT
│ │ │ │ └── strings.xml
│ │ │ ├── values-pt-rBR
│ │ │ │ └── strings.xml
│ │ │ ├── values-ru-rRU
│ │ │ │ └── strings.xml
│ │ │ ├── values-zh-rCN
│ │ │ │ └── strings.xml
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── feature
│ │ │ └── player
│ │ │ └── mini
│ │ │ ├── Di.kt
│ │ │ └── ui
│ │ │ ├── MiniPlayer.kt
│ │ │ ├── MiniPlayerViewModel.kt
│ │ │ └── State.kt
│ ├── queue
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src
│ │ │ └── commonMain
│ │ │ ├── composeResources
│ │ │ ├── values-ca-rES
│ │ │ │ └── strings.xml
│ │ │ ├── values-de-rDE
│ │ │ │ └── strings.xml
│ │ │ ├── values-fr-rFR
│ │ │ │ └── strings.xml
│ │ │ ├── values-it-rIT
│ │ │ │ └── strings.xml
│ │ │ ├── values-pt-rBR
│ │ │ │ └── strings.xml
│ │ │ ├── values-ru-rRU
│ │ │ │ └── strings.xml
│ │ │ ├── values-zh-rCN
│ │ │ │ └── strings.xml
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── feature
│ │ │ └── player
│ │ │ └── queue
│ │ │ ├── Di.kt
│ │ │ └── ui
│ │ │ ├── PlayQueueSongMenu.kt
│ │ │ ├── PlayerQueueScreen.kt
│ │ │ ├── PlayerQueueViewModel.kt
│ │ │ └── State.kt
│ └── screen
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src
│ │ └── commonMain
│ │ ├── composeResources
│ │ ├── values-ca-rES
│ │ │ └── strings.xml
│ │ ├── values-de-rDE
│ │ │ └── strings.xml
│ │ ├── values-fr-rFR
│ │ │ └── strings.xml
│ │ ├── values-it-rIT
│ │ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ ├── values-ru-rRU
│ │ │ └── strings.xml
│ │ ├── values-zh-rCN
│ │ │ └── strings.xml
│ │ └── values
│ │ │ └── strings.xml
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── feature
│ │ └── player
│ │ └── screen
│ │ ├── Di.kt
│ │ └── ui
│ │ ├── Components.kt
│ │ ├── Mapper.kt
│ │ ├── PlayerScreen.kt
│ │ ├── PlayerScreenViewModel.kt
│ │ ├── RepeatModeUi.kt
│ │ ├── ShuffleModeUi.kt
│ │ └── StateUi.kt
├── playlist
│ ├── info
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src
│ │ │ └── commonMain
│ │ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── feature
│ │ │ └── playlist
│ │ │ └── info
│ │ │ ├── Di.kt
│ │ │ ├── data
│ │ │ └── PlaylistInfoRepositoryImpl.kt
│ │ │ ├── domain
│ │ │ ├── PlaylistInfo.kt
│ │ │ ├── PlaylistInfoRepository.kt
│ │ │ └── PlaylistSong.kt
│ │ │ └── ui
│ │ │ ├── Mapper.kt
│ │ │ ├── PlaylistInfoScreen.kt
│ │ │ ├── PlaylistInfoViewModel.kt
│ │ │ └── State.kt
│ └── list
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src
│ │ └── commonMain
│ │ ├── composeResources
│ │ ├── values-ca-rES
│ │ │ └── strings.xml
│ │ ├── values-de-rDE
│ │ │ └── strings.xml
│ │ ├── values-fr-rFR
│ │ │ └── strings.xml
│ │ ├── values-it-rIT
│ │ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ ├── values-ru-rRU
│ │ │ └── strings.xml
│ │ └── values
│ │ │ └── strings.xml
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── feature
│ │ └── playlist
│ │ └── list
│ │ ├── Di.kt
│ │ ├── data
│ │ └── PlaylistsRepositoryImpl.kt
│ │ ├── domain
│ │ ├── Playlist.kt
│ │ └── PlaylistsRepository.kt
│ │ └── ui
│ │ ├── Mapper.kt
│ │ ├── PlaylistsScreen.kt
│ │ ├── PlaylistsViewModel.kt
│ │ └── State.kt
├── search
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ └── commonMain
│ │ ├── composeResources
│ │ ├── values-ca-rES
│ │ │ └── strings.xml
│ │ ├── values-de-rDE
│ │ │ └── strings.xml
│ │ ├── values-fr-rFR
│ │ │ └── strings.xml
│ │ ├── values-it-rIT
│ │ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ ├── values-ru-rRU
│ │ │ └── strings.xml
│ │ ├── values-zh-rCN
│ │ │ └── strings.xml
│ │ └── values
│ │ │ └── strings.xml
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── feature
│ │ └── search
│ │ ├── Di.kt
│ │ ├── data
│ │ ├── Mapper.kt
│ │ ├── Paginator.kt
│ │ └── SearchRepositoryImpl.kt
│ │ ├── domain
│ │ ├── SearchRepository.kt
│ │ └── SearchResult.kt
│ │ └── ui
│ │ ├── Mapper.kt
│ │ ├── Search.kt
│ │ ├── SearchResultUi.kt
│ │ ├── SearchViewModel.kt
│ │ └── State.kt
├── server
│ ├── create
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src
│ │ │ └── commonMain
│ │ │ ├── composeResources
│ │ │ ├── values-ca-rES
│ │ │ │ └── strings.xml
│ │ │ ├── values-de-rDE
│ │ │ │ └── strings.xml
│ │ │ ├── values-fr-rFR
│ │ │ │ └── strings.xml
│ │ │ ├── values-it-rIT
│ │ │ │ └── strings.xml
│ │ │ ├── values-pt-rBR
│ │ │ │ └── strings.xml
│ │ │ ├── values-ru-rRU
│ │ │ │ └── strings.xml
│ │ │ ├── values-zh-rCN
│ │ │ │ └── strings.xml
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ │ └── kotlin
│ │ │ └── ru
│ │ │ └── stersh
│ │ │ └── youamp
│ │ │ └── feature
│ │ │ └── server
│ │ │ └── create
│ │ │ ├── Di.kt
│ │ │ ├── data
│ │ │ └── ServerRepositoryImpl.kt
│ │ │ ├── domain
│ │ │ ├── Server.kt
│ │ │ └── ServerRepository.kt
│ │ │ └── ui
│ │ │ ├── Mapper.kt
│ │ │ ├── ServerCreateScreen.kt
│ │ │ ├── ServerCreateStateUi.kt
│ │ │ ├── ServerCreateViewModel.kt
│ │ │ ├── ServerInputUi.kt
│ │ │ ├── ServerTestResultUi.kt
│ │ │ └── ServerUi.kt
│ └── list
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ └── src
│ │ └── commonMain
│ │ ├── composeResources
│ │ ├── values-ca-rES
│ │ │ └── strings.xml
│ │ ├── values-de-rDE
│ │ │ └── strings.xml
│ │ ├── values-fr-rFR
│ │ │ └── strings.xml
│ │ ├── values-it-rIT
│ │ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ ├── values-ru-rRU
│ │ │ └── strings.xml
│ │ ├── values-zh-rCN
│ │ │ └── strings.xml
│ │ └── values
│ │ │ └── strings.xml
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── feature
│ │ └── server
│ │ └── list
│ │ ├── Di.kt
│ │ ├── data
│ │ └── ServerListRepositoryImpl.kt
│ │ ├── domain
│ │ ├── Server.kt
│ │ └── ServerListRepository.kt
│ │ └── ui
│ │ ├── Mapper.kt
│ │ ├── ServerListScreen.kt
│ │ ├── ServerListViewModel.kt
│ │ └── State.kt
├── settings
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ └── commonMain
│ │ ├── composeResources
│ │ ├── values-ca-rES
│ │ │ └── strings.xml
│ │ ├── values-de-rDE
│ │ │ └── strings.xml
│ │ ├── values-fr-rFR
│ │ │ └── strings.xml
│ │ ├── values-it-rIT
│ │ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ ├── values-ru-rRU
│ │ │ └── strings.xml
│ │ ├── values-ru
│ │ │ └── strings.xml
│ │ ├── values-zh-rCN
│ │ │ └── strings.xml
│ │ └── values
│ │ │ └── strings.xml
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── feature
│ │ └── settings
│ │ └── ui
│ │ └── SettingsScreen.kt
└── song
│ ├── favorites
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ └── commonMain
│ │ ├── composeResources
│ │ ├── values-ca-rES
│ │ │ └── strings.xml
│ │ ├── values-de-rDE
│ │ │ └── strings.xml
│ │ ├── values-fr-rFR
│ │ │ └── strings.xml
│ │ ├── values-it-rIT
│ │ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ ├── values-ru-rRU
│ │ │ └── strings.xml
│ │ └── values
│ │ │ └── strings.xml
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── feature
│ │ └── song
│ │ └── favorites
│ │ ├── Di.kt
│ │ ├── data
│ │ └── FavoriteSongsRepositoryImpl.kt
│ │ ├── domain
│ │ ├── FavoriteSongsRepository.kt
│ │ ├── Favorites.kt
│ │ └── Song.kt
│ │ └── ui
│ │ ├── FavoriteSongsScreen.kt
│ │ ├── FavoriteSongsViewModel.kt
│ │ ├── Mapper.kt
│ │ └── State.kt
│ ├── info
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ │ └── commonMain
│ │ ├── composeResources
│ │ ├── values-ca-rES
│ │ │ └── strings.xml
│ │ ├── values-de-rDE
│ │ │ └── strings.xml
│ │ ├── values-fr-rFR
│ │ │ └── strings.xml
│ │ ├── values-it-rIT
│ │ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ ├── values-ru-rRU
│ │ │ └── strings.xml
│ │ ├── values-zh-rCN
│ │ │ └── strings.xml
│ │ └── values
│ │ │ └── strings.xml
│ │ └── kotlin
│ │ └── ru
│ │ └── stersh
│ │ └── youamp
│ │ └── feature
│ │ └── song
│ │ └── info
│ │ ├── Di.kt
│ │ └── ui
│ │ ├── SongInfoScreen.kt
│ │ ├── SongInfoViewModel.kt
│ │ └── State.kt
│ └── random
│ ├── .gitignore
│ ├── build.gradle.kts
│ └── src
│ └── commonMain
│ ├── composeResources
│ ├── values-ca-rES
│ │ └── strings.xml
│ ├── values-de-rDE
│ │ └── strings.xml
│ ├── values-fr-rFR
│ │ └── strings.xml
│ ├── values-it-rIT
│ │ └── strings.xml
│ ├── values-pt-rBR
│ │ └── strings.xml
│ ├── values-ru-rRU
│ │ └── strings.xml
│ └── values
│ │ └── strings.xml
│ └── kotlin
│ └── ru
│ └── stersh
│ └── youamp
│ └── feature
│ └── song
│ └── random
│ ├── Di.kt
│ └── ui
│ ├── Mapper.kt
│ ├── RandomSongsScreen.kt
│ ├── RandomSongsViewModel.kt
│ └── State.kt
├── gradle.properties
├── gradle
├── libs.versions.toml
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── shared
├── favorites
├── .gitignore
├── build.gradle.kts
└── src
│ ├── androidMain
│ └── AndroidManifest.xml
│ └── commonMain
│ └── kotlin
│ └── ru
│ └── stersh
│ └── youamp
│ └── shared
│ └── favorites
│ ├── Album.kt
│ ├── AlbumFavoritesStorage.kt
│ ├── Artist.kt
│ ├── ArtistFavoritesStorage.kt
│ ├── Di.kt
│ ├── Favorites.kt
│ ├── FavoritesStorageImpl.kt
│ ├── Song.kt
│ └── SongFavoritesStorage.kt
├── queue
├── .gitignore
├── build.gradle.kts
└── src
│ ├── androidMain
│ └── AndroidManifest.xml
│ └── commonMain
│ └── kotlin
│ └── ru
│ └── stersh
│ └── youamp
│ └── shared
│ └── queue
│ ├── AudioSource.kt
│ ├── Di.kt
│ ├── Mapper.kt
│ ├── PlayerQueueAudioSourceManager.kt
│ ├── PlayerQueueAudioSourceManagerImpl.kt
│ └── PlayingSource.kt
└── song
└── random
├── .gitignore
├── build.gradle.kts
└── src
├── androidMain
└── AndroidManifest.xml
└── commonMain
└── kotlin
└── ru
└── stersh
└── youamp
└── shared
└── song
└── random
├── Di.kt
├── RandomSongs.kt
├── Song.kt
├── SongRandomStorage.kt
└── SongRandomStorageImpl.kt
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "gradle"
4 | directory: "/"
5 | schedule:
6 | interval: "weekly"
7 | commit-message:
8 | prefix: chore
9 | include: scope
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /.idea/*
4 | !/.idea/icon.svg
5 | /local.properties
6 | /.idea/caches
7 | /.idea/libraries
8 | /.idea/modules.xml
9 | /.idea/workspace.xml
10 | /.idea/navEditor.xml
11 | /.idea/assetWizardSettings.xml
12 | .DS_Store
13 | /build
14 | /captures
15 | .kotlin/
16 | .externalNativeBuild
17 | .cxx
18 | local.properties
19 | google-service-key.json
20 | Gemfile.lock
--------------------------------------------------------------------------------
/.idea/deploymentTargetSelector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/migrations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
--------------------------------------------------------------------------------
/androidApp/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/androidApp/src/androidMain/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/androidApp/src/androidMain/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/androidApp/src/androidMain/kotlin/ru/stersh/youamp/EmptyActivityLifecycleCallback.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp
2 |
3 | import android.app.Activity
4 | import android.app.Application.ActivityLifecycleCallbacks
5 | import android.os.Bundle
6 |
7 | abstract class EmptyActivityLifecycleCallback : ActivityLifecycleCallbacks {
8 | override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
9 |
10 | override fun onActivityStarted(activity: Activity) {}
11 |
12 | override fun onActivityResumed(activity: Activity) {}
13 |
14 | override fun onActivityPaused(activity: Activity) {}
15 |
16 | override fun onActivityStopped(activity: Activity) {}
17 |
18 | override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
19 |
20 | override fun onActivityDestroyed(activity: Activity) {}
21 | }
--------------------------------------------------------------------------------
/androidApp/src/androidMain/kotlin/ru/stersh/youamp/audio/auto/Auto.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.audio.auto
2 |
3 | object Auto {
4 |
5 | data class Song(
6 | val id: String,
7 | val title: String,
8 | val artist: String?,
9 | val coverUrl: String?,
10 | val streamUrl: String
11 | )
12 |
13 | data class Album(
14 | val id: String,
15 | val title: String,
16 | val coverUrl: String?
17 | )
18 |
19 | data class Playlist(
20 | val id: String,
21 | val title: String,
22 | val coverUrl: String?
23 | )
24 |
25 | data class Artist(
26 | val id: String,
27 | val name: String,
28 | val coverUrl: String?
29 | )
30 | }
--------------------------------------------------------------------------------
/androidApp/src/androidMain/kotlin/ru/stersh/youamp/audio/auto/AutoRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.audio.auto
2 |
3 | interface AutoRepository {
4 | suspend fun getPlaylists(): List
5 | suspend fun getPlaylistSongs(playlistId: String): List
6 | suspend fun getSong(songId: String): Auto.Song
7 | }
--------------------------------------------------------------------------------
/androidApp/src/androidMain/kotlin/ru/stersh/youamp/audio/auto/MediaLibrary.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.audio.auto
2 |
3 | internal object MediaLibrary {
4 | const val LIBRARY_ROOT_ID = "[ROOT_ID]"
5 | const val LIBRARY_PLAYLISTS_ID = "[PLAYLISTS_ID]"
6 | const val LIBRARY_PLAYLIST_PREFIX = "playlist_"
7 |
8 | fun clearPlaylistId(id: String): String {
9 | return id.replace(LIBRARY_PLAYLIST_PREFIX, "")
10 | }
11 |
12 | fun isPlaylist(id: String): Boolean {
13 | return id.startsWith(LIBRARY_PLAYLIST_PREFIX)
14 | }
15 | }
--------------------------------------------------------------------------------
/androidApp/src/androidMain/kotlin/ru/stersh/youamp/audio/player/PlayQueueSyncActivityCallback.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.audio.player
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import androidx.lifecycle.lifecycleScope
6 | import kotlinx.coroutines.launch
7 | import ru.stersh.youamp.EmptyActivityLifecycleCallback
8 | import ru.stersh.youamp.MainActivity
9 | import ru.stersh.youamp.player.ApiSonicPlayQueueSyncer
10 |
11 | internal class PlayQueueSyncActivityCallback(
12 | private val apiSonicPlayQueueSyncer: ApiSonicPlayQueueSyncer
13 | ) : EmptyActivityLifecycleCallback() {
14 |
15 | override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
16 | if (activity !is MainActivity) {
17 | return
18 | }
19 | activity.lifecycleScope.launch {
20 | apiSonicPlayQueueSyncer.syncQueue()
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/drawable-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/androidApp/src/androidMain/res/drawable-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/drawable-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/androidApp/src/androidMain/res/drawable-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/drawable-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/androidApp/src/androidMain/res/drawable-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/drawable-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/androidApp/src/androidMain/res/drawable-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/drawable-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/androidApp/src/androidMain/res/drawable-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/drawable-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/androidApp/src/androidMain/res/drawable-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/drawable-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/androidApp/src/androidMain/res/drawable-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/drawable-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/androidApp/src/androidMain/res/drawable-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/drawable-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/androidApp/src/androidMain/res/drawable-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/drawable-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/androidApp/src/androidMain/res/drawable-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 |
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Youamp
3 |
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/xml/automotive_app_desc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/androidApp/src/androidMain/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/src/commonMain/composeResources/drawable-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/app/src/commonMain/composeResources/drawable-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/commonMain/composeResources/drawable-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/app/src/commonMain/composeResources/drawable-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/commonMain/composeResources/drawable-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/app/src/commonMain/composeResources/drawable-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/commonMain/composeResources/drawable-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/app/src/commonMain/composeResources/drawable-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/commonMain/composeResources/drawable-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/app/src/commonMain/composeResources/drawable-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/commonMain/composeResources/drawable-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/app/src/commonMain/composeResources/drawable-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/commonMain/composeResources/drawable-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/app/src/commonMain/composeResources/drawable-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/commonMain/composeResources/drawable-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/app/src/commonMain/composeResources/drawable-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/commonMain/composeResources/drawable-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/app/src/commonMain/composeResources/drawable-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/commonMain/composeResources/drawable-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/app/src/commonMain/composeResources/drawable-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/commonMain/kotlin/ru/stersh/youamp/app/data/AvatarUrlRepositoryImpl.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.app.data
2 |
3 | import kotlinx.coroutines.flow.Flow
4 | import kotlinx.coroutines.flow.map
5 | import ru.stersh.youamp.core.api.ApiProvider
6 | import ru.stersh.youamp.app.domain.AvatarUrlRepository
7 |
8 | internal class AvatarUrlRepositoryImpl(
9 | private val apiProvider: ApiProvider
10 | ) : AvatarUrlRepository {
11 | override fun getAvatarUrl(): Flow {
12 | return apiProvider
13 | .flowApiOrNull()
14 | .map { it?.avatarUrl(it.username) }
15 | }
16 | }
--------------------------------------------------------------------------------
/app/src/commonMain/kotlin/ru/stersh/youamp/app/data/ServerExistRepositoryImpl.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.app.data
2 |
3 | import kotlinx.coroutines.flow.Flow
4 | import kotlinx.coroutines.flow.map
5 | import ru.stersh.youamp.core.db.server.SubsonicServerDao
6 | import ru.stersh.youamp.app.domain.ServerExistRepository
7 |
8 | internal class ServerExistRepositoryImpl(private val serverDao: SubsonicServerDao) : ServerExistRepository {
9 |
10 | override suspend fun hasServer(): Flow {
11 | return serverDao
12 | .flowActive()
13 | .map { it != null }
14 | }
15 | }
--------------------------------------------------------------------------------
/app/src/commonMain/kotlin/ru/stersh/youamp/app/domain/AvatarUrlRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.app.domain
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | internal interface AvatarUrlRepository {
6 | fun getAvatarUrl(): Flow
7 | }
--------------------------------------------------------------------------------
/app/src/commonMain/kotlin/ru/stersh/youamp/app/domain/ServerExistRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.app.domain
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | internal interface ServerExistRepository {
6 | suspend fun hasServer(): Flow
7 | }
--------------------------------------------------------------------------------
/app/src/commonMain/kotlin/ru/stersh/youamp/app/ui/MainScreen.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.app.ui
2 |
3 | enum class MainScreen { Main, Progress, AddServer }
--------------------------------------------------------------------------------
/app/src/commonMain/kotlin/ru/stersh/youamp/app/ui/StateUi.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.app.ui
2 |
3 | data class StateUi(
4 | val screen: MainScreen = MainScreen.Progress,
5 | val avatarUrl: String? = null
6 | )
--------------------------------------------------------------------------------
/assets/bage/get_it_on_github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/assets/bage/get_it_on_github.png
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.android.application) apply false
3 | alias(libs.plugins.android.library) apply false
4 | alias(libs.plugins.kotlin.android) apply false
5 | alias(libs.plugins.kotlin.serialization) apply false
6 | alias(libs.plugins.kotlin.composeCompiler) apply false
7 | alias(libs.plugins.ksp) apply false
8 | alias(libs.plugins.kotlin.multiplatform) apply false
9 | alias(libs.plugins.android.kotlinMultiplatformLibrary) apply false
10 | }
11 |
12 | tasks.register("clean", Delete::class) {
13 | delete(rootProject.buildDir)
14 | }
--------------------------------------------------------------------------------
/buildSrc/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/buildSrc/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | `kotlin-dsl`
3 | }
4 |
5 | repositories {
6 | google()
7 | mavenCentral()
8 | }
9 |
10 | group = "ru.stersh.youamp.buildSrc"
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/ru/stersh/youamp/AppBuildInfo.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp
2 |
3 | object AppBuildInfo {
4 |
5 | const val VERSION_NAME = "2.0.0-beta09"
6 | const val VERSION_CODE = 26
7 | const val PACKAGE_NAME = "ru.stersh.youamp"
8 |
9 | val CLEAR_VERSION_NAME = clearVersionName()
10 |
11 | private fun clearVersionName(): String {
12 | val index = VERSION_NAME.indexOf('-')
13 | return if (index == -1) {
14 | VERSION_NAME
15 | } else {
16 | VERSION_NAME.substring(0, index)
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/core/api/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/core/api/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.kotlin.multiplatform)
3 | alias(libs.plugins.android.kotlinMultiplatformLibrary)
4 | }
5 |
6 | kotlin {
7 | androidLibrary {
8 | namespace = "ru.stresh.youamp.core.api"
9 | compileSdk = libs.versions.android.compileSdk.get().toInt()
10 | minSdk = libs.versions.android.minSdk.get().toInt()
11 | }
12 |
13 | jvm("desktop")
14 |
15 | sourceSets {
16 | commonMain {
17 | dependencies {
18 | api(libs.subsonicApi)
19 | implementation(libs.kotlin.coroutines.core)
20 | }
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/core/api/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/core/api/src/commonMain/kotlin/ru/stersh/youamp/core/api/ApiDefaults.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.api
2 |
3 | object ApiDefaults {
4 | const val API_VERSION = "1.15.0"
5 | const val CLIENT_ID = "Youamp"
6 | }
--------------------------------------------------------------------------------
/core/api/src/commonMain/kotlin/ru/stersh/youamp/core/api/ApiProvider.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.api
2 |
3 | import kotlinx.coroutines.flow.Flow
4 | import ru.stersh.subsonic.api.SubsonicApi
5 |
6 | interface ApiProvider {
7 |
8 | suspend fun getApi(): SubsonicApi
9 |
10 | suspend fun getApiId(): Long?
11 |
12 | suspend fun requireApiId(): Long
13 |
14 | suspend fun getApi(id: Long): SubsonicApi?
15 |
16 | suspend fun requireApi(id: Long): SubsonicApi
17 |
18 | fun flowApi(): Flow
19 |
20 | fun flowApiOrNull(): Flow
21 |
22 | fun flowApiId(): Flow
23 | }
24 |
--------------------------------------------------------------------------------
/core/api/src/commonMain/kotlin/ru/stersh/youamp/core/api/NoActiveServerSettingsFound.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.api
2 |
3 | class NoActiveServerSettingsFound : Exception()
4 |
--------------------------------------------------------------------------------
/core/db/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/core/db/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/core/db/src/androidMain/kotlin/ru/stersh/youamp/core/db/Database.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.db
2 |
3 | import android.content.Context
4 | import androidx.room.Room
5 | import androidx.room.RoomDatabase
6 |
7 | fun getDatabaseBuilder(ctx: Context): RoomDatabase.Builder {
8 | val appContext = ctx.applicationContext
9 | val dbFile = appContext.getDatabasePath("app.db")
10 | return Room.databaseBuilder(
11 | context = appContext,
12 | name = dbFile.absolutePath
13 | )
14 | }
--------------------------------------------------------------------------------
/core/db/src/commonMain/kotlin/ru/stersh/youamp/core/db/AppDatabase.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.db
2 |
3 | import androidx.room.ConstructedBy
4 | import androidx.room.Database
5 | import androidx.room.RoomDatabase
6 | import androidx.room.RoomDatabaseConstructor
7 | import ru.stersh.youamp.core.db.server.SubsonicServerDao
8 | import ru.stersh.youamp.core.db.server.SubsonicServerDb
9 |
10 | @Database(
11 | entities = [SubsonicServerDb::class],
12 | version = 1,
13 | exportSchema = false,
14 | )
15 | @ConstructedBy(AppDatabaseConstructor::class)
16 | abstract class AppDatabase : RoomDatabase() {
17 |
18 | abstract fun subsonicServerDao(): SubsonicServerDao
19 | }
20 |
21 | @Suppress("NO_ACTUAL_FOR_EXPECT")
22 | expect object AppDatabaseConstructor : RoomDatabaseConstructor {
23 | override fun initialize(): AppDatabase
24 | }
--------------------------------------------------------------------------------
/core/db/src/commonMain/kotlin/ru/stersh/youamp/core/db/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.db
2 |
3 | import androidx.room.RoomDatabase
4 | import androidx.sqlite.driver.bundled.BundledSQLiteDriver
5 | import kotlinx.coroutines.Dispatchers
6 | import kotlinx.coroutines.IO
7 | import org.koin.dsl.module
8 |
9 | val dbModule = module {
10 | single {
11 | get>()
12 | .fallbackToDestructiveMigrationOnDowngrade(dropAllTables = true)
13 | .setQueryCoroutineContext(Dispatchers.IO)
14 | .setDriver(BundledSQLiteDriver())
15 | .build()
16 | }
17 |
18 | single {
19 | get().subsonicServerDao()
20 | }
21 | }
--------------------------------------------------------------------------------
/core/db/src/commonMain/kotlin/ru/stersh/youamp/core/db/server/SubsonicServerDb.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.db.server
2 |
3 | import androidx.room.Entity
4 | import androidx.room.PrimaryKey
5 |
6 | @Entity(tableName = "server_subsonic")
7 | data class SubsonicServerDb(
8 | @PrimaryKey(autoGenerate = true)
9 | val id: Long = 0,
10 | val url: String,
11 | val name: String,
12 | val username: String,
13 | val password: String,
14 | val isActive: Boolean,
15 | val useLegacyAuth: Boolean
16 | )
--------------------------------------------------------------------------------
/core/db/src/desktopMain/kotlin/ru/stersh/youamp/core/db/Database.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.db
2 |
3 | import androidx.room.Room
4 | import androidx.room.RoomDatabase
5 | import java.io.File
6 |
7 | fun getDatabaseBuilder(): RoomDatabase.Builder {
8 | val dbFile = File(System.getProperty("java.io.tmpdir"), "app.db")
9 | return Room.databaseBuilder(
10 | name = dbFile.absolutePath,
11 | )
12 | }
--------------------------------------------------------------------------------
/core/player/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/core/player/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/core/player/src/androidMain/kotlin/ru/stersh/youamp/core/player/PlayerConcurrency.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.player
2 |
3 | import android.os.Handler
4 | import android.os.HandlerThread
5 | import kotlinx.coroutines.CoroutineScope
6 | import kotlinx.coroutines.SupervisorJob
7 | import kotlinx.coroutines.android.asCoroutineDispatcher
8 |
9 | val PlayerThread = HandlerThread("PlayerThread").apply { start() }
10 | val PlayerHandler = Handler(PlayerThread.looper)
11 | val PlayerDispatcher = PlayerHandler.asCoroutineDispatcher("PlayerDispatcher")
12 | val PlayerScope = CoroutineScope(SupervisorJob() + PlayerDispatcher)
--------------------------------------------------------------------------------
/core/player/src/commonMain/kotlin/ru/stersh/youamp/core/player/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.player
2 |
3 | import org.koin.core.module.Module
4 |
5 | expect val playerCoreModule: Module
--------------------------------------------------------------------------------
/core/player/src/commonMain/kotlin/ru/stersh/youamp/core/player/MediaItem.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.player
2 |
3 | data class MediaItem(
4 | val id: String,
5 | val title: String,
6 | val url: String,
7 | val artist: String? = null,
8 | val album: String? = null,
9 | val artworkUrl: String? = null
10 | )
11 |
--------------------------------------------------------------------------------
/core/player/src/commonMain/kotlin/ru/stersh/youamp/core/player/PlayerProgress.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.player
2 |
3 | data class PlayerProgress(
4 | val currentTimeMs: Long,
5 | val totalTimeMs: Long,
6 | val currentTime: String,
7 | val totalTime: String,
8 | ) {
9 | val progressPercent: Float = currentTimeMs.toFloat() / totalTimeMs
10 | }
11 |
--------------------------------------------------------------------------------
/core/player/src/commonMain/kotlin/ru/stersh/youamp/core/player/RepeatMode.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.player
2 |
3 | enum class RepeatMode { One, All, Disabled }
--------------------------------------------------------------------------------
/core/player/src/commonMain/kotlin/ru/stersh/youamp/core/player/ShuffleMode.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.player
2 |
3 | enum class ShuffleMode { Enabled, Disabled }
--------------------------------------------------------------------------------
/core/player/src/desktopMain/kotlin/ru/stersh/youamp/core/player/Di.desktop.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.player
2 |
3 | import org.koin.core.module.Module
4 | import org.koin.dsl.module
5 |
6 | actual val playerCoreModule: Module = module {
7 | single { DesktopPlayer() }
8 | }
--------------------------------------------------------------------------------
/core/properties/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/core/properties/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.kotlin.multiplatform)
3 | alias(libs.plugins.android.kotlinMultiplatformLibrary)
4 | }
5 |
6 | kotlin {
7 |
8 | androidLibrary {
9 | namespace = "ru.stresh.youamp.core.properties"
10 | compileSdk = libs.versions.android.compileSdk
11 | .get()
12 | .toInt()
13 | minSdk = libs.versions.android.minSdk
14 | .get()
15 | .toInt()
16 | }
17 |
18 | jvm("desktop")
19 |
20 | sourceSets {
21 | commonMain {
22 | dependencies {
23 | implementation(libs.koin.core)
24 | implementation(libs.kotlin.coroutines.core)
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/core/properties/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/core/properties/src/commonMain/kotlin/ru/stersh/youamp/core/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core
2 |
3 | import org.koin.dsl.module
4 | import ru.stersh.youamp.core.properties.app.AppPropertiesStorage
5 | import ru.stersh.youamp.core.properties.app.AppPropertiesStorageImpl
6 |
7 | val propertiesModule = module {
8 | single { AppPropertiesStorageImpl(get()) }
9 | }
--------------------------------------------------------------------------------
/core/properties/src/commonMain/kotlin/ru/stersh/youamp/core/properties/app/AppProperties.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.properties.app
2 |
3 | data class AppProperties(
4 | val name: String,
5 | val version: String,
6 | val githubUrl: String,
7 | val fdroidUrl: String,
8 | val crwodinUrl: String
9 | )
10 |
--------------------------------------------------------------------------------
/core/properties/src/commonMain/kotlin/ru/stersh/youamp/core/properties/app/AppPropertiesStorage.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.properties.app
2 |
3 | interface AppPropertiesStorage {
4 | fun getAppProperties(): AppProperties
5 | }
--------------------------------------------------------------------------------
/core/properties/src/commonMain/kotlin/ru/stersh/youamp/core/properties/app/AppPropertiesStorageImpl.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.properties.app
2 |
3 | internal class AppPropertiesStorageImpl(
4 | private val appProperties: AppProperties
5 | ) : AppPropertiesStorage {
6 |
7 | override fun getAppProperties(): AppProperties {
8 | return appProperties
9 | }
10 | }
--------------------------------------------------------------------------------
/core/ui/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/core/ui/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/core/ui/src/commonMain/composeResources/font/montserrat_bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/core/ui/src/commonMain/composeResources/font/montserrat_bold.ttf
--------------------------------------------------------------------------------
/core/ui/src/commonMain/composeResources/font/montserrat_italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/core/ui/src/commonMain/composeResources/font/montserrat_italic.ttf
--------------------------------------------------------------------------------
/core/ui/src/commonMain/composeResources/font/montserrat_light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/core/ui/src/commonMain/composeResources/font/montserrat_light.ttf
--------------------------------------------------------------------------------
/core/ui/src/commonMain/composeResources/font/montserrat_medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/core/ui/src/commonMain/composeResources/font/montserrat_medium.ttf
--------------------------------------------------------------------------------
/core/ui/src/commonMain/composeResources/font/montserrat_regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/core/ui/src/commonMain/composeResources/font/montserrat_regular.ttf
--------------------------------------------------------------------------------
/core/ui/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Torna enrere
4 | Aleatori
5 | Reprodueix-ho tot
6 | Imatge del marcador de posició
7 | Torna a provar
8 | Torneu a provar. Si l\'errada persisteix, contacteu amb el desenvolupador.
9 | Aix, alguna cosa no ha anat bé
10 | No hi ha res aquí encara…
11 | Avatar de l\'usuari
12 | No m\'agrada
13 | M\'agrada
14 |
15 |
--------------------------------------------------------------------------------
/core/ui/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Zurück
4 | Mischen
5 | Alle abspielen
6 | Platzhalter-Bild
7 | Erneut versuchen
8 | Versuchen Sie es erneut. Wenn der Fehler mehrmals auftritt, wenden Sie sich an den Entwickler.
9 | Hoppla, etwas ist schief gelaufen
10 | Hier gibt es noch nichts…
11 | Benutzer Avatar
12 | Gefällt mir nicht
13 | Gefällt mir
14 |
15 |
--------------------------------------------------------------------------------
/core/ui/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Revenir en arrière
4 | Aléatoire
5 | Tout lire
6 | Image de substitution
7 | Réessayer
8 | Réessayez. Si l’erreur se produit plusieurs fois, contactez le développeur.
9 | Oups, une erreur est arrivée
10 | Il n’y a rien encore ici…
11 | Avatar de l’utilisateur
12 | Je n’aime pas
13 | J’aime
14 |
15 |
--------------------------------------------------------------------------------
/core/ui/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Torna indietro
4 | Riproduzione casuale
5 | Riproduci tutto
6 | Immagine temporanea
7 | Riprova
8 | Riprova. Se l\'errore si verifica più volte, contatta lo sviluppatore.
9 | Oops, qualcosa è andato storto
10 | Ancora nulla da vedere qua…
11 | Avatar utente
12 | Non mi piace
13 | Mi Piace
14 |
15 |
--------------------------------------------------------------------------------
/core/ui/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Navegar de volta
4 | Embaralhar
5 | Tocar tudo
6 | Placeholder da imagem
7 | Tentar novamente
8 | Tente novamente. Se o erro ocorrer diversas vezes, entre em contato com os desenvolvedores.
9 | Epa, algo deu errado
10 | Ainda não há nada aqui…
11 | Avatar de usuário
12 | Deslike
13 | Like
14 |
15 |
--------------------------------------------------------------------------------
/core/ui/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Назад
4 | Перемешать
5 | Играть все
6 | Плейсхолдер
7 | Попробовать снова
8 | Попробуйте снова. Если ошибка повторится, свяжитесь с разработчиком.
9 | Ой, что-то пошло не так
10 | Здесь пока ничего нет…
11 | Аватар пользователя
12 | Дизлайк
13 | Лайк
14 |
15 |
--------------------------------------------------------------------------------
/core/ui/src/commonMain/composeResources/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 返回
4 | 随机播放
5 | 播放全部
6 | 占位图片
7 | 重试
8 | 请重试。如果该错误多次发生,请联系开发人员。
9 | 哦豁,出错了
10 | 这里什么都还没有……
11 |
12 |
--------------------------------------------------------------------------------
/core/ui/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Navigate back
4 | Shuffle
5 | Play all
6 | Placeholder image
7 | Try again
8 | Try again. If the error occurs several times, contact the developer.
9 | Oops, something went wrong
10 | There\'s nothing here yet…
11 | User avatar
12 | Dislike
13 | Like
14 |
--------------------------------------------------------------------------------
/core/ui/src/commonMain/kotlin/ru/stersh/youamp/core/ui/Color.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.ui
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | val Purple80 = Color(0xFFD0BCFF)
6 | val PurpleGrey80 = Color(0xFFCCC2DC)
7 | val Pink80 = Color(0xFFEFB8C8)
8 |
9 | val Purple40 = Color(0xFF6650a4)
10 | val PurpleGrey40 = Color(0xFF625b71)
11 | val Pink40 = Color(0xFF7D5260)
12 |
13 | val ArtworkMaskColor = Color(0x73000000)
--------------------------------------------------------------------------------
/core/ui/src/commonMain/kotlin/ru/stersh/youamp/core/ui/Dp.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.ui
2 |
3 | import androidx.compose.ui.unit.Density
4 | import androidx.compose.ui.unit.Dp
5 |
6 |
7 | fun Float.toDp(density: Density): Dp {
8 | return with(density) { toDp() }
9 | }
10 |
11 | fun Int.toDp(density: Density): Dp {
12 | return with(density) { toDp() }
13 | }
14 |
15 | fun Dp.toPx(density: Density): Float {
16 | return with(density) { toPx() }
17 | }
18 |
19 | fun Dp.roundToPx(density: Density): Int {
20 | return with(density) { roundToPx() }
21 | }
--------------------------------------------------------------------------------
/core/ui/src/commonMain/kotlin/ru/stersh/youamp/core/ui/MovePosition.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.ui
2 |
3 | import androidx.compose.runtime.Immutable
4 | import androidx.compose.ui.util.packInts
5 | import androidx.compose.ui.util.unpackInt1
6 | import androidx.compose.ui.util.unpackInt2
7 |
8 | @Immutable
9 | @JvmInline
10 | value class MovePosition internal constructor(private val packedValue: Long) {
11 |
12 | val from: Int
13 | get() = unpackInt1(packedValue)
14 |
15 | val to: Int
16 | get() = unpackInt2(packedValue)
17 | }
18 |
19 | fun MovePosition(from: Int, to: Int) = MovePosition(packInts(from, to))
--------------------------------------------------------------------------------
/core/ui/src/commonMain/kotlin/ru/stersh/youamp/core/ui/Text.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.ui
2 |
3 | import androidx.compose.material3.LocalTextStyle
4 | import androidx.compose.material3.Text
5 | import androidx.compose.runtime.Composable
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.graphics.Color
8 | import androidx.compose.ui.text.TextStyle
9 | import androidx.compose.ui.text.style.TextOverflow
10 |
11 | @Composable
12 | fun SingleLineText(
13 | text: String,
14 | modifier: Modifier = Modifier,
15 | color: Color = Color.Unspecified,
16 | style: TextStyle = LocalTextStyle.current
17 | ) {
18 | Text(
19 | text = text,
20 | modifier = modifier,
21 | color = color,
22 | style = style,
23 | minLines = 1,
24 | maxLines = 1,
25 | overflow = TextOverflow.Ellipsis
26 | )
27 | }
--------------------------------------------------------------------------------
/core/ui/src/desktopMain/kotlin/ru/stersh/youamp/core/ui/Theme.desktop.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.ui
2 |
3 | import androidx.compose.material3.ColorScheme
4 | import androidx.compose.runtime.Composable
5 |
6 | @Composable
7 | actual fun getColorScheme(
8 | darkTheme: Boolean,
9 | dynamicColor: Boolean
10 | ): ColorScheme {
11 | return if (darkTheme) {
12 | DarkColorScheme
13 | } else {
14 | LightColorScheme
15 | }
16 | }
--------------------------------------------------------------------------------
/core/utils/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/core/utils/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.kotlin.multiplatform)
3 | alias(libs.plugins.android.kotlinMultiplatformLibrary)
4 | }
5 |
6 | kotlin {
7 |
8 | androidLibrary {
9 | namespace = "ru.stresh.youamp.core.utils"
10 | compileSdk = libs.versions.android.compileSdk
11 | .get()
12 | .toInt()
13 | minSdk = libs.versions.android.minSdk
14 | .get()
15 | .toInt()
16 | }
17 |
18 | jvm("desktop")
19 |
20 | sourceSets {
21 | commonMain {
22 | dependencies {
23 | implementation(libs.kotlin.coroutines.core)
24 | implementation(libs.kotlinx.datetime)
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/core/utils/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/core/utils/src/commonMain/kotlin/ru/stersh/youamp/core/utils/Flow.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.utils
2 |
3 | import kotlinx.coroutines.flow.Flow
4 | import kotlinx.coroutines.flow.map
5 |
6 | inline fun , T, R> Flow.mapItems(crossinline block: (item: T) -> R): Flow> {
7 | return map { collection ->
8 | collection.map { block(it) }
9 | }
10 | }
--------------------------------------------------------------------------------
/core/utils/src/commonMain/kotlin/ru/stersh/youamp/core/utils/List.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.utils
2 |
3 | fun List.swap(from: Int, to: Int): List {
4 | val mutable = toMutableList()
5 | val item = mutable.removeAt(from)
6 | mutable.add(to, item)
7 | return mutable.toList()
8 | }
--------------------------------------------------------------------------------
/core/utils/src/commonMain/kotlin/ru/stersh/youamp/core/utils/Time.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.core.utils
2 |
3 | import kotlinx.datetime.LocalTime
4 | import kotlinx.datetime.format.char
5 |
6 | private const val ONE_HOUR_MS = 3600000L
7 |
8 | private val hourTimeFormat = LocalTime.Format {
9 | hour()
10 | char(':')
11 | minute()
12 | char(':')
13 | second()
14 | }
15 |
16 | private val minuteTimeFormat = LocalTime.Format {
17 | minute()
18 | char(':')
19 | second()
20 | }
21 |
22 | fun formatSongDuration(time: Long): String {
23 | val dateTime = LocalTime.fromMillisecondOfDay(time.toInt())
24 | return if (time >= ONE_HOUR_MS) {
25 | hourTimeFormat.format(dateTime)
26 | } else {
27 | minuteTimeFormat.format(dateTime)
28 | }
29 | }
30 |
31 | fun formatSongDuration(time: Int): String {
32 | return formatSongDuration(time.toLong())
33 | }
--------------------------------------------------------------------------------
/desktopApp/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/desktopApp/src/commonMain/composeResources/drawable-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/desktopApp/src/commonMain/composeResources/drawable-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/desktopApp/src/commonMain/composeResources/drawable-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/desktopApp/src/commonMain/composeResources/drawable-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/desktopApp/src/commonMain/composeResources/drawable-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/desktopApp/src/commonMain/composeResources/drawable-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/desktopApp/src/commonMain/composeResources/drawable-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/desktopApp/src/commonMain/composeResources/drawable-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/desktopApp/src/commonMain/composeResources/drawable-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/desktopApp/src/commonMain/composeResources/drawable-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/desktopApp/src/commonMain/composeResources/drawable-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/desktopApp/src/commonMain/composeResources/drawable-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/desktopApp/src/commonMain/composeResources/drawable-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/desktopApp/src/commonMain/composeResources/drawable-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/desktopApp/src/commonMain/composeResources/drawable-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/desktopApp/src/commonMain/composeResources/drawable-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/desktopApp/src/commonMain/composeResources/drawable-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/desktopApp/src/commonMain/composeResources/drawable-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/desktopApp/src/commonMain/composeResources/drawable-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/desktopApp/src/commonMain/composeResources/drawable-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/desktopApp/src/desktopMain/kotlin/ru/stersh/youamp/DesktopDi.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp
2 |
3 | import androidx.room.RoomDatabase
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.core.db.AppDatabase
6 | import ru.stersh.youamp.core.db.getDatabaseBuilder
7 | import ru.stersh.youamp.core.properties.app.AppProperties
8 |
9 | val desktopModule = module {
10 | single {
11 | AppProperties(
12 | name = "Youamp",
13 | version = "2.0.0-beta06",
14 | githubUrl = "https://github.com/siper/Youamp",
15 | fdroidUrl = "https://f-droid.org/packages/ru.stersh.youamp/",
16 | crwodinUrl = "https://crowdin.com/project/youamp"
17 | )
18 | }
19 | single> { getDatabaseBuilder() }
20 | }
--------------------------------------------------------------------------------
/fastlane/metadata/android/ca/full_description.txt:
--------------------------------------------------------------------------------
1 | Youamp és un reproductor de música per a servidors Subsonic que té una interfície moderna Material You i un nivell alt de privacitat, gràcies a l'absència de
2 | rastrejadors, anuncis i analítiques. El codi font és obert, de forma que qualsevol persona pot millorar Youamp.
3 |
4 | Aquestes són les característiques actualment disponibles:
5 | • Veure una llista d'artistes, àlbums i llistes de reproducció
6 | • Cercar artistes, àlbums i cançons
7 | • Reproduir música
8 | • Afegir una quantitat il·limitada de servidors Subsonic
--------------------------------------------------------------------------------
/fastlane/metadata/android/ca/short_description.txt:
--------------------------------------------------------------------------------
1 | Reproductor de música per a servidors Subsonic amb interfície Material You
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/full_description.txt:
--------------------------------------------------------------------------------
1 | Youamp ist ein Musikplayer für Subsonic-Server mit einer modernen Material You Oberfläche und einem hohen Maß an Privatsphäre, die durch den Verzicht auf Tracker, Werbung und Analytics gewährleistet ist. Der Quellcode ist offen, so dass jeder Youamp verbessern kann.
2 |
3 | Die folgenden Funktionen werden derzeit unterstützt:
4 | • Liste der Interpreten, Alben und Wiedergabelisten anzeigen
5 | • Suche nach Interpreten, Alben und Liedern
6 | • Musik abspielen
7 | • Unbegrenzte Anzahl von Subsonic-Servern hinzufügen
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/short_description.txt:
--------------------------------------------------------------------------------
1 | Musikplayer für Subsonic-Server mit moderner Material You Oberfläche
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/full_description.txt:
--------------------------------------------------------------------------------
1 | Youamp is a music player for Subsonic servers with a modern Material You interface and a high level of privacy, which is ensured by the absence of trackers, advertising and analytics. The source code is open, so anyone can make Youamp better.
2 |
3 | The following functionality is currently supported:
4 | • View a list of artists, albums and playlists
5 | • Search for artists, albums and songs
6 | • Play music
7 | • Add an unlimited number of Subsonic servers
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/featureGraphic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/fastlane/metadata/android/en-US/images/featureGraphic.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/fastlane/metadata/android/en-US/images/icon.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/fastlane/metadata/android/en-US/images/phoneScreenshots/7.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/fastlane/metadata/android/en-US/images/phoneScreenshots/8.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/short_description.txt:
--------------------------------------------------------------------------------
1 | Music player for Subsonic servers with modern Material You interface
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/title.txt:
--------------------------------------------------------------------------------
1 | Youamp
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/video.txt:
--------------------------------------------------------------------------------
1 | https://youtu.be/aoNijgbqvko
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/full_description.txt:
--------------------------------------------------------------------------------
1 | Youamp est un lecteur de musique pour les serveurs Subsonic avec une interface Material You moderne et un haut niveau de confidentialité, qui est assurée par l’absence de trackers, de publicité et d’analyse. Le code source est ouvert, donc tout le monde peut améliorer Youamp.
2 |
3 | Les fonctionnalités suivantes sont actuellement prises en charge :
4 | • Voir la liste des artistes, albums et listes de lecture
5 | • Recherche d’artistes, d’albums et de chansons
6 | • Lire de la musique
7 | • Ajouter un nombre illimité de serveurs Subsonic
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/short_description.txt:
--------------------------------------------------------------------------------
1 | Lecteur de musique pour serveurs Subsonic avec interface Material You
--------------------------------------------------------------------------------
/fastlane/metadata/android/it-IT/full_description.txt:
--------------------------------------------------------------------------------
1 | Youamp è un lettore musicale per server Subsonic con un interfaccia moderna usando Material You e un alto livello di privacy, con un'assenza di tracker, pubblicità e analytics garantita. Il codice è open source, quindi chiunque può contribuire a rendere youamp migliore.
2 |
3 | Le seguenti funzionalità sono attualmente supportate:
4 | • Lista di artisti, album e playlist
5 | • Cerca per artisti, album e canzoni
6 | • Ascoltare alla musica
7 | • Aggiungere illimitati server Subsonic
--------------------------------------------------------------------------------
/fastlane/metadata/android/it-IT/short_description.txt:
--------------------------------------------------------------------------------
1 | Lettore musicale per server Subsonic con una moderna interfaccia Material You
--------------------------------------------------------------------------------
/fastlane/metadata/android/pt-BR/full_description.txt:
--------------------------------------------------------------------------------
1 | Youamp é um reprodutor de músicas para servidores Subsônicos, com uma interface moderna do Material You e um alto nível de privacidade, que é garantido pela falta de rastreadores, publicidade e análise. O código fonte é open-source, então qualquer pessoa pode melhorar o Youamp.
2 |
3 | A seguinte funcionalidade é suportada no momento:
4 | • Veja uma lista de artistas, álbuns e playlists
5 | • Procurar por artistas, álbuns e músicas
6 | • Reproduzir música
7 | • Adicione um número ilimitado de servidores subsônicos
--------------------------------------------------------------------------------
/fastlane/metadata/android/pt-BR/short_description.txt:
--------------------------------------------------------------------------------
1 | Reprodutor de música para servidores Subsônicos e “interface” do Material You
--------------------------------------------------------------------------------
/fastlane/metadata/android/ru-RU/full_description.txt:
--------------------------------------------------------------------------------
1 | Youamp — музыкальный плеер для серверов Subsonic с современным интерфейсом Material You и высоким уровнем конфиденциальности, который обеспечивается отсутствием трекеров, рекламы и аналитики. Исходный код открыт, поэтому любой желающий может сделать Youamp лучше.
2 |
3 | В настоящее время поддерживается следующий функционал:
4 | • Просмотр списка исполнителей, альбомов и плейлистов
5 | • Поиск исполнителей, альбомов и песен
6 | • Воспроизведение музыки
7 | • Добавление неограниченного количества серверов Subsonic
--------------------------------------------------------------------------------
/fastlane/metadata/android/ru-RU/short_description.txt:
--------------------------------------------------------------------------------
1 | Музыкальный плеер для серверов Subsonic с современным интерфейсом Material You
--------------------------------------------------------------------------------
/fastlane/metadata/android/zh-CN/full_description.txt:
--------------------------------------------------------------------------------
1 | Youamp 是一个适配 Subsonic 服务器的音乐播放器,具备现代 Material You 界面,高度保护隐私,不包含追踪器、广告和分析器。 此为开源项目,任何人都能参与改进 Youamp。 此为开源项目,任何人都能参与改进 Youamp。 此为开源项目,任何人都能参与改进 Youamp。
2 |
3 | 目前支持下列功能:
4 | • 查看艺人、专辑和歌单列表
5 | • 搜索艺人、专辑和歌曲
6 | • 播放音乐
7 | • 添加无限数量的 Subsonic 服务器
--------------------------------------------------------------------------------
/fastlane/metadata/android/zh-CN/short_description.txt:
--------------------------------------------------------------------------------
1 | 适用于 Subsonic 服务器的音乐播放器,具备现代 Material You 界面
--------------------------------------------------------------------------------
/feature/about/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/about/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/feature/about/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Icona de GitHub
4 | Valorar o enviar un informe d\'errada
5 | Icona de F-Droid
6 | Comprova actualitzacions
7 | Icona de Crowdin
8 | Ajudeu a traduir
9 | Quant a…
10 | Icona de l\'aplicació
11 |
12 |
--------------------------------------------------------------------------------
/feature/about/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | GitHub icon
4 | Stern oder Problem melden
5 | F-Droid Icon
6 | Nach Updates suchen
7 | Crowdin Icon
8 | Hilf bei der Übersetzung
9 | Über
10 | App Symbol
11 |
12 |
--------------------------------------------------------------------------------
/feature/about/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Icône GitHub
4 | Mettre en favori ou soumettre un ticket
5 | Icône F-Droid
6 | Vérifier les mises à jour
7 | Icône Crowdin
8 | Aide à traduire
9 | A propos
10 | Icône de l’application
11 |
12 |
--------------------------------------------------------------------------------
/feature/about/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Icona di GitHub
4 | Stella o segnala un problema
5 | Icona di F-Droid
6 | Controlla aggiornamenti
7 | Icona di Crowdin
8 | Aiuta a tradurre
9 | Info
10 | Icona dell\'App
11 |
12 |
--------------------------------------------------------------------------------
/feature/about/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Ícone do GitHub
4 | Favorite ou envie issue
5 | Ícone do F-Droid
6 | Verificar atualizações
7 | Ícone do Crowdin
8 | Ajude a traduzir
9 | Sobre
10 | Ícone do aplicativo
11 |
12 |
--------------------------------------------------------------------------------
/feature/about/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Иконка GitHub
4 | Поставить звездочку или задать вопрос
5 | Иконка F-Droid
6 | Проверить обновления
7 | Иконка Crowdin
8 | Помочь перевести
9 | О приложении
10 | Иконка приложения
11 |
12 |
--------------------------------------------------------------------------------
/feature/about/src/commonMain/composeResources/values-ru/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | GitHub иконка
4 | Поставить звездочку или задать вопрос
5 | F-Droid icon
6 | Проверить обновления
7 | Crowdin иконка
8 | Помочь перевести
9 | О приложении
10 | Иконка приложения
11 |
--------------------------------------------------------------------------------
/feature/about/src/commonMain/composeResources/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | GitHub 图标
4 | Star 或反馈问题
5 | F-Droid 图标
6 | 检查更新
7 | Crowdin 图标
8 | 协助翻译
9 | 关于
10 | 应用图标
11 |
12 |
--------------------------------------------------------------------------------
/feature/about/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | GitHub icon
4 | Github
5 | Star or submit issue
6 | F-Droid icon
7 | F-Droid
8 | Check updates
9 | Crowdin icon
10 | Crowdin
11 | Help translate
12 | About
13 | App icon
14 |
--------------------------------------------------------------------------------
/feature/about/src/commonMain/kotlin/ru/stersh/youamp/feature/about/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.about
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.about.ui.AboutAppViewModel
6 |
7 | val aboutModule = module {
8 | viewModel { AboutAppViewModel(get()) }
9 | }
--------------------------------------------------------------------------------
/feature/about/src/commonMain/kotlin/ru/stersh/youamp/feature/about/ui/AboutAppViewModel.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.about.ui
2 |
3 | import androidx.lifecycle.ViewModel
4 | import kotlinx.coroutines.flow.MutableStateFlow
5 | import kotlinx.coroutines.flow.StateFlow
6 | import ru.stersh.youamp.core.properties.app.AppPropertiesStorage
7 |
8 | internal class AboutAppViewModel(appPropertiesStorage: AppPropertiesStorage) : ViewModel() {
9 | private val _state = MutableStateFlow(appPropertiesStorage.getAppProperties().toUiState())
10 |
11 | val state: StateFlow
12 | get() = _state
13 | }
--------------------------------------------------------------------------------
/feature/about/src/commonMain/kotlin/ru/stersh/youamp/feature/about/ui/AboutStateUi.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.about.ui
2 |
3 | internal data class AboutStateUi(
4 | val name: String,
5 | val version: String,
6 | val githubUri: String,
7 | val fdroidUri: String,
8 | val crwodinUri: String
9 | )
10 |
--------------------------------------------------------------------------------
/feature/about/src/commonMain/kotlin/ru/stersh/youamp/feature/about/ui/Mapper.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.about.ui
2 |
3 | import ru.stersh.youamp.core.properties.app.AppProperties
4 |
5 |
6 | internal fun AppProperties.toUiState(): AboutStateUi {
7 | return AboutStateUi(
8 | name = name,
9 | version = version,
10 | githubUri = githubUrl,
11 | fdroidUri = fdroidUrl,
12 | crwodinUri = crwodinUrl
13 | )
14 | }
--------------------------------------------------------------------------------
/feature/album/favorites/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/album/favorites/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/feature/album/favorites/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Àlbums favorits
4 |
5 |
--------------------------------------------------------------------------------
/feature/album/favorites/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Lieblingsalben
4 |
5 |
--------------------------------------------------------------------------------
/feature/album/favorites/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Albums favoris
4 |
5 |
--------------------------------------------------------------------------------
/feature/album/favorites/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Álbuns favoritos
4 |
5 |
--------------------------------------------------------------------------------
/feature/album/favorites/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Избранные альбомы
4 |
5 |
--------------------------------------------------------------------------------
/feature/album/favorites/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Favorite albums
4 |
--------------------------------------------------------------------------------
/feature/album/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/album/favorites/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.favorites
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.album.favorites.data.FavoriteAlbumsRepositoryImpl
6 | import ru.stersh.youamp.feature.album.favorites.domain.FavoriteAlbumsRepository
7 | import ru.stersh.youamp.feature.album.favorites.ui.FavoriteAlbumsViewModel
8 |
9 | val albumFavoritesModule = module {
10 | single { FavoriteAlbumsRepositoryImpl(get()) }
11 | viewModel { FavoriteAlbumsViewModel(get(), get()) }
12 | }
--------------------------------------------------------------------------------
/feature/album/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/album/favorites/domain/Album.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.favorites.domain
2 |
3 | internal data class Album(
4 | val id: String,
5 | val title: String,
6 | val artist: String?,
7 | val artworkUrl: String?,
8 | val userRating: Int?
9 | )
10 |
--------------------------------------------------------------------------------
/feature/album/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/album/favorites/domain/FavoriteAlbumsRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.favorites.domain
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | internal interface FavoriteAlbumsRepository {
6 | fun getFavorites(): Flow
7 | }
--------------------------------------------------------------------------------
/feature/album/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/album/favorites/domain/Favorites.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.favorites.domain
2 |
3 | internal data class Favorites(
4 | val albums: List
5 | )
6 |
--------------------------------------------------------------------------------
/feature/album/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/album/favorites/ui/Mapper.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.favorites.ui
2 |
3 | import kotlinx.collections.immutable.toImmutableList
4 | import ru.stersh.youamp.feature.album.favorites.domain.Album
5 | import ru.stersh.youamp.feature.album.favorites.domain.Favorites
6 |
7 | internal fun Favorites.toUi(): DataUi {
8 | return DataUi(
9 | albums = albums
10 | .map { it.toUi() }
11 | .toImmutableList()
12 | )
13 | }
14 |
15 | private fun Album.toUi() = AlbumUi(
16 | id = id,
17 | title = title,
18 | artist = artist,
19 | artworkUrl = artworkUrl
20 | )
--------------------------------------------------------------------------------
/feature/album/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/album/favorites/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.favorites.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 |
5 | internal data class StateUi(
6 | val progress: Boolean = true,
7 | val isRefreshing: Boolean = false,
8 | val error: Boolean = false,
9 | val data: DataUi? = null
10 | )
11 |
12 | internal data class DataUi(
13 | val albums: ImmutableList
14 | )
15 |
16 | internal class AlbumUi(
17 | val id: String,
18 | val title: String,
19 | val artist: String?,
20 | val artworkUrl: String?
21 | )
--------------------------------------------------------------------------------
/feature/album/info/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/album/info/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/feature/album/info/src/commonMain/kotlin/ru/stersh/youamp/feature/album/info/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.info
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.album.info.data.AlbumFavoriteRepositoryImpl
6 | import ru.stersh.youamp.feature.album.info.data.AlbumInfoRepositoryImpl
7 | import ru.stersh.youamp.feature.album.info.domain.AlbumFavoriteRepository
8 | import ru.stersh.youamp.feature.album.info.domain.AlbumInfoRepository
9 | import ru.stersh.youamp.feature.album.info.ui.AlbumInfoViewModel
10 |
11 | val albumInfoModule = module {
12 | single { AlbumInfoRepositoryImpl(get(), get()) }
13 | single { AlbumFavoriteRepositoryImpl(get()) }
14 |
15 | viewModel { (id: String) ->
16 | AlbumInfoViewModel(id, get(), get(), get())
17 | }
18 | }
--------------------------------------------------------------------------------
/feature/album/info/src/commonMain/kotlin/ru/stersh/youamp/feature/album/info/data/AlbumFavoriteRepositoryImpl.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.info.data
2 |
3 | import ru.stersh.youamp.feature.album.info.domain.AlbumFavoriteRepository
4 | import ru.stersh.youamp.shared.favorites.AlbumFavoritesStorage
5 |
6 | internal class AlbumFavoriteRepositoryImpl(
7 | private val albumFavoritesStorage: AlbumFavoritesStorage
8 | ) : AlbumFavoriteRepository {
9 |
10 | override suspend fun setFavorite(id: String, isFavorite: Boolean) {
11 | albumFavoritesStorage.setAlbumFavorite(id, isFavorite)
12 | }
13 | }
--------------------------------------------------------------------------------
/feature/album/info/src/commonMain/kotlin/ru/stersh/youamp/feature/album/info/domain/AlbumFavoriteRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.info.domain
2 |
3 | internal interface AlbumFavoriteRepository {
4 |
5 | suspend fun setFavorite(id: String, isFavorite: Boolean)
6 | }
--------------------------------------------------------------------------------
/feature/album/info/src/commonMain/kotlin/ru/stersh/youamp/feature/album/info/domain/AlbumInfo.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.info.domain
2 |
3 | internal data class AlbumInfo(
4 | val artworkUrl: String?,
5 | val title: String,
6 | val artist: String,
7 | val year: String?,
8 | val isFavorite: Boolean,
9 | val songs: List
10 | )
--------------------------------------------------------------------------------
/feature/album/info/src/commonMain/kotlin/ru/stersh/youamp/feature/album/info/domain/AlbumInfoRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.info.domain
2 |
3 | internal interface AlbumInfoRepository {
4 | suspend fun getAlbumInfo(id: String): AlbumInfo
5 | }
--------------------------------------------------------------------------------
/feature/album/info/src/commonMain/kotlin/ru/stersh/youamp/feature/album/info/domain/AlbumSong.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.info.domain
2 |
3 | internal data class AlbumSong(
4 | val id: String,
5 | val track: Int?,
6 | val title: String,
7 | val artist: String?,
8 | val duration: String
9 | )
--------------------------------------------------------------------------------
/feature/album/info/src/commonMain/kotlin/ru/stersh/youamp/feature/album/info/ui/AlbumInfoStateUi.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.info.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 |
5 | internal data class AlbumInfoStateUi(
6 | val progress: Boolean = true,
7 | val content: AlbumInfoUi? = null,
8 | val error: Boolean = false
9 | )
10 |
11 | internal data class AlbumInfoUi(
12 | val artworkUrl: String?,
13 | val title: String,
14 | val artist: String,
15 | val year: String?,
16 | val isFavorite: Boolean,
17 | val songs: ImmutableList
18 | )
19 |
20 | internal data class AlbumSongUi(
21 | val id: String,
22 | val title: String,
23 | val track: Int?,
24 | val artist: String?,
25 | val duration: String
26 | )
--------------------------------------------------------------------------------
/feature/album/info/src/commonMain/kotlin/ru/stersh/youamp/feature/album/info/ui/Mapper.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.info.ui
2 |
3 | import kotlinx.collections.immutable.toImmutableList
4 | import ru.stersh.youamp.feature.album.info.domain.AlbumInfo
5 | import ru.stersh.youamp.feature.album.info.domain.AlbumSong
6 |
7 | internal fun AlbumInfo.toUi(): AlbumInfoUi {
8 | return AlbumInfoUi(
9 | title = title,
10 | artist = artist,
11 | year = year,
12 | artworkUrl = artworkUrl,
13 | isFavorite = isFavorite,
14 | songs = songs
15 | .map { it.toUi() }
16 | .toImmutableList()
17 | )
18 | }
19 |
20 | internal fun AlbumSong.toUi(): AlbumSongUi {
21 | return AlbumSongUi(
22 | id = id,
23 | title = title,
24 | track = track,
25 | artist = artist,
26 | duration = duration
27 | )
28 | }
--------------------------------------------------------------------------------
/feature/album/list/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/album/list/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/feature/album/list/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Àlbums
4 |
5 |
--------------------------------------------------------------------------------
/feature/album/list/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Alben
4 |
5 |
--------------------------------------------------------------------------------
/feature/album/list/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Albums
4 |
5 |
--------------------------------------------------------------------------------
/feature/album/list/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Album
4 |
5 |
--------------------------------------------------------------------------------
/feature/album/list/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Álbuns
4 |
5 |
--------------------------------------------------------------------------------
/feature/album/list/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Альбомы
4 |
5 |
--------------------------------------------------------------------------------
/feature/album/list/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Albums
4 |
--------------------------------------------------------------------------------
/feature/album/list/src/commonMain/kotlin/ru/stersh/youamp/feature/album/list/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.list
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.album.list.data.AlbumsRepositoryImpl
6 | import ru.stersh.youamp.feature.album.list.domain.AlbumsRepository
7 | import ru.stersh.youamp.feature.album.list.ui.AlbumsViewModel
8 |
9 | val albumListModule = module {
10 | single { AlbumsRepositoryImpl(get()) }
11 | viewModel { AlbumsViewModel(get(), get()) }
12 | }
--------------------------------------------------------------------------------
/feature/album/list/src/commonMain/kotlin/ru/stersh/youamp/feature/album/list/domain/Album.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.list.domain
2 |
3 | internal data class Album(
4 | val id: String,
5 | val title: String,
6 | val artist: String,
7 | val artworkUrl: String?
8 | )
--------------------------------------------------------------------------------
/feature/album/list/src/commonMain/kotlin/ru/stersh/youamp/feature/album/list/domain/AlbumsRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.list.domain
2 |
3 | internal interface AlbumsRepository {
4 | suspend fun getAlbums(page: Int, pageSize: Int): List
5 | }
--------------------------------------------------------------------------------
/feature/album/list/src/commonMain/kotlin/ru/stersh/youamp/feature/album/list/ui/Mapper.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.list.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 | import kotlinx.collections.immutable.toPersistentList
5 | import ru.stersh.youamp.feature.album.list.domain.Album
6 |
7 | internal fun List.toUi(): ImmutableList {
8 | return map { it.toUi() }.toPersistentList()
9 | }
10 |
11 | internal fun Album.toUi(): AlbumUi {
12 | return AlbumUi(
13 | id = id,
14 | title = title,
15 | artist = artist,
16 | artworkUrl = artworkUrl
17 | )
18 | }
--------------------------------------------------------------------------------
/feature/album/list/src/commonMain/kotlin/ru/stersh/youamp/feature/album/list/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.album.list.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 | import kotlinx.collections.immutable.persistentListOf
5 |
6 | internal data class AlbumsStateUi(
7 | val progress: Boolean = true,
8 | val isRefreshing: Boolean = false,
9 | val error: Boolean = false,
10 | val items: ImmutableList = persistentListOf()
11 | )
12 |
13 | internal data class AlbumUi(
14 | val id: String,
15 | val title: String,
16 | val artist: String?,
17 | val artworkUrl: String?
18 | )
--------------------------------------------------------------------------------
/feature/artist/favorites/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/artist/favorites/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/feature/artist/favorites/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Artistes favorits
4 |
5 |
--------------------------------------------------------------------------------
/feature/artist/favorites/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Lieblingskünstler
4 |
5 |
--------------------------------------------------------------------------------
/feature/artist/favorites/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Artistes favoris
4 |
5 |
--------------------------------------------------------------------------------
/feature/artist/favorites/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Artistas favoritos
4 |
5 |
--------------------------------------------------------------------------------
/feature/artist/favorites/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Избранные исполнители
4 |
5 |
--------------------------------------------------------------------------------
/feature/artist/favorites/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Favorite artists
4 |
--------------------------------------------------------------------------------
/feature/artist/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/favorites/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.favorites
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.artist.favorites.data.FavoriteArtistsRepositoryImpl
6 | import ru.stersh.youamp.feature.artist.favorites.domain.FavoriteArtistsRepository
7 | import ru.stersh.youamp.feature.artist.favorites.ui.FavoriteArtistViewModel
8 |
9 | val artistFavoritesModule = module {
10 | single { FavoriteArtistsRepositoryImpl(get()) }
11 | viewModel { FavoriteArtistViewModel(get(), get()) }
12 | }
--------------------------------------------------------------------------------
/feature/artist/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/favorites/domain/Artist.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.favorites.domain
2 |
3 | internal data class Artist(
4 | val id: String,
5 | val name: String,
6 | val artworkUrl: String?,
7 | val userRating: Int?
8 | )
9 |
--------------------------------------------------------------------------------
/feature/artist/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/favorites/domain/FavoriteArtistsRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.favorites.domain
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | internal interface FavoriteArtistsRepository {
6 | fun getFavorites(): Flow
7 | }
--------------------------------------------------------------------------------
/feature/artist/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/favorites/domain/Favorites.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.favorites.domain
2 |
3 | internal data class Favorites(
4 | val artists: List
5 | )
6 |
--------------------------------------------------------------------------------
/feature/artist/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/favorites/ui/Mapper.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.favorites.ui
2 |
3 | import kotlinx.collections.immutable.toImmutableList
4 | import ru.stersh.youamp.feature.artist.favorites.domain.Artist
5 | import ru.stersh.youamp.feature.artist.favorites.domain.Favorites
6 |
7 | internal fun Favorites.toUi(): DataUi {
8 | return DataUi(
9 | artists = artists
10 | .map { it.toUi() }
11 | .toImmutableList()
12 | )
13 | }
14 |
15 | private fun Artist.toUi() = ArtistUi(
16 | id = id,
17 | name = name,
18 | artworkUrl = artworkUrl
19 | )
--------------------------------------------------------------------------------
/feature/artist/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/favorites/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.favorites.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 |
5 | internal data class StateUi(
6 | val progress: Boolean = true,
7 | val isRefreshing: Boolean = false,
8 | val error: Boolean = false,
9 | val data: DataUi? = null
10 | )
11 |
12 | internal data class DataUi(
13 | val artists: ImmutableList
14 | )
15 |
16 | internal class ArtistUi(
17 | val id: String,
18 | val name: String,
19 | val artworkUrl: String?
20 | )
--------------------------------------------------------------------------------
/feature/artist/info/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/artist/info/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/feature/artist/info/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/info/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.info
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.artist.info.data.ArtistFavoriteRepositoryImpl
6 | import ru.stersh.youamp.feature.artist.info.data.ArtistInfoRepositoryImpl
7 | import ru.stersh.youamp.feature.artist.info.domain.ArtistFavoriteRepository
8 | import ru.stersh.youamp.feature.artist.info.domain.ArtistInfoRepository
9 | import ru.stersh.youamp.feature.artist.info.ui.ArtistInfoViewModel
10 |
11 | val artistInfoModule = module {
12 | single { ArtistInfoRepositoryImpl(get(), get()) }
13 | single { ArtistFavoriteRepositoryImpl(get()) }
14 | viewModel { (id: String) ->
15 | ArtistInfoViewModel(id, get(), get(), get())
16 | }
17 | }
--------------------------------------------------------------------------------
/feature/artist/info/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/info/data/ArtistFavoriteRepositoryImpl.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.info.data
2 |
3 | import ru.stersh.youamp.feature.artist.info.domain.ArtistFavoriteRepository
4 | import ru.stersh.youamp.shared.favorites.ArtistFavoritesStorage
5 |
6 | internal class ArtistFavoriteRepositoryImpl(
7 | private val artistFavoritesStorage: ArtistFavoritesStorage
8 | ) : ArtistFavoriteRepository {
9 |
10 | override suspend fun setFavorite(id: String, isFavorite: Boolean) {
11 | artistFavoritesStorage.setArtistFavorite(id, isFavorite)
12 | }
13 | }
--------------------------------------------------------------------------------
/feature/artist/info/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/info/domain/ArtistAlbum.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.info.domain
2 |
3 | internal data class ArtistAlbum(
4 | val id: String,
5 | val title: String,
6 | val artist: String?,
7 | val artworkUrl: String?
8 | )
--------------------------------------------------------------------------------
/feature/artist/info/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/info/domain/ArtistFavoriteRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.info.domain
2 |
3 | internal interface ArtistFavoriteRepository {
4 |
5 | suspend fun setFavorite(id: String, isFavorite: Boolean)
6 | }
--------------------------------------------------------------------------------
/feature/artist/info/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/info/domain/ArtistInfo.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.info.domain
2 |
3 | internal data class ArtistInfo(
4 | val artworkUrl: String? = null,
5 | val isFavorite: Boolean,
6 | val name: String,
7 | val albums: List
8 | )
--------------------------------------------------------------------------------
/feature/artist/info/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/info/domain/ArtistInfoRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.info.domain
2 |
3 | internal interface ArtistInfoRepository {
4 | suspend fun getArtistInfo(id: String): ArtistInfo
5 | }
--------------------------------------------------------------------------------
/feature/artist/info/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/info/ui/Mapper.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.info.ui
2 |
3 | import kotlinx.collections.immutable.toImmutableList
4 | import ru.stersh.youamp.feature.artist.info.domain.ArtistAlbum
5 | import ru.stersh.youamp.feature.artist.info.domain.ArtistInfo
6 |
7 | internal fun ArtistInfo.toUi(): ArtistInfoUi {
8 | return ArtistInfoUi(
9 | artworkUrl = artworkUrl,
10 | name = name,
11 | isFavorite = isFavorite,
12 | albums = albums
13 | .map { it.toUi() }
14 | .toImmutableList()
15 | )
16 | }
17 |
18 | internal fun ArtistAlbum.toUi(): AlbumUi {
19 | return AlbumUi(
20 | id = id,
21 | title = title,
22 | artist = artist,
23 | artworkUrl = artworkUrl
24 | )
25 | }
--------------------------------------------------------------------------------
/feature/artist/info/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/info/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.info.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 |
5 | internal data class ArtistInfoStateUi(
6 | val progress: Boolean = true,
7 | val error: Boolean = true,
8 | val content: ArtistInfoUi? = null
9 | )
10 |
11 | internal data class ArtistInfoUi(
12 | val artworkUrl: String? = null,
13 | val name: String,
14 | val isFavorite: Boolean,
15 | val albums: ImmutableList
16 | )
17 |
18 | internal data class AlbumUi(
19 | val id: String,
20 | val title: String,
21 | val artist: String?,
22 | val artworkUrl: String?
23 | )
--------------------------------------------------------------------------------
/feature/artist/list/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/artist/list/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/feature/artist/list/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Artistes
4 |
5 |
--------------------------------------------------------------------------------
/feature/artist/list/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Künstler
4 |
5 |
--------------------------------------------------------------------------------
/feature/artist/list/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Artistes
4 |
5 |
--------------------------------------------------------------------------------
/feature/artist/list/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Artisti
4 |
5 |
--------------------------------------------------------------------------------
/feature/artist/list/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Artistas
4 |
5 |
--------------------------------------------------------------------------------
/feature/artist/list/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Исполнители
4 |
5 |
--------------------------------------------------------------------------------
/feature/artist/list/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Artists
4 |
--------------------------------------------------------------------------------
/feature/artist/list/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/list/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.list
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.artist.list.data.ArtistsRepositoryImpl
6 | import ru.stersh.youamp.feature.artist.list.domain.ArtistsRepository
7 | import ru.stersh.youamp.feature.artist.list.ui.ArtistsViewModel
8 |
9 | val artistListModule = module {
10 | single { ArtistsRepositoryImpl(get()) }
11 | viewModel { ArtistsViewModel(get()) }
12 | }
--------------------------------------------------------------------------------
/feature/artist/list/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/list/domain/Artist.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.list.domain
2 |
3 | internal data class Artist(
4 | val id: String,
5 | val name: String,
6 | val artworkUrl: String?
7 | )
--------------------------------------------------------------------------------
/feature/artist/list/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/list/domain/ArtistsRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.list.domain
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | internal interface ArtistsRepository {
6 | suspend fun getArtists(): Flow>
7 | }
--------------------------------------------------------------------------------
/feature/artist/list/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/list/ui/Mapper.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.list.ui
2 |
3 | import ru.stersh.youamp.feature.artist.list.domain.Artist
4 |
5 | internal fun Artist.toUi(): ArtistUi {
6 | return ArtistUi(
7 | id = id,
8 | name = name,
9 | artworkUrl = artworkUrl
10 | )
11 | }
--------------------------------------------------------------------------------
/feature/artist/list/src/commonMain/kotlin/ru/stersh/youamp/feature/artist/list/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.artist.list.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 | import kotlinx.collections.immutable.persistentListOf
5 |
6 | internal data class ArtistsStateUi(
7 | val progress: Boolean = true,
8 | val isRefreshing: Boolean = false,
9 | val error: Boolean = false,
10 | val items: ImmutableList = persistentListOf()
11 | )
12 |
13 | internal data class ArtistUi(
14 | val id: String,
15 | val name: String,
16 | val artworkUrl: String?
17 | )
--------------------------------------------------------------------------------
/feature/explore/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/explore/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Cerca cançons, àlbums, artistes…
4 | Cerca
5 | Cançons aleatòries
6 |
7 |
--------------------------------------------------------------------------------
/feature/explore/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Suche Lieder, Alben, Künstler…
4 | Suchen
5 | Zufällige Lieder
6 |
7 |
--------------------------------------------------------------------------------
/feature/explore/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Recherche chansons, albums, artistes…
4 | Rechercher
5 | Chansons aléatoires
6 |
7 |
--------------------------------------------------------------------------------
/feature/explore/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Cerca canzoni, album, artisti…
4 | Cerca
5 | Brani casuali
6 |
7 |
--------------------------------------------------------------------------------
/feature/explore/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Pesquisar músicas, álbuns, artistas…
4 | Pesquisar
5 | Músicas aleatórias
6 |
7 |
--------------------------------------------------------------------------------
/feature/explore/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Поиск песен, альбомов, исполнителей…
4 | Поиск
5 | Случайные песни
6 |
7 |
--------------------------------------------------------------------------------
/feature/explore/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Search songs, albums, artists…
4 | Search
5 | Random songs
6 |
--------------------------------------------------------------------------------
/feature/explore/src/commonMain/kotlin/ru/stersh/youamp/feature/explore/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.explore
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.explore.data.ExploreRepositoryImpl
6 | import ru.stersh.youamp.feature.explore.domain.ExploreRepository
7 | import ru.stersh.youamp.feature.explore.ui.ExploreViewModel
8 |
9 | val exploreModule = module {
10 | single { ExploreRepositoryImpl(get(), get(), get(), get()) }
11 | viewModel { ExploreViewModel(get(), get(), get(), get()) }
12 | }
--------------------------------------------------------------------------------
/feature/explore/src/commonMain/kotlin/ru/stersh/youamp/feature/explore/domain/Explore.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.explore.domain
2 |
3 | internal class Explore(
4 | val randomSongs: List
5 | )
--------------------------------------------------------------------------------
/feature/explore/src/commonMain/kotlin/ru/stersh/youamp/feature/explore/domain/ExploreRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.explore.domain
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | internal interface ExploreRepository {
6 | fun getExplore(): Flow
7 | suspend fun refresh()
8 | }
--------------------------------------------------------------------------------
/feature/explore/src/commonMain/kotlin/ru/stersh/youamp/feature/explore/domain/Song.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.explore.domain
2 |
3 | internal data class Song(
4 | val id: String,
5 | val title: String,
6 | val artist: String?,
7 | val artworkUrl: String?,
8 | val isPlaying: Boolean
9 | )
10 |
--------------------------------------------------------------------------------
/feature/explore/src/commonMain/kotlin/ru/stersh/youamp/feature/explore/ui/Mapper.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.explore.ui
2 |
3 | import kotlinx.collections.immutable.toPersistentList
4 | import ru.stersh.youamp.feature.explore.domain.Explore
5 | import ru.stersh.youamp.feature.explore.domain.Song
6 |
7 | internal fun Explore.toUi(): DataUi {
8 | return DataUi(
9 | randomSongs = randomSongs
10 | .map { it.toUi() }
11 | .chunked(3)
12 | .map { it.toPersistentList() }
13 | .toPersistentList()
14 | )
15 | }
16 |
17 | private fun Song.toUi(): SongUi {
18 | return SongUi(
19 | id = id,
20 | title = title,
21 | artist = artist,
22 | artworkUrl = artworkUrl,
23 | isPlaying = isPlaying
24 | )
25 | }
--------------------------------------------------------------------------------
/feature/explore/src/commonMain/kotlin/ru/stersh/youamp/feature/explore/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.explore.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 | import kotlinx.collections.immutable.persistentListOf
5 |
6 | internal data class StateUi(
7 | val progress: Boolean = true,
8 | val refreshing: Boolean = false,
9 | val error: Boolean = false,
10 | val data: DataUi? = null
11 | )
12 |
13 | internal data class DataUi(
14 | val randomSongs: ImmutableList> = persistentListOf(),
15 | )
16 |
17 | internal data class SongUi(
18 | val id: String,
19 | val title: String,
20 | val artist: String?,
21 | val artworkUrl: String?,
22 | val isPlaying: Boolean
23 | )
--------------------------------------------------------------------------------
/feature/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/library/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Àlbums
4 | Artistes
5 |
6 |
--------------------------------------------------------------------------------
/feature/library/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Alben
4 | Künstler
5 |
6 |
--------------------------------------------------------------------------------
/feature/library/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Albums
4 | Artistes
5 |
6 |
--------------------------------------------------------------------------------
/feature/library/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Album
4 | Artisti
5 |
6 |
--------------------------------------------------------------------------------
/feature/library/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Álbuns
4 | Artistas
5 |
6 |
--------------------------------------------------------------------------------
/feature/library/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Альбомы
4 | Исполнители
5 |
6 |
--------------------------------------------------------------------------------
/feature/library/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Albums
4 | Artists
5 |
--------------------------------------------------------------------------------
/feature/library/src/commonMain/kotlin/ru/stersh/youamp/feature/library/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.library
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.library.data.LibraryRepositoryImpl
6 | import ru.stersh.youamp.feature.library.domain.LibraryRepository
7 | import ru.stersh.youamp.feature.library.ui.LibraryViewModel
8 |
9 | val libraryModule = module {
10 | single { LibraryRepositoryImpl(get(), get(), get()) }
11 | viewModel { LibraryViewModel(get(), get(), get(), get()) }
12 | }
--------------------------------------------------------------------------------
/feature/library/src/commonMain/kotlin/ru/stersh/youamp/feature/library/domain/Library.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.library.domain
2 |
3 | internal data class Library(
4 | val artists: List,
5 | val albums: List,
6 | )
7 |
8 | internal data class Artist(
9 | val id: String,
10 | val name: String,
11 | val artworkUrl: String?,
12 | val isPlaying: Boolean
13 | )
14 |
15 | internal data class Album(
16 | val id: String,
17 | val title: String,
18 | val artist: String?,
19 | val artworkUrl: String?,
20 | val isPlaying: Boolean
21 | )
--------------------------------------------------------------------------------
/feature/library/src/commonMain/kotlin/ru/stersh/youamp/feature/library/domain/LibraryRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.library.domain
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | internal interface LibraryRepository {
6 | fun getLibrary(): Flow
7 | }
--------------------------------------------------------------------------------
/feature/library/src/commonMain/kotlin/ru/stersh/youamp/feature/library/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.library.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 | import kotlinx.collections.immutable.persistentListOf
5 |
6 | internal data class StateUi(
7 | val progress: Boolean = true,
8 | val error: Boolean = false,
9 | val refreshing: Boolean = false,
10 | val data: DataUi? = null
11 | )
12 |
13 | internal data class DataUi(
14 | val artists: ImmutableList = persistentListOf(),
15 | val albums: ImmutableList = persistentListOf(),
16 | )
17 |
18 | internal data class ArtistUi(
19 | val id: String,
20 | val name: String,
21 | val artworkUrl: String?,
22 | val isPlaying: Boolean
23 | )
24 |
25 | internal data class AlbumUi(
26 | val id: String,
27 | val title: String,
28 | val artist: String?,
29 | val artworkUrl: String?,
30 | val isPlaying: Boolean
31 | )
--------------------------------------------------------------------------------
/feature/main/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/main/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Personal
4 | Explora
5 | Biblioteca
6 |
7 |
--------------------------------------------------------------------------------
/feature/main/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/feature/main/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Personnel
4 | Explorez
5 | Bibliothèque
6 |
7 |
--------------------------------------------------------------------------------
/feature/main/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/feature/main/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Perfil
4 | Explorar
5 | Galeria
6 |
7 |
--------------------------------------------------------------------------------
/feature/main/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Личное
4 | Обзор
5 | Библиотека
6 |
7 |
--------------------------------------------------------------------------------
/feature/main/src/commonMain/composeResources/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/feature/main/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Personal
4 | Explore
5 | Library
6 |
--------------------------------------------------------------------------------
/feature/main/src/commonMain/kotlin/ru/stersh/youamp/feature/main/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.main
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.main.data.ServerInfoRepositoryImpl
6 | import ru.stersh.youamp.feature.main.domain.ServerInfoRepository
7 | import ru.stersh.youamp.feature.main.ui.MainViewModel
8 |
9 | val mainModule = module {
10 | single { ServerInfoRepositoryImpl(get(), get()) }
11 | viewModel { MainViewModel(get()) }
12 | }
--------------------------------------------------------------------------------
/feature/main/src/commonMain/kotlin/ru/stersh/youamp/feature/main/domain/ServerInfo.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.main.domain
2 |
3 | internal data class ServerInfo(
4 | val name: String,
5 | val avatarUrl: String?
6 | )
7 |
--------------------------------------------------------------------------------
/feature/main/src/commonMain/kotlin/ru/stersh/youamp/feature/main/domain/ServerInfoRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.main.domain
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | internal interface ServerInfoRepository {
6 |
7 | fun getServerInfo(): Flow
8 | }
--------------------------------------------------------------------------------
/feature/personal/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/personal/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Pausa
4 | Reprodueix
5 | %s i %s
6 | %s, %s i d\'altres
7 | Cançons
8 | Llistes de reproducció
9 | Àlbums
10 | Artistes
11 |
12 |
--------------------------------------------------------------------------------
/feature/personal/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Pause
4 | Abspielen
5 | %s und %s
6 | %s, %s und andere
7 | Songs
8 | Wiedergabelisten
9 | Alben
10 | Künstler
11 |
12 |
--------------------------------------------------------------------------------
/feature/personal/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Pause
4 | Lire
5 | %s et %s
6 | %s, %s et autres
7 | Chansons
8 | Playlists
9 | Albums
10 | Artistes
11 |
12 |
--------------------------------------------------------------------------------
/feature/personal/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Pausa
4 | Riproduci
5 | %s E %s
6 | %s, %s e altri
7 | Brani
8 | Playlist
9 | Album
10 | Artisti
11 |
12 |
--------------------------------------------------------------------------------
/feature/personal/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Pausar
4 | Reproduzir
5 | %s e %s
6 | %s, %s e outros
7 | Músicas
8 | Playlists
9 | Álbuns
10 | Artistas
11 |
12 |
--------------------------------------------------------------------------------
/feature/personal/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Пауза
4 | Играть
5 | %s и %s
6 | %s, %s и другие
7 | Песни
8 | Плейлисты
9 | Альбомы
10 | Исполнители
11 |
12 |
--------------------------------------------------------------------------------
/feature/personal/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Pause
4 | Play
5 | %s and %s
6 | %s, %s and others
7 | Songs
8 | Playlists
9 | Albums
10 | Artists
11 |
--------------------------------------------------------------------------------
/feature/personal/src/commonMain/kotlin/ru/stersh/youamp/feature/personal/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.personal
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.personal.data.PersonalRepositoryImpl
6 | import ru.stersh.youamp.feature.personal.domain.PersonalRepository
7 | import ru.stersh.youamp.feature.personal.ui.PersonalViewModel
8 |
9 | val personalModule = module {
10 | single { PersonalRepositoryImpl(get(), get(), get(), get(), get(), get()) }
11 | viewModel { PersonalViewModel(get(), get(), get(), get()) }
12 | }
--------------------------------------------------------------------------------
/feature/personal/src/commonMain/kotlin/ru/stersh/youamp/feature/personal/domain/Album.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.personal.domain
2 |
3 | internal data class Album(
4 | val id: String,
5 | val title: String,
6 | val artist: String?,
7 | val artworkUrl: String?,
8 | val isPlaying: Boolean
9 | )
--------------------------------------------------------------------------------
/feature/personal/src/commonMain/kotlin/ru/stersh/youamp/feature/personal/domain/Artist.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.personal.domain
2 |
3 | internal data class Artist(
4 | val id: String,
5 | val name: String,
6 | val artworkUrl: String?,
7 | val isPlaying: Boolean
8 | )
--------------------------------------------------------------------------------
/feature/personal/src/commonMain/kotlin/ru/stersh/youamp/feature/personal/domain/Personal.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.personal.domain
2 |
3 | internal data class Personal(
4 | val playlists: List,
5 | val songs: List,
6 | val albums: List,
7 | val artists: List
8 | )
--------------------------------------------------------------------------------
/feature/personal/src/commonMain/kotlin/ru/stersh/youamp/feature/personal/domain/PersonalRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.personal.domain
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | internal interface PersonalRepository {
6 | suspend fun getPersonal(): Flow
7 | }
--------------------------------------------------------------------------------
/feature/personal/src/commonMain/kotlin/ru/stersh/youamp/feature/personal/domain/Playlist.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.personal.domain
2 |
3 | internal data class Playlist(
4 | val id: String,
5 | val name: String,
6 | val artworkUrl: String?,
7 | val isPlaying: Boolean
8 | )
--------------------------------------------------------------------------------
/feature/personal/src/commonMain/kotlin/ru/stersh/youamp/feature/personal/domain/Song.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.personal.domain
2 |
3 | internal data class Song(
4 | val id: String,
5 | val title: String,
6 | val artist: String?,
7 | val artworkUrl: String?,
8 | val isPlaying: Boolean
9 | )
--------------------------------------------------------------------------------
/feature/player/mini/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/player/mini/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Botó de pausa
4 | Botó de reproducció
5 |
6 |
--------------------------------------------------------------------------------
/feature/player/mini/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Pause-Taste
4 | Play-Taste
5 |
6 |
--------------------------------------------------------------------------------
/feature/player/mini/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Bouton pause
4 | Bouton lire
5 |
6 |
--------------------------------------------------------------------------------
/feature/player/mini/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Pausa
4 | Riproduci
5 |
6 |
--------------------------------------------------------------------------------
/feature/player/mini/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Botão \"Pausar\"
4 | Botão \"Reproduzir\"
5 |
6 |
--------------------------------------------------------------------------------
/feature/player/mini/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Кнопка \"Пауза\"
4 | Кнопка \"Играть\"
5 |
6 |
--------------------------------------------------------------------------------
/feature/player/mini/src/commonMain/composeResources/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 暂停按钮
4 | 播放按钮
5 |
6 |
--------------------------------------------------------------------------------
/feature/player/mini/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Pause button
4 | Play button
5 |
--------------------------------------------------------------------------------
/feature/player/mini/src/commonMain/kotlin/ru/stersh/youamp/feature/player/mini/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.player.mini
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.player.mini.ui.MiniPlayerViewModel
6 |
7 | val playerMiniModule = module {
8 | viewModel { MiniPlayerViewModel(get()) }
9 | }
--------------------------------------------------------------------------------
/feature/player/mini/src/commonMain/kotlin/ru/stersh/youamp/feature/player/mini/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.player.mini.ui
2 |
3 | internal data class StateUi(
4 | val data: PlayerDataUi? = null,
5 | val invisible: Boolean = true
6 | )
7 |
8 | internal data class PlayerDataUi(
9 | val title: String?,
10 | val artist: String?,
11 | val artworkUrl: String?,
12 | val isPlaying: Boolean,
13 | val progress: Float,
14 | )
--------------------------------------------------------------------------------
/feature/player/queue/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/player/queue/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Reprodueix la cua
4 | Reprodueix la cançó
5 | Elimina de la cua
6 |
7 |
--------------------------------------------------------------------------------
/feature/player/queue/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Wiedergabeliste
4 | Titel abspielen
5 | Aus der Warteschlange entfernen
6 |
7 |
--------------------------------------------------------------------------------
/feature/player/queue/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Jouer liste de lecture
4 | Lire le titre
5 | Retirer de la file d’attente
6 |
7 |
--------------------------------------------------------------------------------
/feature/player/queue/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Coda di riproduzione
4 | Riproduci brano
5 | Rimuovi dalla coda
6 |
7 |
--------------------------------------------------------------------------------
/feature/player/queue/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Fila de reprodução
4 | Reproduzir música
5 | Remover da fila
6 |
7 |
--------------------------------------------------------------------------------
/feature/player/queue/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Очередь воспроизведения
4 | Играть песню
5 | Удалить из очереди
6 |
7 |
--------------------------------------------------------------------------------
/feature/player/queue/src/commonMain/composeResources/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 播放队列
4 |
5 |
--------------------------------------------------------------------------------
/feature/player/queue/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Play queue
4 | Play song
5 | Remove from queue
6 |
--------------------------------------------------------------------------------
/feature/player/queue/src/commonMain/kotlin/ru/stersh/youamp/feature/player/queue/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.player.queue
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.player.queue.ui.PlayerQueueViewModel
6 |
7 | val playerQueueScreenModule = module {
8 | viewModel { PlayerQueueViewModel(get()) }
9 | }
--------------------------------------------------------------------------------
/feature/player/queue/src/commonMain/kotlin/ru/stersh/youamp/feature/player/queue/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.player.queue.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 | import kotlinx.collections.immutable.persistentListOf
5 |
6 | internal data class StateUi(
7 | val songs: ImmutableList = persistentListOf(),
8 | val progress: Boolean = true,
9 | val menuSongState: MenuSongStateUi? = null
10 | )
11 |
12 | internal data class MenuSongStateUi(
13 | val title: String?,
14 | val artist: String?,
15 | val artworkUrl: String?,
16 | val index: Int
17 | )
18 |
19 | internal data class SongUi(
20 | val id: String,
21 | val title: String,
22 | val artist: String?,
23 | val isCurrent: Boolean,
24 | val isPlaying: Boolean,
25 | val artworkUrl: String?
26 | )
27 |
--------------------------------------------------------------------------------
/feature/player/screen/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/player/screen/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Reprodueix la cua
4 | Mode aleatori
5 | Mode de repetició
6 | Cançó preferida
7 | Botó de pausa
8 | Botó de reproducció
9 | Cançó anterior
10 | Cançó següent
11 |
12 |
--------------------------------------------------------------------------------
/feature/player/screen/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Wiedergabeliste
4 | Shufflemodus
5 | Wiederholungsmodus
6 | Titel zu Favoriten hinzufügen
7 | Pause-Taste
8 | Play-Taste
9 | Vorheriger Titel
10 | Nächster Titel
11 |
12 |
--------------------------------------------------------------------------------
/feature/player/screen/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Jouer liste de lecture
4 | Mode aléatoire
5 | Mode répétition
6 | Chanson favorite
7 | Bouton pause
8 | Bouton lire
9 | Chanson précédente
10 | Chanson suivante
11 |
12 |
--------------------------------------------------------------------------------
/feature/player/screen/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Coda di riproduzione
4 | Modalità casuale
5 | Modalità Ripeti
6 | Canzone preferita
7 | Pausa
8 | Riproduci
9 | Canzone precedente
10 | Canzone successiva
11 |
12 |
--------------------------------------------------------------------------------
/feature/player/screen/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Fila de reprodução
4 | Modo de reprodução aleatória
5 | Modo de repetição
6 | Músicas favoritas
7 | Botão \"Pausar\"
8 | Botão \"Reproduzir\"
9 | Música anterior
10 | Próxima música
11 |
12 |
--------------------------------------------------------------------------------
/feature/player/screen/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Очередь воспроизведения
4 | Режим перемешивания
5 | Режим повтора
6 | Любимая песня
7 | Кнопка \"Пауза\"
8 | Кнопка \"Играть\"
9 | Предыдущая песня
10 | Следующая песня
11 |
12 |
--------------------------------------------------------------------------------
/feature/player/screen/src/commonMain/composeResources/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 播放队列
4 | 随机模式
5 | 重复模式
6 | 收藏歌曲
7 | 暂停按钮
8 | 播放按钮
9 | 上一首歌
10 | 下一首歌
11 |
12 |
--------------------------------------------------------------------------------
/feature/player/screen/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Play queue
4 | Shuffle mode
5 | Repeat mode
6 | Favorite song
7 | Pause button
8 | Play button
9 | Previous song
10 | Next song
11 |
--------------------------------------------------------------------------------
/feature/player/screen/src/commonMain/kotlin/ru/stersh/youamp/feature/player/screen/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.player.screen
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.player.screen.ui.PlayerScreenViewModel
6 |
7 | val playerScreenModule = module {
8 | viewModel { PlayerScreenViewModel(get(), get()) }
9 | }
--------------------------------------------------------------------------------
/feature/player/screen/src/commonMain/kotlin/ru/stersh/youamp/feature/player/screen/ui/RepeatModeUi.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.player.screen.ui
2 |
3 | internal enum class RepeatModeUi { Disabled, One, All }
--------------------------------------------------------------------------------
/feature/player/screen/src/commonMain/kotlin/ru/stersh/youamp/feature/player/screen/ui/ShuffleModeUi.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.player.screen.ui
2 |
3 | internal enum class ShuffleModeUi { Enabled, Disabled }
--------------------------------------------------------------------------------
/feature/player/screen/src/commonMain/kotlin/ru/stersh/youamp/feature/player/screen/ui/StateUi.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.player.screen.ui
2 |
3 | internal data class StateUi(
4 | val artworkUrl: String? = null,
5 | val title: String? = null,
6 | val artist: String? = null,
7 | val isPlaying: Boolean = false,
8 | val progress: Float = 0f,
9 | val currentTime: String? = "00:00",
10 | val totalTime: String? = "00:00",
11 | val repeatMode: RepeatModeUi = RepeatModeUi.Disabled,
12 | val shuffleMode: ShuffleModeUi = ShuffleModeUi.Disabled,
13 | val isFavorite: Boolean = false
14 | )
--------------------------------------------------------------------------------
/feature/playlist/info/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/playlist/info/src/commonMain/kotlin/ru/stersh/youamp/feature/playlist/info/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.playlist.info
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.playlist.info.data.PlaylistInfoRepositoryImpl
6 | import ru.stersh.youamp.feature.playlist.info.domain.PlaylistInfoRepository
7 | import ru.stersh.youamp.feature.playlist.info.ui.PlaylistInfoViewModel
8 |
9 | val playlistInfoModule = module {
10 | single { PlaylistInfoRepositoryImpl(get(), get()) }
11 | viewModel { (id: String) ->
12 | PlaylistInfoViewModel(id, get(), get(), get())
13 | }
14 | }
--------------------------------------------------------------------------------
/feature/playlist/info/src/commonMain/kotlin/ru/stersh/youamp/feature/playlist/info/domain/PlaylistInfo.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.playlist.info.domain
2 |
3 | internal data class PlaylistInfo(
4 | val artworkUrl: String?,
5 | val title: String,
6 | val songs: List
7 | )
--------------------------------------------------------------------------------
/feature/playlist/info/src/commonMain/kotlin/ru/stersh/youamp/feature/playlist/info/domain/PlaylistInfoRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.playlist.info.domain
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | internal interface PlaylistInfoRepository {
6 | fun getPlaylistInfo(playlistId: String): Flow
7 | }
--------------------------------------------------------------------------------
/feature/playlist/info/src/commonMain/kotlin/ru/stersh/youamp/feature/playlist/info/domain/PlaylistSong.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.playlist.info.domain
2 |
3 | internal data class PlaylistSong(
4 | val id: String,
5 | val title: String,
6 | val artist: String?,
7 | val artworkUrl: String?,
8 | val isCurrent: Boolean,
9 | val isPlaying: Boolean
10 | )
--------------------------------------------------------------------------------
/feature/playlist/info/src/commonMain/kotlin/ru/stersh/youamp/feature/playlist/info/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.playlist.info.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 |
5 | internal data class PlaylistInfoScreenStateUi(
6 | val progress: Boolean = true,
7 | val error: Boolean = false,
8 | val playlistInfo: PlaylistInfoUi? = null
9 | )
10 |
11 | internal data class PlaylistInfoUi(
12 | val artworkUrl: String?,
13 | val title: String,
14 | val songs: ImmutableList
15 | )
16 |
17 | internal data class PlaylistSongUi(
18 | val id: String,
19 | val title: String,
20 | val artist: String?,
21 | val artworkUrl: String?,
22 | val isCurrent: Boolean,
23 | val isPlaying: Boolean
24 | )
--------------------------------------------------------------------------------
/feature/playlist/list/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/playlist/list/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Llistes de reproducció
4 |
5 |
--------------------------------------------------------------------------------
/feature/playlist/list/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Wiedergabelisten
4 |
5 |
--------------------------------------------------------------------------------
/feature/playlist/list/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Playlists
4 |
5 |
--------------------------------------------------------------------------------
/feature/playlist/list/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Playlist
4 |
5 |
--------------------------------------------------------------------------------
/feature/playlist/list/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Playlists
4 |
5 |
--------------------------------------------------------------------------------
/feature/playlist/list/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Плейлисты
4 |
5 |
--------------------------------------------------------------------------------
/feature/playlist/list/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Playlists
4 |
--------------------------------------------------------------------------------
/feature/playlist/list/src/commonMain/kotlin/ru/stersh/youamp/feature/playlist/list/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.playlist.list
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.playlist.list.data.PlaylistsRepositoryImpl
6 | import ru.stersh.youamp.feature.playlist.list.domain.PlaylistsRepository
7 | import ru.stersh.youamp.feature.playlist.list.ui.PlaylistsViewModel
8 |
9 | val playlistListModule = module {
10 | single { PlaylistsRepositoryImpl(get()) }
11 | viewModel { PlaylistsViewModel(get()) }
12 | }
--------------------------------------------------------------------------------
/feature/playlist/list/src/commonMain/kotlin/ru/stersh/youamp/feature/playlist/list/domain/Playlist.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.playlist.list.domain
2 |
3 | internal data class Playlist(
4 | val id: String,
5 | val name: String,
6 | val artworkUrl: String?
7 | )
--------------------------------------------------------------------------------
/feature/playlist/list/src/commonMain/kotlin/ru/stersh/youamp/feature/playlist/list/domain/PlaylistsRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.playlist.list.domain
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | internal interface PlaylistsRepository {
6 | suspend fun getPlaylists(): Flow>
7 | }
--------------------------------------------------------------------------------
/feature/playlist/list/src/commonMain/kotlin/ru/stersh/youamp/feature/playlist/list/ui/Mapper.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.playlist.list.ui
2 |
3 | import ru.stersh.youamp.feature.playlist.list.domain.Playlist
4 |
5 |
6 | internal fun Playlist.toUi(): PlaylistUi {
7 | return PlaylistUi(
8 | id = id,
9 | name = name,
10 | artworkUrl = artworkUrl
11 | )
12 | }
--------------------------------------------------------------------------------
/feature/playlist/list/src/commonMain/kotlin/ru/stersh/youamp/feature/playlist/list/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.playlist.list.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 | import kotlinx.collections.immutable.persistentListOf
5 |
6 | internal data class PlaylistsStateUi(
7 | val progress: Boolean = true,
8 | val isRefreshing: Boolean = false,
9 | val error: Boolean = false,
10 | val items: ImmutableList = persistentListOf()
11 | )
12 |
13 | internal data class PlaylistUi(
14 | val id: String,
15 | val name: String,
16 | val artworkUrl: String?
17 | )
--------------------------------------------------------------------------------
/feature/search/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/search/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Reprodueix
4 | Afegeix a la cua
5 | Informació de l\'artista
6 | Informació de l\'àlbum
7 | Cançons
8 | Carrega\'n més
9 | Àlbums
10 | Artistes
11 | Tanca la cerca
12 | Esborra la cerca
13 | Cerca cançons, àlbums, artistes…
14 | Cerca
15 | Més
16 |
17 |
--------------------------------------------------------------------------------
/feature/search/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Abspielen
4 | Zur Warteschlange hinzufügen
5 | Interpreteninfo
6 | Albumdetails
7 | Titel
8 | Mehr laden
9 | Alben
10 | Interpreten
11 | Suche schließen
12 | Suchabfrage leeren
13 | Suche Titel, Alben, Interpreten…
14 | Suchen
15 | Mehr
16 |
17 |
--------------------------------------------------------------------------------
/feature/search/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Riproduci
4 | Aggiungi alla coda
5 | Informazioni sull\'artista
6 | Informazioni sull\'album
7 | Brani
8 | Carica altro
9 | Album
10 | Artisti
11 | Chiudi ricerca
12 | Cancella la ricerca
13 | Cerca canzoni, album, artisti…
14 | Cerca
15 | Di più
16 |
17 |
--------------------------------------------------------------------------------
/feature/search/src/commonMain/composeResources/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 播放
4 | 添加到队列
5 | 艺人信息
6 | 专辑信息
7 | 歌曲
8 | 加载更多
9 | 专辑
10 | 艺人
11 | 关闭搜索
12 | 清空搜索栏
13 | 搜索歌曲、专辑、艺人…
14 | 搜索
15 | 更多
16 |
17 |
--------------------------------------------------------------------------------
/feature/search/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Play
4 | Add to queue
5 | Artist info
6 | Album info
7 |
8 | Songs
9 | Load more
10 | Albums
11 | Artists
12 | Close search
13 | Clear search query
14 | Search songs, albums, artists…
15 | Search
16 | More
17 |
--------------------------------------------------------------------------------
/feature/search/src/commonMain/kotlin/ru/stersh/youamp/feature/search/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.search
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.search.data.SearchRepositoryImpl
6 | import ru.stersh.youamp.feature.search.domain.SearchRepository
7 | import ru.stersh.youamp.feature.search.ui.SearchViewModel
8 |
9 | val searchModule = module {
10 | factory { SearchRepositoryImpl(get()) }
11 | viewModel { SearchViewModel(get(), get()) }
12 | }
--------------------------------------------------------------------------------
/feature/search/src/commonMain/kotlin/ru/stersh/youamp/feature/search/domain/SearchRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.search.domain
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | internal interface SearchRepository {
6 |
7 | fun searchResults(): Flow
8 |
9 | suspend fun search(query: String)
10 |
11 | suspend fun loadMoreSongs()
12 |
13 | suspend fun loadMoreAlbums()
14 |
15 | suspend fun loadMoreArtists()
16 | }
--------------------------------------------------------------------------------
/feature/search/src/commonMain/kotlin/ru/stersh/youamp/feature/search/ui/Mapper.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.search.ui
2 |
3 | import ru.stersh.youamp.feature.search.domain.SearchResult
4 |
5 | internal fun SearchResult.Song.toUi(): Song {
6 | return Song(
7 | id = id,
8 | title = title,
9 | artist = artist,
10 | artworkUrl = artworkUrl
11 | )
12 | }
13 |
14 | internal fun SearchResult.Album.toUi(): Album {
15 | return Album(
16 | id = id,
17 | title = title,
18 | artist = artist,
19 | artworkUrl = artworkUrl
20 | )
21 | }
22 |
23 | internal fun SearchResult.Artist.toUi(): Artist {
24 | return Artist(
25 | id = id,
26 | name = name,
27 | artworkUrl = artworkUrl
28 | )
29 | }
--------------------------------------------------------------------------------
/feature/server/create/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/server/create/src/commonMain/kotlin/ru/stersh/youamp/feature/server/create/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.server.create
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.server.create.data.ServerRepositoryImpl
6 | import ru.stersh.youamp.feature.server.create.domain.ServerRepository
7 | import ru.stersh.youamp.feature.server.create.ui.ServerCreateViewModel
8 |
9 | val serverCreateModule = module {
10 | factory { ServerRepositoryImpl(get()) }
11 | viewModel { (serverId: Long?) ->
12 | ServerCreateViewModel(serverId, get())
13 | }
14 | }
--------------------------------------------------------------------------------
/feature/server/create/src/commonMain/kotlin/ru/stersh/youamp/feature/server/create/domain/Server.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.server.create.domain
2 |
3 | internal data class Server(
4 | val name: String,
5 | val url: String,
6 | val username: String,
7 | val password: String,
8 | val useLegacyAuth: Boolean
9 | )
10 |
--------------------------------------------------------------------------------
/feature/server/create/src/commonMain/kotlin/ru/stersh/youamp/feature/server/create/domain/ServerRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.server.create.domain
2 |
3 | internal interface ServerRepository {
4 |
5 | suspend fun addServer(server: Server)
6 |
7 | suspend fun editServer(serverId: Long, server: Server)
8 |
9 | suspend fun getServer(serverId: Long): Server?
10 |
11 | suspend fun hasActiveServer(): Boolean
12 |
13 | suspend fun testServer(server: Server)
14 | }
--------------------------------------------------------------------------------
/feature/server/create/src/commonMain/kotlin/ru/stersh/youamp/feature/server/create/ui/ServerCreateStateUi.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.server.create.ui
2 |
3 | internal data class ServerCreateStateUi(
4 | val serverInfo: ServerInfoUi = ServerInfoUi(),
5 | val progress: Boolean = true,
6 | val closeAvailable: Boolean = false,
7 | val buttonsEnabled: Boolean = false
8 | )
9 |
10 | internal data class ServerInfoUi(
11 | val name: String = "",
12 | val url: String = "http://",
13 | val username: String = "",
14 | val password: String = "",
15 | val useLegacyAuth: Boolean = false
16 | ) {
17 | val isValid: Boolean = name.isNotEmpty() && url.isNotEmpty() && username.isNotEmpty() && password.isNotEmpty()
18 | }
--------------------------------------------------------------------------------
/feature/server/create/src/commonMain/kotlin/ru/stersh/youamp/feature/server/create/ui/ServerInputUi.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.server.create.ui
2 |
3 | internal data class ServerInputUi(
4 | val name: String,
5 | val url: String,
6 | val username: String,
7 | val password: String
8 | ) {
9 | val isValid: Boolean = name.isNotEmpty() && url.isNotEmpty() && username.isNotEmpty() && password.isNotEmpty()
10 | }
--------------------------------------------------------------------------------
/feature/server/create/src/commonMain/kotlin/ru/stersh/youamp/feature/server/create/ui/ServerTestResultUi.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.server.create.ui
2 |
3 | internal enum class ServerTestResultUi {
4 | Success, Error
5 | }
--------------------------------------------------------------------------------
/feature/server/create/src/commonMain/kotlin/ru/stersh/youamp/feature/server/create/ui/ServerUi.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.server.create.ui
2 |
3 | internal data class ServerUi(
4 | val name: String,
5 | val url: String,
6 | val username: String,
7 | val password: String,
8 | val useLegacyAuth: Boolean
9 | )
10 |
--------------------------------------------------------------------------------
/feature/server/list/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/server/list/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Servidors
4 | Afegeix
5 | Activa
6 | Edita
7 | Suprimeix
8 |
9 |
--------------------------------------------------------------------------------
/feature/server/list/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Server
4 | Hinzufügen
5 | Aktivieren
6 | Bearbeiten
7 | Löschen
8 |
9 |
--------------------------------------------------------------------------------
/feature/server/list/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Serveurs
4 | Ajouter
5 | Activer
6 | Éditer
7 | Supprimer
8 |
9 |
--------------------------------------------------------------------------------
/feature/server/list/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Server
4 | Aggiungi
5 | Attiva
6 | Modifica
7 | Elimina
8 |
9 |
--------------------------------------------------------------------------------
/feature/server/list/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Servidores
4 | Adicionar
5 | Ativar
6 | Editar
7 | Apagar
8 |
9 |
--------------------------------------------------------------------------------
/feature/server/list/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Серверы
4 | Добавить
5 | Активировать
6 | Изменить
7 | Удалить
8 |
9 |
--------------------------------------------------------------------------------
/feature/server/list/src/commonMain/composeResources/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 服务器
4 | 添加
5 | 激活
6 | 编辑
7 | 删除
8 |
9 |
--------------------------------------------------------------------------------
/feature/server/list/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Servers
4 | Add
5 | Activate
6 | Edit
7 | Delete
8 |
--------------------------------------------------------------------------------
/feature/server/list/src/commonMain/kotlin/ru/stersh/youamp/feature/server/list/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.server.list
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.server.list.data.ServerListRepositoryImpl
6 | import ru.stersh.youamp.feature.server.list.domain.ServerListRepository
7 | import ru.stersh.youamp.feature.server.list.ui.ServerListViewModel
8 |
9 | val serverListModule = module {
10 | single { ServerListRepositoryImpl(get()) }
11 | viewModel { ServerListViewModel(get()) }
12 | }
--------------------------------------------------------------------------------
/feature/server/list/src/commonMain/kotlin/ru/stersh/youamp/feature/server/list/domain/Server.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.server.list.domain
2 |
3 | internal data class Server(
4 | val id: Long,
5 | val title: String,
6 | val url: String,
7 | val isActive: Boolean
8 | )
9 |
--------------------------------------------------------------------------------
/feature/server/list/src/commonMain/kotlin/ru/stersh/youamp/feature/server/list/domain/ServerListRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.server.list.domain
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | internal interface ServerListRepository {
6 |
7 | fun getServerList(): Flow>
8 |
9 | suspend fun setActiveServer(serverId: Long)
10 |
11 | suspend fun deleteServer(serverId: Long)
12 | }
--------------------------------------------------------------------------------
/feature/server/list/src/commonMain/kotlin/ru/stersh/youamp/feature/server/list/ui/Mapper.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.server.list.ui
2 |
3 | import ru.stersh.youamp.feature.server.list.domain.Server
4 |
5 | internal fun Server.toUi(): ServerUi {
6 | return ServerUi(
7 | id = id,
8 | title = title,
9 | url = url,
10 | isActive = isActive
11 | )
12 | }
--------------------------------------------------------------------------------
/feature/server/list/src/commonMain/kotlin/ru/stersh/youamp/feature/server/list/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.server.list.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 | import kotlinx.collections.immutable.persistentListOf
5 |
6 | internal data class StateUi(
7 | val progress: Boolean = true,
8 | val items: ImmutableList = persistentListOf()
9 | )
10 |
11 | internal data class ServerUi(
12 | val id: Long,
13 | val title: String,
14 | val url: String,
15 | val isActive: Boolean
16 | )
17 |
--------------------------------------------------------------------------------
/feature/settings/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/settings/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Quant a…
4 | Informació de l\'aplicació, enllaços de retroalimentació
5 | Servidors
6 | Gestioneu els vostres servidors Subsonic
7 | Icona quant a…
8 | Icona dels servidors
9 | Paràmetres
10 |
11 |
--------------------------------------------------------------------------------
/feature/settings/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Über
4 | App-Infos, Feedbacklinks
5 | Server
6 | Subsonic-Server verwalten
7 | Über Icon
8 | Server Icon
9 | Einstellungen
10 |
11 |
--------------------------------------------------------------------------------
/feature/settings/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | A propos
4 | Infos sur l’application, liens vers les commentaires
5 | Serveurs
6 | Gérer vos serveurs Subsonic
7 | Icône À propos
8 | Icône des serveurs
9 | Options
10 |
11 |
--------------------------------------------------------------------------------
/feature/settings/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Info
4 | Info app, link di feedback
5 | Server
6 | Gestisci i tuoi server Subsonic
7 | Icona d\'informazioni
8 | Icona del server
9 | Impostazioni
10 |
11 |
--------------------------------------------------------------------------------
/feature/settings/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Sobre
4 | Informações do aplicativo, links de feedback
5 | Servidores
6 | Gerenciar seus servidores subsónicos
7 | Sobre o ícone
8 | Ícone do servidor
9 | Configurações
10 |
11 |
--------------------------------------------------------------------------------
/feature/settings/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | О приложении
4 | Информация о приложении, обратная связь
5 | Серверы
6 | Управление вашими серверами Subsonic
7 | Иконка о приложении
8 | Иконка серверов
9 | Настройки
10 |
11 |
--------------------------------------------------------------------------------
/feature/settings/src/commonMain/composeResources/values-ru/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | О приложении
4 | Информация о приложенни, обратная связь
5 | Серверы
6 | Управления вашими серверами Subsonic
7 | Иконка о приложении
8 | Иконка серверов
9 | Настройки
10 |
--------------------------------------------------------------------------------
/feature/settings/src/commonMain/composeResources/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 关于
4 | 应用程序信息,反馈链接
5 | 服务器
6 | 管理你的 Subsonic 服务器
7 | 关于图标
8 | 服务器图标
9 | 设置
10 |
11 |
--------------------------------------------------------------------------------
/feature/settings/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | About
4 | App info, feedback links
5 | Servers
6 | Manage you Subsonic servers
7 | About icon
8 | Servers icon
9 | Settings
10 |
--------------------------------------------------------------------------------
/feature/song/favorites/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/song/favorites/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Cançons preferides
4 |
5 |
--------------------------------------------------------------------------------
/feature/song/favorites/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Lieblingslieder
4 |
5 |
--------------------------------------------------------------------------------
/feature/song/favorites/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Chansons favorites
4 |
5 |
--------------------------------------------------------------------------------
/feature/song/favorites/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Canzoni preferite
4 |
5 |
--------------------------------------------------------------------------------
/feature/song/favorites/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Músicas favoritas
4 |
5 |
--------------------------------------------------------------------------------
/feature/song/favorites/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Избранные песни
4 |
5 |
--------------------------------------------------------------------------------
/feature/song/favorites/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Favorite songs
4 |
--------------------------------------------------------------------------------
/feature/song/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/song/favorites/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.song.favorites
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.song.favorites.data.FavoriteSongsRepositoryImpl
6 | import ru.stersh.youamp.feature.song.favorites.domain.FavoriteSongsRepository
7 | import ru.stersh.youamp.feature.song.favorites.ui.FavoriteSongsViewModel
8 |
9 | val songFavoritesModule = module {
10 | single { FavoriteSongsRepositoryImpl(get()) }
11 | viewModel { FavoriteSongsViewModel(get(), get()) }
12 | }
--------------------------------------------------------------------------------
/feature/song/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/song/favorites/domain/FavoriteSongsRepository.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.song.favorites.domain
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | internal interface FavoriteSongsRepository {
6 | fun getFavorites(): Flow
7 | }
--------------------------------------------------------------------------------
/feature/song/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/song/favorites/domain/Favorites.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.song.favorites.domain
2 |
3 | internal data class Favorites(
4 | val songs: List
5 | )
6 |
--------------------------------------------------------------------------------
/feature/song/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/song/favorites/domain/Song.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.song.favorites.domain
2 |
3 | internal data class Song(
4 | val id: String,
5 | val title: String,
6 | val artist: String?,
7 | val album: String?,
8 | val artworkUrl: String?,
9 | val userRating: Int?
10 | )
11 |
--------------------------------------------------------------------------------
/feature/song/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/song/favorites/ui/Mapper.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.song.favorites.ui
2 |
3 | import kotlinx.collections.immutable.toPersistentList
4 | import ru.stersh.youamp.feature.song.favorites.domain.Favorites
5 | import ru.stersh.youamp.feature.song.favorites.domain.Song
6 |
7 | internal fun Favorites.toUi(): DataUi {
8 | return DataUi(
9 | songs = songs
10 | .map { it.toUi() }
11 | .toPersistentList()
12 | )
13 | }
14 |
15 | private fun Song.toUi() = SongUi(
16 | id = id,
17 | title = title,
18 | artist = artist,
19 | artworkUrl = artworkUrl
20 | )
--------------------------------------------------------------------------------
/feature/song/favorites/src/commonMain/kotlin/ru/stersh/youamp/feature/song/favorites/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.song.favorites.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 |
5 | internal data class StateUi(
6 | val progress: Boolean = true,
7 | val isRefreshing: Boolean = false,
8 | val error: Boolean = false,
9 | val data: DataUi? = null
10 | )
11 |
12 | internal data class DataUi(
13 | val songs: ImmutableList
14 | )
15 |
16 | internal class SongUi(
17 | val id: String,
18 | val title: String,
19 | val artist: String?,
20 | val artworkUrl: String?
21 | )
--------------------------------------------------------------------------------
/feature/song/info/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/song/info/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Reprodueix
4 | Reprodueix la següent en la cua
5 | Vés a l\'àlbum
6 | Vés a l\'artista
7 | Afegeix als preferits
8 | Elimina dels preferits
9 |
10 |
--------------------------------------------------------------------------------
/feature/song/info/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Abspielen
4 | Als Nächstes abspielen
5 | Zum Album gehen
6 | Zum Interpreten gehen
7 | Zu Favoriten hinzufügen
8 | Aus Favoriten entfernen
9 |
10 |
--------------------------------------------------------------------------------
/feature/song/info/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Lire
4 | Jouer le suivant dans la file d’attente
5 | Aller à l’album
6 | Aller à l’artiste
7 | Ajouter aux favoris
8 | Supprimer des favoris
9 |
10 |
--------------------------------------------------------------------------------
/feature/song/info/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Riproduci
4 | Riproduci prossimo in coda
5 | Vai all\'album
6 | Vai all\'artista
7 | Aggiungi ai preferiti
8 | Rimuovi dai preferiti
9 |
10 |
--------------------------------------------------------------------------------
/feature/song/info/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Reproduzir
4 | Adicionar à fila
5 | Adicionar à fila por último
6 | Ir para o álbum
7 | Ir para o artista
8 | Adicionar aos favoritos
9 | Remover dos favoritos
10 |
11 |
--------------------------------------------------------------------------------
/feature/song/info/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Играть
4 | Добавить следующей в очереди
5 | Добавить последней в очереди
6 | Перейти к альбому
7 | Перейти к исполнителю
8 | Добавить в избранное
9 | Удалить из избранного
10 |
11 |
--------------------------------------------------------------------------------
/feature/song/info/src/commonMain/composeResources/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 播放
4 | 播放队列中的下一个
5 | 查看专辑
6 | 查看艺人
7 |
8 |
--------------------------------------------------------------------------------
/feature/song/info/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Play
4 | Add to queue next
5 | Add to queue last
6 | Go to album
7 | Go to artist
8 | Add to favorites
9 | Remove from favorites
10 |
--------------------------------------------------------------------------------
/feature/song/info/src/commonMain/kotlin/ru/stersh/youamp/feature/song/info/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.song.info
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.song.info.ui.SongInfoViewModel
6 |
7 | val songInfoModule = module {
8 | viewModel { SongInfoViewModel(get(), get(), get()) }
9 | }
--------------------------------------------------------------------------------
/feature/song/info/src/commonMain/kotlin/ru/stersh/youamp/feature/song/info/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.song.info.ui
2 |
3 | import androidx.compose.runtime.Immutable
4 |
5 | @Immutable
6 | internal data class State(
7 | val title: String? = null,
8 | val artist: String? = null,
9 | val artistId: String? = null,
10 | val albumId: String? = null,
11 | val artworkUrl: String? = null,
12 | val showAlbum: Boolean = false,
13 | val favorite: Boolean = false,
14 | val progress: Boolean = true,
15 | val error: Boolean = false,
16 | )
17 |
--------------------------------------------------------------------------------
/feature/song/random/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/feature/song/random/src/commonMain/composeResources/values-ca-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Cançons aleatòries
4 |
5 |
--------------------------------------------------------------------------------
/feature/song/random/src/commonMain/composeResources/values-de-rDE/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Zufällige Lieder
4 |
5 |
--------------------------------------------------------------------------------
/feature/song/random/src/commonMain/composeResources/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Chansons aléatoires
4 |
5 |
--------------------------------------------------------------------------------
/feature/song/random/src/commonMain/composeResources/values-it-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Brani casuali
4 |
5 |
--------------------------------------------------------------------------------
/feature/song/random/src/commonMain/composeResources/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Músicas aleatórias
4 |
5 |
--------------------------------------------------------------------------------
/feature/song/random/src/commonMain/composeResources/values-ru-rRU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Случайные песни
4 |
5 |
--------------------------------------------------------------------------------
/feature/song/random/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Random songs
4 |
--------------------------------------------------------------------------------
/feature/song/random/src/commonMain/kotlin/ru/stersh/youamp/feature/song/random/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.song.random
2 |
3 | import org.koin.core.module.dsl.viewModel
4 | import org.koin.dsl.module
5 | import ru.stersh.youamp.feature.song.random.ui.RandomSongsViewModel
6 |
7 | val songRandomModule = module {
8 | viewModel { RandomSongsViewModel(get(), get()) }
9 | }
--------------------------------------------------------------------------------
/feature/song/random/src/commonMain/kotlin/ru/stersh/youamp/feature/song/random/ui/Mapper.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.song.random.ui
2 |
3 | import kotlinx.collections.immutable.toPersistentList
4 | import ru.stersh.youamp.shared.song.random.Song
5 |
6 | internal fun List.toUi(): DataUi {
7 | return DataUi(
8 | songs = map { it.toUi() }.toPersistentList()
9 | )
10 | }
11 |
12 | private fun Song.toUi() = SongUi(
13 | id = id,
14 | title = title,
15 | artist = artist,
16 | artworkUrl = artworkUrl
17 | )
--------------------------------------------------------------------------------
/feature/song/random/src/commonMain/kotlin/ru/stersh/youamp/feature/song/random/ui/State.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.feature.song.random.ui
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 |
5 | internal data class StateUi(
6 | val progress: Boolean = true,
7 | val isRefreshing: Boolean = false,
8 | val error: Boolean = false,
9 | val data: DataUi? = null
10 | )
11 |
12 | internal data class DataUi(
13 | val songs: ImmutableList
14 | )
15 |
16 | internal class SongUi(
17 | val id: String,
18 | val title: String,
19 | val artist: String?,
20 | val artworkUrl: String?
21 | )
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/siper/Youamp/4e03e6f9ca5133f9727d62f83e19b4ec36f50444/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Mar 22 12:07:24 MSK 2025
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/shared/favorites/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/shared/favorites/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.kotlin.multiplatform)
3 | alias(libs.plugins.android.kotlinMultiplatformLibrary)
4 | }
5 |
6 | kotlin {
7 |
8 | androidLibrary {
9 | namespace = "ru.stersh.youamp.shared.favorites"
10 | compileSdk = libs.versions.android.compileSdk.get().toInt()
11 | minSdk = libs.versions.android.minSdk.get().toInt()
12 | }
13 |
14 | jvm("desktop")
15 |
16 | sourceSets {
17 | commonMain {
18 | dependencies {
19 | implementation(libs.koin.core)
20 | implementation(libs.kotlin.coroutines.core)
21 | implementation(project(":core:api"))
22 | }
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/shared/favorites/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/shared/favorites/src/commonMain/kotlin/ru/stersh/youamp/shared/favorites/Album.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.favorites
2 |
3 | data class Album(
4 | val id: String,
5 | val title: String,
6 | val artist: String?,
7 | val artistId: String?,
8 | val artworkUrl: String?,
9 | val userRating: Int?
10 | )
11 |
--------------------------------------------------------------------------------
/shared/favorites/src/commonMain/kotlin/ru/stersh/youamp/shared/favorites/AlbumFavoritesStorage.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.favorites
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | interface AlbumFavoritesStorage {
6 |
7 | fun flowAlbums(): Flow>
8 |
9 | suspend fun getAlbums(): List
10 |
11 | suspend fun setAlbumFavorite(id: String, isFavorite: Boolean)
12 | }
--------------------------------------------------------------------------------
/shared/favorites/src/commonMain/kotlin/ru/stersh/youamp/shared/favorites/Artist.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.favorites
2 |
3 | data class Artist(
4 | val id: String,
5 | val name: String,
6 | val artworkUrl: String?,
7 | val userRating: Int?
8 | )
--------------------------------------------------------------------------------
/shared/favorites/src/commonMain/kotlin/ru/stersh/youamp/shared/favorites/ArtistFavoritesStorage.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.favorites
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | interface ArtistFavoritesStorage {
6 |
7 | fun flowArtists(): Flow>
8 |
9 | suspend fun getArtists(): List
10 |
11 | suspend fun setArtistFavorite(id: String, isFavorite: Boolean)
12 | }
--------------------------------------------------------------------------------
/shared/favorites/src/commonMain/kotlin/ru/stersh/youamp/shared/favorites/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.favorites
2 |
3 | import org.koin.dsl.binds
4 | import org.koin.dsl.module
5 |
6 | val favoritesSharedModule = module {
7 | single { FavoritesStorageImpl(get()) } binds arrayOf(
8 | SongFavoritesStorage::class,
9 | AlbumFavoritesStorage::class,
10 | ArtistFavoritesStorage::class
11 | )
12 | }
--------------------------------------------------------------------------------
/shared/favorites/src/commonMain/kotlin/ru/stersh/youamp/shared/favorites/Song.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.favorites
2 |
3 | data class Song(
4 | val id: String,
5 | val title: String,
6 | val album: String?,
7 | val albumId: String?,
8 | val artist: String?,
9 | val artistId: String?,
10 | val artworkUrl: String?,
11 | val userRating: Int?
12 | )
--------------------------------------------------------------------------------
/shared/favorites/src/commonMain/kotlin/ru/stersh/youamp/shared/favorites/SongFavoritesStorage.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.favorites
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | interface SongFavoritesStorage {
6 |
7 | fun flowSongs(): Flow>
8 |
9 | suspend fun getSongs(): List
10 |
11 | suspend fun setSongFavorite(id: String, isFavorite: Boolean)
12 | }
--------------------------------------------------------------------------------
/shared/queue/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/shared/queue/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.kotlin.multiplatform)
3 | alias(libs.plugins.android.kotlinMultiplatformLibrary)
4 | }
5 |
6 | kotlin {
7 |
8 | androidLibrary {
9 | namespace = "ru.stresh.youamp.shared.queue"
10 | compileSdk = libs.versions.android.compileSdk.get().toInt()
11 | minSdk = libs.versions.android.minSdk.get().toInt()
12 | }
13 |
14 | jvm("desktop")
15 |
16 | sourceSets {
17 | commonMain {
18 | dependencies {
19 | implementation(libs.koin.core)
20 | implementation(libs.kotlin.coroutines.core)
21 | implementation(project(":core:player"))
22 | implementation(project(":core:api"))
23 | }
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/shared/queue/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/shared/queue/src/commonMain/kotlin/ru/stersh/youamp/shared/queue/AudioSource.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.queue
2 |
3 | sealed class AudioSource(open val id: String) {
4 |
5 | data class Song(override val id: String) : AudioSource(id)
6 |
7 | data class Album(
8 | override val id: String,
9 | val songId: String? = null
10 | ) : AudioSource(id)
11 |
12 | data class Artist(override val id: String) : AudioSource(id)
13 |
14 | data class Playlist(
15 | override val id: String,
16 | val songId: String? = null
17 | ) : AudioSource(id)
18 |
19 | data class RawSong(
20 | override val id: String,
21 | val title: String?,
22 | val artist: String?,
23 | val album: String?,
24 | val artworkUrl: String?
25 | ) : AudioSource(id)
26 | }
27 |
--------------------------------------------------------------------------------
/shared/queue/src/commonMain/kotlin/ru/stersh/youamp/shared/queue/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.queue
2 |
3 | import org.koin.dsl.module
4 |
5 | val queueSharedModule = module {
6 | single { PlayerQueueAudioSourceManagerImpl(get(), get()) }
7 | }
8 |
--------------------------------------------------------------------------------
/shared/queue/src/commonMain/kotlin/ru/stersh/youamp/shared/queue/Mapper.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.queue
2 |
3 | import ru.stersh.subsonic.api.model.Song
4 | import ru.stersh.youamp.core.api.ApiProvider
5 |
6 | suspend fun Song.toMediaItem(apiProvider: ApiProvider): ru.stersh.youamp.core.player.MediaItem {
7 | val songUri = apiProvider
8 | .getApi()
9 | .streamUrl(id)
10 |
11 | val artworkUri = apiProvider
12 | .getApi()
13 | .getCoverArtUrl(coverArt, auth = true)
14 |
15 | return ru.stersh.youamp.core.player.MediaItem(
16 | id = id,
17 | title = title,
18 | url = songUri,
19 | artist = artist,
20 | album = album,
21 | artworkUrl = artworkUri
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/shared/queue/src/commonMain/kotlin/ru/stersh/youamp/shared/queue/PlayerQueueAudioSourceManager.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.queue
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | interface PlayerQueueAudioSourceManager {
6 | fun playingSource(): Flow
7 | suspend fun playSource(vararg source: AudioSource, shuffled: Boolean = false)
8 | suspend fun addLast(vararg source: AudioSource, shuffled: Boolean = false)
9 | suspend fun addNext(vararg source: AudioSource, shuffled: Boolean = false)
10 | }
11 |
--------------------------------------------------------------------------------
/shared/song/random/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/shared/song/random/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.kotlin.multiplatform)
3 | alias(libs.plugins.android.kotlinMultiplatformLibrary)
4 | }
5 |
6 | kotlin {
7 |
8 | androidLibrary {
9 | namespace = "ru.stersh.youamp.shared.song.random"
10 | compileSdk = libs.versions.android.compileSdk.get().toInt()
11 | minSdk = libs.versions.android.minSdk.get().toInt()
12 | }
13 |
14 | jvm("desktop")
15 |
16 | sourceSets {
17 | commonMain {
18 | dependencies {
19 | implementation(libs.koin.core)
20 | implementation(libs.kotlin.coroutines.core)
21 | implementation(project(":core:api"))
22 | }
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/shared/song/random/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/shared/song/random/src/commonMain/kotlin/ru/stersh/youamp/shared/song/random/Di.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.song.random
2 |
3 | import org.koin.dsl.module
4 |
5 | val songRandomSharedModule = module {
6 | single { SongRandomStorageImpl(get()) }
7 | }
--------------------------------------------------------------------------------
/shared/song/random/src/commonMain/kotlin/ru/stersh/youamp/shared/song/random/RandomSongs.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.song.random
2 |
3 | import kotlinx.coroutines.flow.Flow
4 | import kotlinx.coroutines.flow.MutableStateFlow
5 | import kotlinx.coroutines.flow.filter
6 | import kotlinx.coroutines.flow.flatMapLatest
7 | import kotlinx.coroutines.flow.update
8 |
9 | internal class RandomSongs {
10 |
11 | private val needFetch = MutableStateFlow(true)
12 |
13 | private val songs = MutableStateFlow>(emptyList())
14 |
15 | val needFetchData: Boolean
16 | get() = needFetch.value
17 |
18 | fun songs(): Flow> {
19 | return needFetch
20 | .filter { !it }
21 | .flatMapLatest { songs }
22 | }
23 |
24 | fun update(
25 | songs: List
26 | ) {
27 | this.songs.update { songs }
28 | needFetch.update { false }
29 | }
30 | }
--------------------------------------------------------------------------------
/shared/song/random/src/commonMain/kotlin/ru/stersh/youamp/shared/song/random/Song.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.song.random
2 |
3 | data class Song(
4 | val id: String,
5 | val title: String,
6 | val album: String?,
7 | val albumId: String?,
8 | val artist: String?,
9 | val artistId: String?,
10 | val artworkUrl: String?,
11 | )
--------------------------------------------------------------------------------
/shared/song/random/src/commonMain/kotlin/ru/stersh/youamp/shared/song/random/SongRandomStorage.kt:
--------------------------------------------------------------------------------
1 | package ru.stersh.youamp.shared.song.random
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | interface SongRandomStorage {
6 |
7 | fun flowSongs(): Flow>
8 |
9 | suspend fun getSongs(): List
10 |
11 | suspend fun refresh()
12 | }
--------------------------------------------------------------------------------