├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yaml │ ├── config.yml │ └── feature_request.yaml ├── delete_success_workflows.sh ├── dependabot.yml ├── get_developers.py └── workflows │ ├── build-all-flavors-weekly.yml │ ├── cache-builder.yaml │ ├── close-issues-on-release.yaml │ ├── comment-on-label.yaml │ ├── house-keeper.yaml │ ├── sync-crowdin-translations.yaml │ └── weekly-update-contributors.yaml ├── .gitignore ├── .gitmodules ├── .kotlin └── metadata │ └── kotlinTransformedMetadataLibraries │ └── org.jetbrains.kotlin-kotlin-stdlib-2.0.20-commonMain-WPEnbA.klib ├── LICENSE ├── README.md ├── assets ├── design │ ├── app_banner.png │ ├── ic_launcher_background.svg │ ├── ic_launcher_foreground.svg │ └── ic_launcher_monochrome.svg └── get-it-on │ ├── Accrescent.png │ ├── AndroidFreeware.png │ ├── F-Droid.png │ ├── GitHub.png │ ├── IzzyOnDroid.png │ ├── Obtainium.png │ └── OpenAPK.png ├── build.gradle.kts ├── composeApp ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro ├── schemas │ ├── database.MusicDatabase │ │ └── 23.json │ ├── database.MusicDatabaseConstructor │ │ └── 23.json │ └── it.fast4x.rimusic.DatabaseInitializer │ │ ├── 1.json │ │ ├── 10.json │ │ ├── 11.json │ │ ├── 12.json │ │ ├── 13.json │ │ ├── 14.json │ │ ├── 15.json │ │ ├── 16.json │ │ ├── 17.json │ │ ├── 18.json │ │ ├── 19.json │ │ ├── 2.json │ │ ├── 20.json │ │ ├── 21.json │ │ ├── 22.json │ │ ├── 23.json │ │ ├── 24.json │ │ ├── 25.json │ │ ├── 26.json │ │ ├── 27.json │ │ ├── 3.json │ │ ├── 4.json │ │ ├── 5.json │ │ ├── 6.json │ │ ├── 7.json │ │ ├── 8.json │ │ └── 9.json └── src │ ├── androidMain │ ├── AndroidManifest.xml │ ├── ic_launcher-playstore.webp │ ├── ic_logo-playstore.webp │ ├── kotlin │ │ ├── app │ │ │ └── kreate │ │ │ │ └── android │ │ │ │ ├── Threads.kt │ │ │ │ ├── constant │ │ │ │ └── Speed.kt │ │ │ │ ├── drawable │ │ │ │ └── AppIcon.kt │ │ │ │ ├── network │ │ │ │ └── innertube │ │ │ │ │ └── Store.kt │ │ │ │ ├── screens │ │ │ │ ├── artist │ │ │ │ │ └── ArtistDetails.kt │ │ │ │ └── player │ │ │ │ │ └── background │ │ │ │ │ └── BlurredCover.kt │ │ │ │ ├── service │ │ │ │ └── DataspecServices.kt │ │ │ │ ├── themed │ │ │ │ └── rimusic │ │ │ │ │ └── screen │ │ │ │ │ ├── artist │ │ │ │ │ └── ArtistAlbums.kt │ │ │ │ │ ├── home │ │ │ │ │ ├── HomeSongs.kt │ │ │ │ │ ├── HomeSongsScreen.kt │ │ │ │ │ └── onDevice │ │ │ │ │ │ └── OnDeviceSongs.kt │ │ │ │ │ └── player │ │ │ │ │ ├── ActionBar.kt │ │ │ │ │ └── timeline │ │ │ │ │ └── DurationIndicator.kt │ │ │ │ ├── utils │ │ │ │ └── CharUtils.kt │ │ │ │ └── widget │ │ │ │ ├── Widget.kt │ │ │ │ └── WidgetReceiver.kt │ │ ├── database │ │ │ └── getMusicDatabase.kt │ │ ├── it │ │ │ └── fast4x │ │ │ │ ├── compose │ │ │ │ ├── persist │ │ │ │ │ ├── Persist.kt │ │ │ │ │ ├── PersistMap.kt │ │ │ │ │ ├── PersistMapCleanup.kt │ │ │ │ │ ├── PersistMapOwner.kt │ │ │ │ │ └── Utils.kt │ │ │ │ └── reordering │ │ │ │ │ ├── AnimatablesPool.kt │ │ │ │ │ ├── AnimateItemPlacement.kt │ │ │ │ │ ├── DraggedItem.kt │ │ │ │ │ ├── Reorder.kt │ │ │ │ │ └── ReorderingState.kt │ │ │ │ └── rimusic │ │ │ │ ├── Database.kt │ │ │ │ ├── GlobalVars.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── MainApplication.kt │ │ │ │ ├── Platform.android.kt │ │ │ │ ├── enums │ │ │ │ ├── AlbumSortBy.kt │ │ │ │ ├── AlbumSwipeAction.kt │ │ │ │ ├── AlbumsType.kt │ │ │ │ ├── AnimatedGradient.kt │ │ │ │ ├── ArtistSortBy.kt │ │ │ │ ├── ArtistsType.kt │ │ │ │ ├── AudioQualityFormat.kt │ │ │ │ ├── BackgroundProgress.kt │ │ │ │ ├── BuiltInPlaylist.kt │ │ │ │ ├── ButtonState.kt │ │ │ │ ├── CacheType.kt │ │ │ │ ├── CarousalSize.kt │ │ │ │ ├── CheckUpdateState.kt │ │ │ │ ├── ClickLyricsText.kt │ │ │ │ ├── CoilDiskCacheSize.kt │ │ │ │ ├── ColorPaletteMode.kt │ │ │ │ ├── ColorPaletteName.kt │ │ │ │ ├── DeviceLists.kt │ │ │ │ ├── DownloadedStateMedia.kt │ │ │ │ ├── DragAnchors.kt │ │ │ │ ├── Drawable.kt │ │ │ │ ├── Durations.kt │ │ │ │ ├── ExoPlayerCacheLocation.kt │ │ │ │ ├── ExoPlayerDiskCacheMaxSize.kt │ │ │ │ ├── ExoPlayerDiskDownloadCacheMaxSize.kt │ │ │ │ ├── ExoPlayerMinTimeForEvent.kt │ │ │ │ ├── FilterBy.kt │ │ │ │ ├── FontType.kt │ │ │ │ ├── HistoryType.kt │ │ │ │ ├── HomeItemSize.kt │ │ │ │ ├── HomeScreenTabs.kt │ │ │ │ ├── IconsLikeType.kt │ │ │ │ ├── LandscapeLayout.kt │ │ │ │ ├── LibraryItemSize.kt │ │ │ │ ├── Locales.kt │ │ │ │ ├── LogType.kt │ │ │ │ ├── LyricsAlignment.kt │ │ │ │ ├── LyricsBackground.kt │ │ │ │ ├── LyricsColor.kt │ │ │ │ ├── LyricsFontSize.kt │ │ │ │ ├── LyricsHighlight.kt │ │ │ │ ├── LyricsOutline.kt │ │ │ │ ├── MaxSongs.kt │ │ │ │ ├── MaxStatisticsItems.kt │ │ │ │ ├── MenuStyle.kt │ │ │ │ ├── MessageType.kt │ │ │ │ ├── MiniPlayerType.kt │ │ │ │ ├── MoodType.kt │ │ │ │ ├── MusicAnimationType.kt │ │ │ │ ├── NavRoutes.kt │ │ │ │ ├── NavigationBarPosition.kt │ │ │ │ ├── NavigationBarType.kt │ │ │ │ ├── NotificationButtons.kt │ │ │ │ ├── NotificationType.kt │ │ │ │ ├── OnDeviceFolderSortBy.kt │ │ │ │ ├── OnDeviceSongSortBy.kt │ │ │ │ ├── PauseBetweenSongs.kt │ │ │ │ ├── PipModule.kt │ │ │ │ ├── PlayEventsType.kt │ │ │ │ ├── PlayerBackgroundColors.kt │ │ │ │ ├── PlayerControlsType.kt │ │ │ │ ├── PlayerInfoType.kt │ │ │ │ ├── PlayerPlayButtonType.kt │ │ │ │ ├── PlayerPosition.kt │ │ │ │ ├── PlayerThumbnailSize.kt │ │ │ │ ├── PlayerTimelineSize.kt │ │ │ │ ├── PlayerTimelineType.kt │ │ │ │ ├── PlayerType.kt │ │ │ │ ├── PlaylistSongSortBy.kt │ │ │ │ ├── PlaylistSongsTypeFilter.kt │ │ │ │ ├── PlaylistSortBy.kt │ │ │ │ ├── PlaylistSwipeAction.kt │ │ │ │ ├── PlaylistsType.kt │ │ │ │ ├── PopupType.kt │ │ │ │ ├── PresetReverb.kt │ │ │ │ ├── PrevNextSongs.kt │ │ │ │ ├── QueueLoopType.kt │ │ │ │ ├── QueueSelection.kt │ │ │ │ ├── QueueSwipeAction.kt │ │ │ │ ├── QueueType.kt │ │ │ │ ├── RecommendationsNumber.kt │ │ │ │ ├── Romanization.kt │ │ │ │ ├── SearchType.kt │ │ │ │ ├── SongSortBy.kt │ │ │ │ ├── SongsNumber.kt │ │ │ │ ├── SortOrder.kt │ │ │ │ ├── Statistics.kt │ │ │ │ ├── SwipeAnimations.kt │ │ │ │ ├── ThumbnailCoverType.kt │ │ │ │ ├── ThumbnailRoundness.kt │ │ │ │ ├── ThumbnailType.kt │ │ │ │ ├── TopPlaylistItems.kt │ │ │ │ ├── TransitionEffect.kt │ │ │ │ ├── UiType.kt │ │ │ │ ├── ValidationType.kt │ │ │ │ ├── WallpaperType.kt │ │ │ │ └── playerVisualizerType.kt │ │ │ │ ├── extensions │ │ │ │ ├── audiovolume │ │ │ │ │ ├── AudioVolumeContentObserver.kt │ │ │ │ │ ├── AudioVolumeObserver.kt │ │ │ │ │ └── OnAudioVolumeChangedListener.kt │ │ │ │ ├── connectivity │ │ │ │ │ ├── AndroidConnectivityObserver.kt │ │ │ │ │ ├── AndroidConnectivityObserverLegacy.kt │ │ │ │ │ └── ConnectivityObserver.kt │ │ │ │ ├── contributors │ │ │ │ │ ├── Contributors.kt │ │ │ │ │ └── models │ │ │ │ │ │ ├── Developer.kt │ │ │ │ │ │ └── Translator.kt │ │ │ │ ├── discord │ │ │ │ │ └── Discord.kt │ │ │ │ ├── games │ │ │ │ │ ├── pacman │ │ │ │ │ │ ├── GameViewModel.kt │ │ │ │ │ │ ├── Pacman.kt │ │ │ │ │ │ ├── models │ │ │ │ │ │ │ ├── DialogState.kt │ │ │ │ │ │ │ ├── EnemyMovementModel.kt │ │ │ │ │ │ │ ├── GameStatsModel.kt │ │ │ │ │ │ │ └── PacFood.kt │ │ │ │ │ │ ├── ui │ │ │ │ │ │ │ ├── GameComposables.kt │ │ │ │ │ │ │ └── theme │ │ │ │ │ │ │ │ ├── Color.kt │ │ │ │ │ │ │ │ ├── Shape.kt │ │ │ │ │ │ │ │ ├── Theme.kt │ │ │ │ │ │ │ │ └── Type.kt │ │ │ │ │ │ └── utils │ │ │ │ │ │ │ └── GameConstants.kt │ │ │ │ │ └── snake │ │ │ │ │ │ └── Snake.kt │ │ │ │ ├── nextvisualizer │ │ │ │ │ ├── NextVisualizer.kt │ │ │ │ │ ├── painters │ │ │ │ │ │ ├── Painter.kt │ │ │ │ │ │ ├── fft │ │ │ │ │ │ │ ├── FftAnalog.kt │ │ │ │ │ │ │ ├── FftBar.kt │ │ │ │ │ │ │ ├── FftCBar.kt │ │ │ │ │ │ │ ├── FftCLine.kt │ │ │ │ │ │ │ ├── FftCPoly.kt │ │ │ │ │ │ │ ├── FftCWave.kt │ │ │ │ │ │ │ ├── FftCWaveRgb.kt │ │ │ │ │ │ │ ├── FftLine.kt │ │ │ │ │ │ │ ├── FftPoly.kt │ │ │ │ │ │ │ ├── FftWave.kt │ │ │ │ │ │ │ └── FftWaveRgb.kt │ │ │ │ │ │ ├── misc │ │ │ │ │ │ │ ├── Background.kt │ │ │ │ │ │ │ ├── Gradient.kt │ │ │ │ │ │ │ ├── Icon.kt │ │ │ │ │ │ │ └── SimpleText.kt │ │ │ │ │ │ ├── modifier │ │ │ │ │ │ │ ├── Beat.kt │ │ │ │ │ │ │ ├── Blend.kt │ │ │ │ │ │ │ ├── Compose.kt │ │ │ │ │ │ │ ├── Glitch.kt │ │ │ │ │ │ │ ├── Move.kt │ │ │ │ │ │ │ ├── Rotate.kt │ │ │ │ │ │ │ ├── Scale.kt │ │ │ │ │ │ │ ├── Shake.kt │ │ │ │ │ │ │ └── Zoom.kt │ │ │ │ │ │ └── waveform │ │ │ │ │ │ │ └── WfmAnalog.kt │ │ │ │ │ ├── utils │ │ │ │ │ │ ├── FrameManager.kt │ │ │ │ │ │ ├── Preset.kt │ │ │ │ │ │ └── VisualizerHelper.kt │ │ │ │ │ └── views │ │ │ │ │ │ └── VisualizerView.kt │ │ │ │ ├── pip │ │ │ │ │ ├── PictureInPicture.kt │ │ │ │ │ ├── PipEventContainer.kt │ │ │ │ │ ├── PipModuleContainer.kt │ │ │ │ │ └── PipModuleCover.kt │ │ │ │ ├── webpotoken │ │ │ │ │ ├── JavaScriptUtil.kt │ │ │ │ │ ├── PoTokenException.kt │ │ │ │ │ ├── PoTokenGenerator.kt │ │ │ │ │ ├── PoTokenResult.kt │ │ │ │ │ └── PoTokenWebView.kt │ │ │ │ └── youtubelogin │ │ │ │ │ ├── YouTubeLogin.kt │ │ │ │ │ └── YoutubeSession.kt │ │ │ │ ├── models │ │ │ │ ├── Album.kt │ │ │ │ ├── Artist.kt │ │ │ │ ├── Event.kt │ │ │ │ ├── Format.kt │ │ │ │ ├── Info.kt │ │ │ │ ├── Lyrics.kt │ │ │ │ ├── Mood.kt │ │ │ │ ├── PersistentQueue.kt │ │ │ │ ├── PipedSession.kt │ │ │ │ ├── Playlist.kt │ │ │ │ ├── PlaylistPreview.kt │ │ │ │ ├── PlaylistWithSongs.kt │ │ │ │ ├── QueuedMediaItem.kt │ │ │ │ ├── SearchQuery.kt │ │ │ │ ├── Song.kt │ │ │ │ ├── SongAlbumMap.kt │ │ │ │ ├── SongArtistMap.kt │ │ │ │ ├── SongPlaylistMap.kt │ │ │ │ ├── SongWithContentLength.kt │ │ │ │ ├── SortedSongPlaylistMap.kt │ │ │ │ └── ui │ │ │ │ │ └── UiMedia.kt │ │ │ │ ├── service │ │ │ │ ├── BitmapProvider.kt │ │ │ │ ├── MyDownloadHelper.kt │ │ │ │ ├── MyDownloadService.kt │ │ │ │ ├── PlaybackExceptions.kt │ │ │ │ └── modern │ │ │ │ │ ├── MediaLibrarySessionCallback.kt │ │ │ │ │ ├── PlayerServiceModern.kt │ │ │ │ │ └── SleepTimer.kt │ │ │ │ ├── ui │ │ │ │ ├── components │ │ │ │ │ ├── BottomSheet.kt │ │ │ │ │ ├── ButtonsRow.kt │ │ │ │ │ ├── CustomModalBottomSheet.kt │ │ │ │ │ ├── Menu.kt │ │ │ │ │ ├── MultiFloatingActionsButton.kt │ │ │ │ │ ├── MusicAnimations.kt │ │ │ │ │ ├── Scaffold.kt │ │ │ │ │ ├── ScaffoldTB.kt │ │ │ │ │ ├── SeekBar.kt │ │ │ │ │ ├── SeekBarAudioWaves.kt │ │ │ │ │ ├── SeekBarColored.kt │ │ │ │ │ ├── SeekBarCustom.kt │ │ │ │ │ ├── SeekBarWaved.kt │ │ │ │ │ ├── ShimmerHost.kt │ │ │ │ │ ├── Skeleton.kt │ │ │ │ │ ├── SwipeableContent.kt │ │ │ │ │ ├── navigation │ │ │ │ │ │ ├── header │ │ │ │ │ │ │ ├── ActionBar.kt │ │ │ │ │ │ │ ├── AppHeader.kt │ │ │ │ │ │ │ ├── AppTitle.kt │ │ │ │ │ │ │ ├── TabToolBar.kt │ │ │ │ │ │ │ └── Utils.kt │ │ │ │ │ │ └── nav │ │ │ │ │ │ │ ├── AbstractNavigationBar.kt │ │ │ │ │ │ │ ├── HomeNavigation.kt │ │ │ │ │ │ │ ├── HorizontalNavigationBar.kt │ │ │ │ │ │ │ └── VerticalNavigationBar.kt │ │ │ │ │ ├── tab │ │ │ │ │ │ ├── ItemSize.kt │ │ │ │ │ │ ├── TabHeader.kt │ │ │ │ │ │ └── toolbar │ │ │ │ │ │ │ ├── Button.kt │ │ │ │ │ │ │ ├── Clickable.kt │ │ │ │ │ │ │ ├── ConfirmDialog.kt │ │ │ │ │ │ │ ├── Descriptive.kt │ │ │ │ │ │ │ ├── Dialog.kt │ │ │ │ │ │ │ ├── DualIcon.kt │ │ │ │ │ │ │ ├── DynamicColor.kt │ │ │ │ │ │ │ ├── EllipsisMenuComponent.kt │ │ │ │ │ │ │ ├── Icon.kt │ │ │ │ │ │ │ ├── Menu.kt │ │ │ │ │ │ │ ├── MenuIcon.kt │ │ │ │ │ │ │ └── Randomizer.kt │ │ │ │ │ └── themed │ │ │ │ │ │ ├── AlbumsItemGridMenu.kt │ │ │ │ │ │ ├── AlbumsItemMenu.kt │ │ │ │ │ │ ├── AutoResizeText.kt │ │ │ │ │ │ ├── Button.kt │ │ │ │ │ │ ├── ButtonWithTitle.kt │ │ │ │ │ │ ├── CacheSpaceIndicator.kt │ │ │ │ │ │ ├── CircularSlider.kt │ │ │ │ │ │ ├── CrossfadeContainer.kt │ │ │ │ │ │ ├── CustomElevateButton.kt │ │ │ │ │ │ ├── CustomSlider.kt │ │ │ │ │ │ ├── DeleteDialog.kt │ │ │ │ │ │ ├── Dialog.kt │ │ │ │ │ │ ├── DialogColorPicker.kt │ │ │ │ │ │ ├── DialogTextButton.kt │ │ │ │ │ │ ├── DownloadStateIconButton.kt │ │ │ │ │ │ ├── DropdownMenu.kt │ │ │ │ │ │ ├── FloatingActionsContainer.kt │ │ │ │ │ │ ├── FluidGradient.kt │ │ │ │ │ │ ├── GridMenu.kt │ │ │ │ │ │ ├── Header.kt │ │ │ │ │ │ ├── IDialog.kt │ │ │ │ │ │ ├── IconButton.kt │ │ │ │ │ │ ├── IconInfo.kt │ │ │ │ │ │ ├── InputTextField.kt │ │ │ │ │ │ ├── ItemsList.kt │ │ │ │ │ │ ├── LayoutWithAdaptiveThumbnail.kt │ │ │ │ │ │ ├── Loader.kt │ │ │ │ │ │ ├── MediaItemGridMenu.kt │ │ │ │ │ │ ├── MediaItemMenu.kt │ │ │ │ │ │ ├── Menu.kt │ │ │ │ │ │ ├── MenuComponent.kt │ │ │ │ │ │ ├── NowPlaying.kt │ │ │ │ │ │ ├── PlayerMenu.kt │ │ │ │ │ │ ├── Playlist.kt │ │ │ │ │ │ ├── PlaylistsItemGridMenu.kt │ │ │ │ │ │ ├── PlaylistsItemMenu.kt │ │ │ │ │ │ ├── PlaylistsMenu.kt │ │ │ │ │ │ ├── PrimaryButton.kt │ │ │ │ │ │ ├── ProgressIndicator.kt │ │ │ │ │ │ ├── RotateThumbnailCover.kt │ │ │ │ │ │ ├── ScrollText.kt │ │ │ │ │ │ ├── SecondaryButton.kt │ │ │ │ │ │ ├── SecondaryTextButton.kt │ │ │ │ │ │ ├── Slider.kt │ │ │ │ │ │ ├── SliderControl.kt │ │ │ │ │ │ ├── SortMenu.kt │ │ │ │ │ │ ├── Switch.kt │ │ │ │ │ │ ├── TextIconButton.kt │ │ │ │ │ │ ├── TextPlaceholder.kt │ │ │ │ │ │ └── Title.kt │ │ │ │ ├── items │ │ │ │ │ ├── AlbumItem.kt │ │ │ │ │ ├── ArtistItem.kt │ │ │ │ │ ├── ItemContainer.kt │ │ │ │ │ ├── PlaylistItem.kt │ │ │ │ │ ├── SongItem.kt │ │ │ │ │ └── VideoItem.kt │ │ │ │ ├── screens │ │ │ │ │ ├── AppNavigation.kt │ │ │ │ │ ├── album │ │ │ │ │ │ ├── AlbumDetails.kt │ │ │ │ │ │ └── AlbumScreen.kt │ │ │ │ │ ├── artist │ │ │ │ │ │ └── ArtistScreenModern.kt │ │ │ │ │ ├── history │ │ │ │ │ │ ├── HistoryList.kt │ │ │ │ │ │ └── HistoryScreen.kt │ │ │ │ │ ├── home │ │ │ │ │ │ ├── HomeAlbum.kt │ │ │ │ │ │ ├── HomeArtist.kt │ │ │ │ │ │ ├── HomeDiscovery.kt │ │ │ │ │ │ ├── HomeLibrary.kt │ │ │ │ │ │ ├── HomePage.kt │ │ │ │ │ │ ├── HomeQuickPicks.kt │ │ │ │ │ │ ├── HomeScreen.kt │ │ │ │ │ │ ├── HomeSearch.kt │ │ │ │ │ │ └── HomeStatistics.kt │ │ │ │ │ ├── localplaylist │ │ │ │ │ │ ├── LocalPlaylistScreen.kt │ │ │ │ │ │ └── LocalPlaylistSongs.kt │ │ │ │ │ ├── mood │ │ │ │ │ │ ├── MoodList.kt │ │ │ │ │ │ ├── MoodScreen.kt │ │ │ │ │ │ ├── MoodsPage.kt │ │ │ │ │ │ └── MoodsPageScreen.kt │ │ │ │ │ ├── newreleases │ │ │ │ │ │ ├── NewAlbums.kt │ │ │ │ │ │ ├── NewAlbumsFromArtists.kt │ │ │ │ │ │ └── NewReleasesScreen.kt │ │ │ │ │ ├── player │ │ │ │ │ │ ├── AnimatedGradient.kt │ │ │ │ │ │ ├── Controls.kt │ │ │ │ │ │ ├── Lyrics.kt │ │ │ │ │ │ ├── MiniPlayer.kt │ │ │ │ │ │ ├── NextVisualizer.kt │ │ │ │ │ │ ├── PlaybackError.kt │ │ │ │ │ │ ├── Player.kt │ │ │ │ │ │ ├── PlayerSheetState.kt │ │ │ │ │ │ ├── Queue.kt │ │ │ │ │ │ ├── StatsForNerds.kt │ │ │ │ │ │ ├── Thumbnail.kt │ │ │ │ │ │ └── components │ │ │ │ │ │ │ ├── YoutubePlayer.kt │ │ │ │ │ │ │ └── controls │ │ │ │ │ │ │ ├── Essential.kt │ │ │ │ │ │ │ └── Modern.kt │ │ │ │ │ ├── playlist │ │ │ │ │ │ ├── PlaylistScreen.kt │ │ │ │ │ │ └── PlaylistSongList.kt │ │ │ │ │ ├── podcast │ │ │ │ │ │ ├── Podcast.kt │ │ │ │ │ │ └── PodcastScreen.kt │ │ │ │ │ ├── search │ │ │ │ │ │ ├── GoToLink.kt │ │ │ │ │ │ ├── LocalSongSearch.kt │ │ │ │ │ │ ├── OnlineSearch.kt │ │ │ │ │ │ ├── SearchScreen.kt │ │ │ │ │ │ └── SearchTypeScreen.kt │ │ │ │ │ ├── searchresult │ │ │ │ │ │ ├── ItemsPage.kt │ │ │ │ │ │ └── SearchResultScreen.kt │ │ │ │ │ ├── settings │ │ │ │ │ │ ├── About.kt │ │ │ │ │ │ ├── AccountsSettings.kt │ │ │ │ │ │ ├── AppearanceSettings.kt │ │ │ │ │ │ ├── DataSettings.kt │ │ │ │ │ │ ├── GeneralSettings.kt │ │ │ │ │ │ ├── OtherSettings.kt │ │ │ │ │ │ ├── QuickPicsSettings.kt │ │ │ │ │ │ ├── SettingsScreen.kt │ │ │ │ │ │ └── UiSettings.kt │ │ │ │ │ └── statistics │ │ │ │ │ │ ├── StatisticsPage.kt │ │ │ │ │ │ └── StatisticsScreen.kt │ │ │ │ └── styling │ │ │ │ │ ├── Appearance.kt │ │ │ │ │ ├── ColorPalette.kt │ │ │ │ │ ├── CustomColorPalette.kt │ │ │ │ │ ├── Dimensions.kt │ │ │ │ │ ├── Hsl.kt │ │ │ │ │ └── Typography.kt │ │ │ │ └── utils │ │ │ │ ├── ActionReceiver.kt │ │ │ │ ├── AudioUtils.kt │ │ │ │ ├── BitmapUtils.kt │ │ │ │ ├── BlurTransformation.kt │ │ │ │ ├── Bundle.kt │ │ │ │ ├── Cache.kt │ │ │ │ ├── CaptureCrash.kt │ │ │ │ ├── ClipBoard.kt │ │ │ │ ├── CoilBitmapLoader.kt │ │ │ │ ├── Configuration.kt │ │ │ │ ├── ConnectivityUtil.kt │ │ │ │ ├── Context.kt │ │ │ │ ├── CoroutineExtensions.kt │ │ │ │ ├── DataSource.kt │ │ │ │ ├── Discover.kt │ │ │ │ ├── DownloadUtils.kt │ │ │ │ ├── DrawScope.kt │ │ │ │ ├── DropShadow.kt │ │ │ │ ├── EffectHandler.kt │ │ │ │ ├── EncryptedPreferences.kt │ │ │ │ ├── FadingEdge.kt │ │ │ │ ├── FileLoggingTree.kt │ │ │ │ ├── FileUtils.kt │ │ │ │ ├── GetControlsType.kt │ │ │ │ ├── GetDeviceInfo.kt │ │ │ │ ├── GetLikeIconType.kt │ │ │ │ ├── GetPipedSession.kt │ │ │ │ ├── GetSeekBarType.kt │ │ │ │ ├── HomeSongsUtils.kt │ │ │ │ ├── IPChecker.kt │ │ │ │ ├── ImageUtils.kt │ │ │ │ ├── InvincibleService.kt │ │ │ │ ├── IsCompositionLaunched.kt │ │ │ │ ├── LanguageDestination.kt │ │ │ │ ├── LikeState.kt │ │ │ │ ├── LocalPlaylistSongs.kt │ │ │ │ ├── MenuItemColors.kt │ │ │ │ ├── Modifier.kt │ │ │ │ ├── MonetCompat.kt │ │ │ │ ├── MonthlyPlaylists.kt │ │ │ │ ├── NavControllerUtils.kt │ │ │ │ ├── OKHttpRequest.kt │ │ │ │ ├── PinchToggle.kt │ │ │ │ ├── Player.kt │ │ │ │ ├── PlayerState.kt │ │ │ │ ├── Preference.kt │ │ │ │ ├── Preferences.kt │ │ │ │ ├── Resource.kt │ │ │ │ ├── RingBuffer.kt │ │ │ │ ├── ScrollingInfo.kt │ │ │ │ ├── SearchYoutubeEntity.kt │ │ │ │ ├── ServiceUtils.kt │ │ │ │ ├── ShowUpdatedVersion.kt │ │ │ │ ├── SliderPulsatingEffectModifier.kt │ │ │ │ ├── SmoothScrollToTop.kt │ │ │ │ ├── SnapLayoutInfoProvider.kt │ │ │ │ ├── SyncPipedUtils.kt │ │ │ │ ├── SyncYTMusicUtils.kt │ │ │ │ ├── SynchronizedLyrics.kt │ │ │ │ ├── TextStyle.kt │ │ │ │ ├── TimerJob.kt │ │ │ │ ├── UpdateYoutubeEntity.kt │ │ │ │ ├── Utils.kt │ │ │ │ ├── WelcomeMessage.kt │ │ │ │ ├── YoutubeRadio.kt │ │ │ │ └── YoutubeUtils.kt │ │ └── me │ │ │ └── knighthat │ │ │ ├── coil │ │ │ └── ImageCacheFactory.kt │ │ │ ├── component │ │ │ ├── ExportToFileDialog.kt │ │ │ ├── FolderItem.kt │ │ │ ├── ImportFromFile.kt │ │ │ ├── MediaDownloadDialog.kt │ │ │ ├── RenameDialog.kt │ │ │ ├── ResetCache.kt │ │ │ ├── SongItem.kt │ │ │ ├── Sort.kt │ │ │ ├── album │ │ │ │ └── AlbumModifier.kt │ │ │ ├── artist │ │ │ │ └── FollowButton.kt │ │ │ ├── dialog │ │ │ │ ├── CheckboxDialog.kt │ │ │ │ ├── ConfirmDialog.kt │ │ │ │ ├── Dialog.kt │ │ │ │ ├── InputDialog.kt │ │ │ │ ├── InputDialogConstraints.kt │ │ │ │ ├── InteractiveDialog.kt │ │ │ │ ├── RestartAppDialog.kt │ │ │ │ └── TextInputDialog.kt │ │ │ ├── export │ │ │ │ ├── ExportDatabaseDialog.kt │ │ │ │ └── ExportSettingsDialog.kt │ │ │ ├── import │ │ │ │ ├── ImportDatabase.kt │ │ │ │ ├── ImportMigration.kt │ │ │ │ └── ImportSettings.kt │ │ │ ├── menu │ │ │ │ ├── GridMenu.kt │ │ │ │ ├── ListMenu.kt │ │ │ │ ├── MenuConstants.kt │ │ │ │ └── song │ │ │ │ │ └── SongItemMenu.kt │ │ │ ├── player │ │ │ │ ├── BlurAdjuster.kt │ │ │ │ ├── PlaybackSpeed.kt │ │ │ │ └── SleepTimer.kt │ │ │ ├── playlist │ │ │ │ ├── NewPlaylistDialog.kt │ │ │ │ ├── PinPlaylist.kt │ │ │ │ ├── PlaylistSongsSort.kt │ │ │ │ ├── RenamePlaylistDialog.kt │ │ │ │ └── Reposition.kt │ │ │ ├── song │ │ │ │ ├── ChangeAuthorDialog.kt │ │ │ │ ├── ExportCacheDialog.kt │ │ │ │ ├── GoToAlbum.kt │ │ │ │ ├── GoToArtist.kt │ │ │ │ ├── PeriodSelector.kt │ │ │ │ ├── RenameSongDialog.kt │ │ │ │ └── ResetSongDialog.kt │ │ │ ├── tab │ │ │ │ ├── DeleteAllDownloadedSongsDialog.kt │ │ │ │ ├── DeleteHiddenSongsDialog.kt │ │ │ │ ├── DeleteSongDialog.kt │ │ │ │ ├── DownloadAllSongsDialog.kt │ │ │ │ ├── ExportSongsToCSVDialog.kt │ │ │ │ ├── HiddenSongs.kt │ │ │ │ ├── HideSongDialog.kt │ │ │ │ ├── ImportSongsFromCSV.kt │ │ │ │ ├── ItemSelector.kt │ │ │ │ ├── LikeComponent.kt │ │ │ │ ├── Locator.kt │ │ │ │ ├── Radio.kt │ │ │ │ ├── Search.kt │ │ │ │ └── SongShuffler.kt │ │ │ └── ui │ │ │ │ └── screens │ │ │ │ ├── LayoutWithAdaptiveThumbnail.kt │ │ │ │ ├── album │ │ │ │ └── AlbumDetails.kt │ │ │ │ └── player │ │ │ │ └── Queue.kt │ │ │ ├── database │ │ │ ├── AlbumTable.kt │ │ │ ├── ArtistTable.kt │ │ │ ├── Converters.kt │ │ │ ├── EventTable.kt │ │ │ ├── FormatTable.kt │ │ │ ├── LyricsTable.kt │ │ │ ├── PlaylistTable.kt │ │ │ ├── QueuedMediaItemTable.kt │ │ │ ├── SearchQueryTable.kt │ │ │ ├── SongAlbumMapTable.kt │ │ │ ├── SongArtistMapTable.kt │ │ │ ├── SongPlaylistMapTable.kt │ │ │ ├── SongTable.kt │ │ │ ├── ext │ │ │ │ ├── EventWithSong.kt │ │ │ │ └── FormatWithSong.kt │ │ │ └── migration │ │ │ │ ├── From10To11Migration.kt │ │ │ │ ├── From11To12Migration.kt │ │ │ │ ├── From14To15Migration.kt │ │ │ │ ├── From20To21Migration.kt │ │ │ │ ├── From21To22Migration.kt │ │ │ │ ├── From22To23Migration.kt │ │ │ │ ├── From23To24Migration.kt │ │ │ │ ├── From24To25Migration.kt │ │ │ │ ├── From25To26Migration.kt │ │ │ │ ├── From26To27Migration.kt │ │ │ │ ├── From3To4Migration.kt │ │ │ │ ├── From7To8Migration.kt │ │ │ │ └── From8To9Migration.kt │ │ │ ├── enums │ │ │ └── TextView.kt │ │ │ ├── sync │ │ │ └── YouTubeSync.kt │ │ │ ├── updater │ │ │ ├── ChangelogsDialog.kt │ │ │ ├── CheckForUpdateDialog.kt │ │ │ ├── GithubRelease.kt │ │ │ ├── NewUpdateAvailableDialog.kt │ │ │ └── Updater.kt │ │ │ └── utils │ │ │ ├── DurationUtils.kt │ │ │ ├── OnDeviceMedia.kt │ │ │ ├── PathUtils.kt │ │ │ ├── PropUtils.kt │ │ │ ├── Repository.kt │ │ │ ├── TimeDateUtils.kt │ │ │ ├── Toaster.kt │ │ │ └── csv │ │ │ └── SongCSV.kt │ └── res │ │ ├── drawable-anydpi │ │ ├── locked.xml │ │ ├── repeat.xml │ │ ├── search_circle.xml │ │ ├── settings.xml │ │ ├── translate.xml │ │ └── unlocked.xml │ │ ├── drawable-nodpi │ │ ├── a13shape.webp │ │ ├── ghost_orange.webp │ │ ├── ghost_red.webp │ │ ├── ghost_reverse.webp │ │ ├── ic_launcher.png │ │ └── vinyl_background.png │ │ ├── drawable │ │ ├── add.xml │ │ ├── add_in_playlist.xml │ │ ├── album.xml │ │ ├── alert.xml │ │ ├── alert_circle.xml │ │ ├── alert_circle_not_filled.xml │ │ ├── alternative_version.xml │ │ ├── app_logo_text.xml │ │ ├── arrow_down.xml │ │ ├── arrow_forward.xml │ │ ├── arrow_left.xml │ │ ├── arrow_right.xml │ │ ├── arrow_up.xml │ │ ├── artist.xml │ │ ├── artists_edit.xml │ │ ├── backspace_outline.xml │ │ ├── bookmark.xml │ │ ├── bookmark_outline.xml │ │ ├── burger.xml │ │ ├── calendar.xml │ │ ├── calendar_clear.xml │ │ ├── cd.xml │ │ ├── checked_filled.xml │ │ ├── checkmark.xml │ │ ├── chevron_back.xml │ │ ├── chevron_down.xml │ │ ├── chevron_forward.xml │ │ ├── chevron_up.xml │ │ ├── close.xml │ │ ├── color_palette.xml │ │ ├── copy.xml │ │ ├── cover_edit.xml │ │ ├── devices.xml │ │ ├── dice.xml │ │ ├── discord_logo.xml │ │ ├── download.xml │ │ ├── download_cover.xml │ │ ├── download_progress.xml │ │ ├── downloaded.xml │ │ ├── drop_blur.xml │ │ ├── drop_half_fill.xml │ │ ├── droplet.xml │ │ ├── ellipsis_horizontal.xml │ │ ├── ellipsis_vertical.xml │ │ ├── enqueue.xml │ │ ├── equalizer.xml │ │ ├── explicit.xml │ │ ├── export_outline.xml │ │ ├── eye.xml │ │ ├── eye_off.xml │ │ ├── featured_playlist.xml │ │ ├── folder.xml │ │ ├── git_pull_request_outline.xml │ │ ├── github_logo.xml │ │ ├── globe.xml │ │ ├── heart.xml │ │ ├── heart_apple.xml │ │ ├── heart_apple_outline.xml │ │ ├── heart_breaked_no.xml │ │ ├── heart_breaked_yes.xml │ │ ├── heart_brilliant.xml │ │ ├── heart_brilliant_outline.xml │ │ ├── heart_dislike.xml │ │ ├── heart_gift.xml │ │ ├── heart_gift_outline.xml │ │ ├── heart_outline.xml │ │ ├── heart_shape.xml │ │ ├── heart_shape_outline.xml │ │ ├── heart_striped.xml │ │ ├── heart_striped_outline.xml │ │ ├── history.xml │ │ ├── horizontal_bold_line.xml │ │ ├── horizontal_bold_line_rounded.xml │ │ ├── horizontal_straight_line.xml │ │ ├── ic_banner_foreground.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── ic_launcher_monochrome.xml │ │ ├── image.xml │ │ ├── images_sharp.xml │ │ ├── import_outline.xml │ │ ├── infinite.xml │ │ ├── information.xml │ │ ├── library.xml │ │ ├── link.xml │ │ ├── loader.xml │ │ ├── locate.xml │ │ ├── logo_discord.xml │ │ ├── logo_youtube.xml │ │ ├── master_volume.xml │ │ ├── maximize.xml │ │ ├── medical.xml │ │ ├── menu.xml │ │ ├── musical_notes.xml │ │ ├── noimage.xml │ │ ├── open.xml │ │ ├── partially_downloaded.xml │ │ ├── pause.xml │ │ ├── pencil.xml │ │ ├── people.xml │ │ ├── person.xml │ │ ├── pin_filled.xml │ │ ├── piped_logo.xml │ │ ├── play.xml │ │ ├── play_forward.xml │ │ ├── play_skip_back.xml │ │ ├── play_skip_forward.xml │ │ ├── playbackduration.xml │ │ ├── player_horizontal_widget.xml │ │ ├── player_vertical_widget.xml │ │ ├── playlist.xml │ │ ├── podcast.xml │ │ ├── position.xml │ │ ├── query_stats.xml │ │ ├── radio.xml │ │ ├── random.xml │ │ ├── refresh.xml │ │ ├── refresh_circle.xml │ │ ├── reorder.xml │ │ ├── repeatone.xml │ │ ├── resize.xml │ │ ├── search.xml │ │ ├── server.xml │ │ ├── share_social.xml │ │ ├── shield_checkmark.xml │ │ ├── shuffle.xml │ │ ├── shuffle_filled.xml │ │ ├── sleep.xml │ │ ├── slow_motion.xml │ │ ├── smart_shuffle.xml │ │ ├── song_lyrics.xml │ │ ├── sound_effect.xml │ │ ├── sparkles.xml │ │ ├── speedometer_outline.xml │ │ ├── star_brilliant.xml │ │ ├── stat.xml │ │ ├── stat_3months.xml │ │ ├── stat_6months.xml │ │ ├── stat_month.xml │ │ ├── stat_today.xml │ │ ├── stat_week.xml │ │ ├── stat_year.xml │ │ ├── stats_chart.xml │ │ ├── sync.xml │ │ ├── text.xml │ │ ├── time.xml │ │ ├── title_edit.xml │ │ ├── trash.xml │ │ ├── trending.xml │ │ ├── ui.xml │ │ ├── unchecked_outline.xml │ │ ├── up_right_arrow.xml │ │ ├── update.xml │ │ ├── video.xml │ │ ├── volume_up.xml │ │ └── ytmusic.xml │ │ ├── font │ │ ├── pac_font.TTF │ │ ├── poppins_w300.ttf │ │ ├── poppins_w400.ttf │ │ ├── poppins_w500.ttf │ │ ├── poppins_w600.ttf │ │ ├── poppins_w700.ttf │ │ ├── rubik_w300.ttf │ │ ├── rubik_w400.ttf │ │ ├── rubik_w500.ttf │ │ ├── rubik_w600.ttf │ │ └── rubik_w700.ttf │ │ ├── mipmap-anydpi-v26 │ │ └── ic_launcher.xml │ │ ├── mipmap-hdpi │ │ ├── ic_banner.png │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ ├── ic_banner.png │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ ├── ic_banner.png │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_banner.png │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_banner.png │ │ └── ic_launcher.png │ │ ├── raw │ │ ├── ayp_youtube_player.html │ │ ├── contributors.json │ │ ├── po_token.html │ │ └── translators.json │ │ ├── resources.properties │ │ ├── values-af │ │ └── strings.xml │ │ ├── values-ar │ │ └── strings.xml │ │ ├── values-az │ │ └── strings.xml │ │ ├── values-ba │ │ └── strings.xml │ │ ├── values-bn │ │ └── strings.xml │ │ ├── values-ca │ │ └── strings.xml │ │ ├── values-cs │ │ └── strings.xml │ │ ├── values-da │ │ └── strings.xml │ │ ├── values-de │ │ └── strings.xml │ │ ├── values-el │ │ └── strings.xml │ │ ├── values-en │ │ └── strings.xml │ │ ├── values-eo │ │ └── strings.xml │ │ ├── values-es │ │ └── strings.xml │ │ ├── values-et │ │ └── strings.xml │ │ ├── values-fa │ │ └── strings.xml │ │ ├── values-fi │ │ └── strings.xml │ │ ├── values-fil │ │ └── strings.xml │ │ ├── values-fr │ │ └── strings.xml │ │ ├── values-ga │ │ └── strings.xml │ │ ├── values-gl │ │ └── strings.xml │ │ ├── values-he │ │ └── strings.xml │ │ ├── values-hi │ │ └── strings.xml │ │ ├── values-hu │ │ └── strings.xml │ │ ├── values-ia │ │ └── strings.xml │ │ ├── values-id │ │ └── strings.xml │ │ ├── values-in │ │ └── strings.xml │ │ ├── values-it │ │ └── strings.xml │ │ ├── values-iw │ │ └── strings.xml │ │ ├── values-ja │ │ └── strings.xml │ │ ├── values-ko │ │ └── strings.xml │ │ ├── values-ml │ │ └── strings.xml │ │ ├── values-night-v29 │ │ └── themes.xml │ │ ├── values-night │ │ └── themes.xml │ │ ├── values-nl │ │ └── strings.xml │ │ ├── values-no │ │ └── strings.xml │ │ ├── values-or │ │ └── strings.xml │ │ ├── values-pl │ │ └── strings.xml │ │ ├── values-pt-rBR │ │ └── strings.xml │ │ ├── values-pt │ │ └── strings.xml │ │ ├── values-ro │ │ └── strings.xml │ │ ├── values-ru │ │ └── strings.xml │ │ ├── values-si │ │ └── strings.xml │ │ ├── values-sr-rCS │ │ └── strings.xml │ │ ├── values-sr │ │ └── strings.xml │ │ ├── values-sv │ │ └── strings.xml │ │ ├── values-ta │ │ └── strings.xml │ │ ├── values-te │ │ └── strings.xml │ │ ├── values-tr │ │ └── strings.xml │ │ ├── values-uk │ │ └── strings.xml │ │ ├── values-vi │ │ └── strings.xml │ │ ├── values-zh-rCN │ │ └── strings.xml │ │ ├── values-zh-rTW │ │ └── strings.xml │ │ ├── values-zh │ │ └── strings.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── ic_banner_background.xml │ │ ├── ic_launcher_background.xml │ │ ├── strings.xml │ │ └── themes.xml │ │ ├── xml-v25 │ │ └── shortcuts.xml │ │ └── xml │ │ ├── automotive_app_desc.xml │ │ ├── network_security_config.xml │ │ ├── player_horizontal_widget_info.xml │ │ └── player_vertical_widget_info.xml │ ├── commonMain │ ├── composeResources │ │ ├── drawable │ │ │ ├── album.xml │ │ │ ├── app_icon.xml │ │ │ ├── app_logo.xml │ │ │ ├── app_logo_text.xml │ │ │ ├── arrow_forward.xml │ │ │ ├── arrow_left.xml │ │ │ ├── artists.xml │ │ │ ├── bookmark.xml │ │ │ ├── bookmark_outline.xml │ │ │ ├── chevron_down.xml │ │ │ ├── chevron_up.xml │ │ │ ├── compose-multiplatform.xml │ │ │ ├── dice.webp │ │ │ ├── library.xml │ │ │ ├── loader.webp │ │ │ ├── musical_notes.xml │ │ │ ├── pause.xml │ │ │ ├── pin.webp │ │ │ ├── piped_logo.xml │ │ │ ├── play.xml │ │ │ ├── play_skip_back.xml │ │ │ ├── play_skip_forward.xml │ │ │ ├── share_social.xml │ │ │ ├── shuffle.xml │ │ │ ├── stat_month.xml │ │ │ └── translate.xml │ │ └── values │ │ │ └── strings.xml │ └── kotlin │ │ ├── database │ │ ├── MusicDatabase.kt │ │ └── entities │ │ │ ├── Album.kt │ │ │ ├── Artist.kt │ │ │ ├── Event.kt │ │ │ ├── Format.kt │ │ │ ├── Lyrics.kt │ │ │ ├── Playlist.kt │ │ │ ├── QueuedMediaItem.kt │ │ │ ├── SearchQuery.kt │ │ │ ├── Song.kt │ │ │ ├── SongAlbumMap.kt │ │ │ ├── SongArtistMap.kt │ │ │ ├── SongEntity.kt │ │ │ ├── SongPlaylistMap.kt │ │ │ └── SortedSongPlaylistMap.kt │ │ └── it │ │ └── fast4x │ │ └── rimusic │ │ ├── App.kt │ │ ├── AsyncImageLoader.kt │ │ ├── Greeting.kt │ │ ├── Platform.kt │ │ └── Utils.kt │ ├── debug │ └── res │ │ └── xml-v25 │ │ └── shortcuts.xml │ ├── desktopMain │ └── kotlin │ │ ├── database │ │ └── getMusicDatabase.kt │ │ ├── it │ │ └── fast4x │ │ │ └── rimusic │ │ │ ├── Platform.jvm.kt │ │ │ ├── enums │ │ │ ├── ColorPaletteMode.kt │ │ │ ├── ColorPaletteName.kt │ │ │ ├── FontType.kt │ │ │ ├── Locales.kt │ │ │ ├── PageType.kt │ │ │ └── ThumbnailRoundness.kt │ │ │ ├── items │ │ │ ├── ItemContainer.kt │ │ │ └── Items.kt │ │ │ ├── models │ │ │ └── PipedSession.kt │ │ │ ├── player │ │ │ ├── exception │ │ │ │ └── Catch.kt │ │ │ ├── extension │ │ │ │ └── Long.kt │ │ │ ├── player │ │ │ │ ├── DefaultControls.kt │ │ │ │ ├── PlayerController.kt │ │ │ │ ├── PlayerInput.kt │ │ │ │ ├── PlayerSource.kt │ │ │ │ ├── PlayerState.kt │ │ │ │ ├── component │ │ │ │ │ ├── ComponentContainer.kt │ │ │ │ │ ├── ComponentPlayer.kt │ │ │ │ │ └── ComponentRenderer.kt │ │ │ │ └── frame │ │ │ │ │ ├── FrameContainer.kt │ │ │ │ │ ├── FramePlayer.kt │ │ │ │ │ └── FrameRenderer.kt │ │ │ ├── upload │ │ │ │ └── UploadDialog.kt │ │ │ └── vlcj │ │ │ │ ├── VlcjComponentController.kt │ │ │ │ ├── VlcjController.kt │ │ │ │ └── VlcjFrameController.kt │ │ │ ├── styling │ │ │ ├── ColorPalette.kt │ │ │ └── Dimensions.kt │ │ │ ├── ui │ │ │ ├── DesktopApp.kt │ │ │ ├── ThreeColumnsApp.kt │ │ │ ├── bars │ │ │ │ └── DefaultBottomBar.kt │ │ │ ├── components │ │ │ │ ├── AutoResizeText.kt │ │ │ │ ├── CustomModalBottomSheet.kt │ │ │ │ ├── LayoutWithAdaptiveThumbnail.kt │ │ │ │ ├── Loader.kt │ │ │ │ ├── PlayerEssential.kt │ │ │ │ ├── Title.kt │ │ │ │ ├── Title2Actions.kt │ │ │ │ └── ToolButton.kt │ │ │ ├── pages │ │ │ │ ├── AlbumsPage.kt │ │ │ │ └── SongsPage.kt │ │ │ ├── screens │ │ │ │ ├── AlbumScreen.kt │ │ │ │ ├── ArtistScreen.kt │ │ │ │ ├── ArtistsScreen.kt │ │ │ │ ├── MoodScreen.kt │ │ │ │ ├── PlaylistScreen.kt │ │ │ │ └── QuickPicsScreen.kt │ │ │ └── theme │ │ │ │ ├── Color.kt │ │ │ │ ├── Theme.kt │ │ │ │ └── Typography.kt │ │ │ └── utils │ │ │ ├── FadingEdge.kt │ │ │ ├── GetPipedSession.kt │ │ │ ├── LanguageDestination.kt │ │ │ ├── LoadImage.kt │ │ │ ├── MonthlyPlaylist.kt │ │ │ └── Utils.kt │ │ └── main.kt │ └── main │ └── res │ └── drawable │ ├── preset0.webp │ ├── preset1.webp │ ├── preset2.webp │ ├── preset3.webp │ ├── preset4.webp │ └── preset5.webp ├── crowdin.yml ├── extensions ├── innertube │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ ├── it │ │ │ └── fast4x │ │ │ │ └── innertube │ │ │ │ ├── Innertube.kt │ │ │ │ ├── YtMusic.kt │ │ │ │ ├── clients │ │ │ │ ├── YouTubeClient.kt │ │ │ │ ├── YouTubeContext.kt │ │ │ │ └── YouTubeLocale.kt │ │ │ │ ├── models │ │ │ │ ├── AccountInfo.kt │ │ │ │ ├── AccountMenuResponse.kt │ │ │ │ ├── BadgesRenderer.kt │ │ │ │ ├── BrowseResponse.kt │ │ │ │ ├── ButtonRenderer.kt │ │ │ │ ├── Context.kt │ │ │ │ ├── Continuation.kt │ │ │ │ ├── ContinuationResponse.kt │ │ │ │ ├── CreatePlaylistResponse.kt │ │ │ │ ├── Endpoint.kt │ │ │ │ ├── GetQueueResponse.kt │ │ │ │ ├── GetSearchSuggestionsResponse.kt │ │ │ │ ├── GridRenderer.kt │ │ │ │ ├── Icon.kt │ │ │ │ ├── MediaType.kt │ │ │ │ ├── Menu.kt │ │ │ │ ├── MusicCarouselShelfRenderer.kt │ │ │ │ ├── MusicEditablePlaylistDetailHeaderRenderer.kt │ │ │ │ ├── MusicNavigationButtonRenderer.kt │ │ │ │ ├── MusicPlaylistShelfRenderer.kt │ │ │ │ ├── MusicResponsiveHeaderRenderer.kt │ │ │ │ ├── MusicResponsiveListItemRenderer.kt │ │ │ │ ├── MusicShelfRenderer.kt │ │ │ │ ├── MusicTwoRowItemRenderer.kt │ │ │ │ ├── NavigationEndpoint.kt │ │ │ │ ├── NextResponse.kt │ │ │ │ ├── PipedResponse.kt │ │ │ │ ├── PlayerResponse.kt │ │ │ │ ├── PlaylistPanelVideoRenderer.kt │ │ │ │ ├── ResponseContext.kt │ │ │ │ ├── Runs.kt │ │ │ │ ├── SearchResponse.kt │ │ │ │ ├── SearchSuggestionsResponse.kt │ │ │ │ ├── SearchSuggestionsSectionRenderer.kt │ │ │ │ ├── SectionListRenderer.kt │ │ │ │ ├── SubscriptionButton.kt │ │ │ │ ├── Tabs.kt │ │ │ │ ├── Thumbnail.kt │ │ │ │ ├── ThumbnailRenderer.kt │ │ │ │ ├── Thumbnails.kt │ │ │ │ ├── bodies │ │ │ │ │ ├── AccountMenuBody.kt │ │ │ │ │ ├── BrowseBody.kt │ │ │ │ │ ├── BrowseBodyWithLocale.kt │ │ │ │ │ ├── ContinuationBody.kt │ │ │ │ │ ├── ContinuationBodyWithLocale.kt │ │ │ │ │ ├── CreatePlaylistBody.kt │ │ │ │ │ ├── EditPlaylistBody.kt │ │ │ │ │ ├── FormData.kt │ │ │ │ │ ├── LikeBody.kt │ │ │ │ │ ├── NextBody.kt │ │ │ │ │ ├── PlayerBody.kt │ │ │ │ │ ├── PlaylistDeleteBody.kt │ │ │ │ │ ├── QueueBody.kt │ │ │ │ │ ├── SearchBody.kt │ │ │ │ │ ├── SearchSuggestionsBody.kt │ │ │ │ │ └── SubscribeBody.kt │ │ │ │ └── v0624 │ │ │ │ │ ├── BrowseResponse0624.kt │ │ │ │ │ ├── charts │ │ │ │ │ └── BrowseChartsResponse0624.kt │ │ │ │ │ └── podcasts │ │ │ │ │ └── BrowsePodcastsResponse0624.kt │ │ │ │ ├── requests │ │ │ │ ├── AlbumPage.kt │ │ │ │ ├── ArtistInfoPage.kt │ │ │ │ ├── ArtistItemsContinuationPage.kt │ │ │ │ ├── ArtistItemsPage.kt │ │ │ │ ├── ArtistPage.kt │ │ │ │ ├── Browse.kt │ │ │ │ ├── ChartsPage.kt │ │ │ │ ├── ChartsPageComplete.kt │ │ │ │ ├── DiscoverPage.kt │ │ │ │ ├── HistoryPage.kt │ │ │ │ ├── HomePage.kt │ │ │ │ ├── ItemsPage.kt │ │ │ │ ├── LibraryContinuationPage.kt │ │ │ │ ├── LibraryPage.kt │ │ │ │ ├── Lyrics.kt │ │ │ │ ├── NewReleaseAlbumPage.kt │ │ │ │ ├── NextPage.kt │ │ │ │ ├── PlaylistContinuationPage.kt │ │ │ │ ├── PlaylistPage.kt │ │ │ │ ├── PodcastPage.kt │ │ │ │ ├── Queue.kt │ │ │ │ ├── RelatedPage.kt │ │ │ │ ├── RelatedSongs.kt │ │ │ │ ├── SearchPage.kt │ │ │ │ └── SearchSuggestions.kt │ │ │ │ └── utils │ │ │ │ ├── FromMusicResponsiveListItemRenderer.kt │ │ │ │ ├── FromMusicShelfRendererContent.kt │ │ │ │ ├── FromMusicTwoRowItemRenderer.kt │ │ │ │ ├── LocalePreferences.kt │ │ │ │ ├── NewPipe.kt │ │ │ │ ├── PageHelper.kt │ │ │ │ ├── ProxyPreferences.kt │ │ │ │ ├── Utils.kt │ │ │ │ └── YoutubePreferences.kt │ │ │ └── me │ │ │ └── knighthat │ │ │ ├── common │ │ │ ├── HttpFetcher.kt │ │ │ ├── PublicInstances.kt │ │ │ └── response │ │ │ │ ├── AudioFormat.kt │ │ │ │ └── MediaFormatContainer.kt │ │ │ ├── invidious │ │ │ ├── Invidious.kt │ │ │ ├── request │ │ │ │ └── Player.kt │ │ │ └── response │ │ │ │ └── PlayerResponse.kt │ │ │ └── piped │ │ │ ├── Piped.kt │ │ │ ├── request │ │ │ └── Player.kt │ │ │ └── response │ │ │ └── PlayerResponse.kt │ │ └── test │ │ └── kotlin │ │ └── Test.kt ├── invidious │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── kotlin │ │ └── it │ │ └── fast4x │ │ └── invidious │ │ ├── Invidious.kt │ │ ├── models │ │ ├── AdaptiveFormats.kt │ │ └── Instances.kt │ │ └── utils │ │ ├── Coroutines.kt │ │ ├── ProxyPreferences.kt │ │ └── Serializers.kt ├── ktor-client-brotli │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── kotlin │ │ └── io │ │ └── ktor │ │ └── client │ │ └── plugins │ │ └── compression │ │ └── BrotliEncoder.kt ├── kugou │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── it │ │ │ └── fast4x │ │ │ └── kugou │ │ │ ├── KuGou.kt │ │ │ ├── Result.kt │ │ │ └── models │ │ │ ├── DownloadLyricsResponse.kt │ │ │ ├── SearchLyricsResponse.kt │ │ │ └── SearchSongResponse.kt │ │ └── test │ │ └── kotlin │ │ └── Test.kt ├── lrclib │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── kotlin │ │ └── it │ │ └── fast4x │ │ └── lrclib │ │ ├── LrcLib.kt │ │ ├── models │ │ └── Track.kt │ │ └── utils │ │ ├── Coroutines.kt │ │ ├── ProxyPreferences.kt │ │ └── Serializers.kt └── piped │ ├── build.gradle.kts │ └── src │ └── main │ └── kotlin │ └── it │ └── fast4x │ └── piped │ ├── Piped.kt │ ├── models │ ├── Instance.kt │ ├── PipedResponse.kt │ ├── PlaylistPreview.kt │ ├── Serializers.kt │ └── Session.kt │ └── utils │ ├── Coroutines.kt │ ├── ProxyPreferences.kt │ └── Serializers.kt ├── fastlane └── metadata │ └── android │ └── en-US │ ├── changelogs │ ├── 100.txt │ ├── 87.txt │ ├── 88.txt │ ├── 89.txt │ ├── 90.txt │ ├── 91.txt │ ├── 92.txt │ ├── 93.txt │ ├── 94.txt │ ├── 95.txt │ ├── 96.txt │ ├── 97.txt │ ├── 98.txt │ └── 99.txt │ ├── 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 │ │ └── 9.png │ └── tvBanner.png │ ├── short_description.txt │ └── title.txt ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle.kts /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | patreon: knighthat 4 | liberapay: knighthat 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /captures 2 | .externalNativeBuild 3 | .cxx 4 | .ignore.d/ 5 | 6 | ### IDEA 7 | .idea 8 | .gradle 9 | .vscode 10 | 11 | ### BUILDS 12 | **build/ 13 | 14 | ### BINS 15 | **bin/ 16 | 17 | ### ANDROID 18 | **APK keystore/ 19 | .DS_Store 20 | composeApp/src/androidMain/res/raw/release_notes.txt 21 | 22 | ### PROPERTIES 23 | **local.properties 24 | **crowdin.properties 25 | **__crowdin.properties 26 | 27 | 28 | ### DEPENDENCIES 29 | /YT python/ 30 | /.kotlin/ 31 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "innertube-java"] 2 | path = modules/innertube 3 | url = https://github.com/knighthat/innertube-java -------------------------------------------------------------------------------- /.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-stdlib-2.0.20-commonMain-WPEnbA.klib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-stdlib-2.0.20-commonMain-WPEnbA.klib -------------------------------------------------------------------------------- /assets/design/app_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/assets/design/app_banner.png -------------------------------------------------------------------------------- /assets/get-it-on/Accrescent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/assets/get-it-on/Accrescent.png -------------------------------------------------------------------------------- /assets/get-it-on/AndroidFreeware.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/assets/get-it-on/AndroidFreeware.png -------------------------------------------------------------------------------- /assets/get-it-on/F-Droid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/assets/get-it-on/F-Droid.png -------------------------------------------------------------------------------- /assets/get-it-on/GitHub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/assets/get-it-on/GitHub.png -------------------------------------------------------------------------------- /assets/get-it-on/IzzyOnDroid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/assets/get-it-on/IzzyOnDroid.png -------------------------------------------------------------------------------- /assets/get-it-on/Obtainium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/assets/get-it-on/Obtainium.png -------------------------------------------------------------------------------- /assets/get-it-on/OpenAPK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/assets/get-it-on/OpenAPK.png -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | // Multiplatform 3 | alias(libs.plugins.kotlin.multiplatform) apply false 4 | alias(libs.plugins.kotlin.compose) apply false 5 | alias(libs.plugins.jetbrains.compose) apply false 6 | 7 | // Android 8 | alias(libs.plugins.android.application) apply false 9 | 10 | // Others 11 | alias(libs.plugins.kotlin.serialization) apply false 12 | alias(libs.plugins.kotlin.ksp) apply false 13 | } 14 | -------------------------------------------------------------------------------- /composeApp/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /release 3 | /lint-baseline.xml 4 | /accrescent 5 | /foss 6 | /.gradle 7 | /_conveyor.conf 8 | /conveyor.conf 9 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/ic_launcher-playstore.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/ic_launcher-playstore.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/ic_logo-playstore.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/ic_logo-playstore.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/app/kreate/android/Threads.kt: -------------------------------------------------------------------------------- 1 | package app.kreate.android 2 | 3 | import kotlinx.coroutines.asCoroutineDispatcher 4 | import java.util.concurrent.Executors 5 | 6 | /** 7 | * Collection of useful threads. 8 | * 9 | * Must be closed individually after use to prevent unwanted outcome 10 | */ 11 | object Threads { 12 | 13 | /** 14 | * Single thread dispatcher guarantee jobs are 15 | * executed in the order that were given to it. 16 | * 17 | * Should only be used by DataspecServices.kt 18 | */ 19 | val DATASPEC_DISPATCHER = Executors.newSingleThreadExecutor().asCoroutineDispatcher() 20 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/app/kreate/android/constant/Speed.kt: -------------------------------------------------------------------------------- 1 | package app.kreate.android.constant 2 | 3 | import androidx.compose.runtime.Composable 4 | import me.knighthat.enums.TextView 5 | 6 | enum class Speed( 7 | private val _text: String, 8 | val value: Float 9 | ): TextView { 10 | 11 | SLOW_QUARTER( "0.25x", .25f ), 12 | 13 | SLOW_HALF( "0.5x", .5f ), 14 | 15 | SLOW_TWO_THIRD( "0.75x", .75f ), 16 | 17 | NORMAL( "1x", 1f ), 18 | 19 | FAST_HALF( "1.5x", 1.5f ), 20 | 21 | FAST_TWO( "2x", 2f ), 22 | 23 | FAST_THREE( "3x", 3f ), 24 | 25 | FAST_FOUR( "4x", 4f ), 26 | 27 | FAST_FIVE( "5x", 5f ), 28 | 29 | FAST_TEN( "10x", 10f ); 30 | 31 | override val text: String 32 | @Composable 33 | get() = this._text 34 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/app/kreate/android/drawable/AppIcon.kt: -------------------------------------------------------------------------------- 1 | package app.kreate.android.drawable 2 | 3 | import android.graphics.Bitmap 4 | import android.graphics.BitmapFactory 5 | import androidx.compose.ui.graphics.ImageBitmap 6 | import androidx.compose.ui.graphics.asImageBitmap 7 | import app.kreate.android.R 8 | import it.fast4x.rimusic.appContext 9 | 10 | // Due to the complexity of rasterized image, it must be converted into 11 | // bitmap before rendering. 12 | val APP_ICON_BITMAP: Bitmap by lazy { 13 | BitmapFactory.decodeResource( appContext().resources, R.drawable.ic_launcher ) 14 | } 15 | 16 | val APP_ICON_IMAGE_BITMAP: ImageBitmap by lazy { 17 | APP_ICON_BITMAP.asImageBitmap() 18 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/app/kreate/android/utils/CharUtils.kt: -------------------------------------------------------------------------------- 1 | package app.kreate.android.utils 2 | 3 | object CharUtils { 4 | 5 | private const val CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" 6 | fun randomString( length: Int ): String = 7 | (1..length).map { CHARS.random() }.joinToString("") 8 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/app/kreate/android/widget/WidgetReceiver.kt: -------------------------------------------------------------------------------- 1 | package app.kreate.android.widget 2 | 3 | import androidx.glance.appwidget.GlanceAppWidget 4 | import androidx.glance.appwidget.GlanceAppWidgetReceiver 5 | 6 | class VerticalWidgetReceiver( 7 | override val glanceAppWidget: GlanceAppWidget = Widget.Vertical 8 | ): GlanceAppWidgetReceiver() 9 | 10 | class HorizontalWidgetReceiver( 11 | override val glanceAppWidget: GlanceAppWidget = Widget.Horizontal 12 | ): GlanceAppWidgetReceiver() -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/database/getMusicDatabase.kt: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | import android.content.Context 4 | import androidx.room.Room 5 | import androidx.room.RoomDatabase 6 | 7 | fun getAndroidDatabaseBuilder(ctx: Context): RoomDatabase.Builder { 8 | val appContext = ctx.applicationContext 9 | val dbFile = appContext.getDatabasePath("rimusic.db") 10 | return Room.databaseBuilder( 11 | context = appContext, 12 | name = dbFile.absolutePath 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/compose/persist/PersistMap.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.compose.persist 2 | 3 | import android.util.Log 4 | import androidx.compose.runtime.compositionLocalOf 5 | 6 | typealias PersistMap = HashMap 7 | 8 | val LocalPersistMap = compositionLocalOf { 9 | Log.e("PersistMap", "Tried to reference uninitialized PersistMap, stacktrace:") 10 | runCatching { error("Stack:") }.exceptionOrNull()?.printStackTrace() 11 | null 12 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/compose/persist/PersistMapOwner.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.compose.persist 2 | 3 | interface PersistMapOwner { 4 | val persistMap: PersistMap 5 | } 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/compose/persist/Utils.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.compose.persist 2 | 3 | import android.content.Context 4 | import android.content.ContextWrapper 5 | 6 | val Context.persistMap: PersistMap? 7 | get() = findOwner()?.persistMap 8 | 9 | internal inline fun Context.findOwner(): T? { 10 | var context = this 11 | while (context is ContextWrapper) { 12 | if (context is T) return context 13 | context = context.baseContext 14 | } 15 | return null 16 | } 17 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/compose/reordering/AnimateItemPlacement.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.compose.reordering 2 | 3 | import androidx.compose.animation.core.spring 4 | import androidx.compose.foundation.ExperimentalFoundationApi 5 | import androidx.compose.foundation.lazy.LazyItemScope 6 | import androidx.compose.ui.Modifier 7 | 8 | context(LazyItemScope) 9 | @ExperimentalFoundationApi 10 | fun Modifier.localAnimateItemPlacement(reorderingState: ReorderingState) = 11 | if (reorderingState.draggingIndex == -1) Modifier.animateItem() else this 12 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/Platform.android.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic 2 | 3 | actual fun getPlatform(): Platform { 4 | TODO("Not yet implemented") 5 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/AlbumSortBy.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.DrawableRes 4 | import androidx.annotation.StringRes 5 | import app.kreate.android.R 6 | import me.knighthat.enums.TextView 7 | 8 | enum class AlbumSortBy( 9 | @field:StringRes override val textId: Int, 10 | @field:DrawableRes override val iconId: Int 11 | ): Drawable, TextView { 12 | 13 | Title( R.string.sort_album, R.drawable.text ), 14 | 15 | Year( R.string.sort_album_year, R.drawable.calendar ), 16 | 17 | DateAdded( R.string.sort_date_added, R.drawable.time ), 18 | 19 | Artist( R.string.sort_artist, R.drawable.artist ), 20 | 21 | Songs( R.string.sort_songs_number, R.drawable.medical ), 22 | 23 | Duration( R.string.sort_duration, R.drawable.time ); 24 | } 25 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/AlbumsType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class AlbumsType( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Favorites( R.string.favorites ), 12 | Library( R.string.library ); 13 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/ArtistSortBy.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.DrawableRes 4 | import androidx.annotation.StringRes 5 | import app.kreate.android.R 6 | import me.knighthat.enums.TextView 7 | 8 | enum class ArtistSortBy( 9 | @field:StringRes override val textId: Int, 10 | @field:DrawableRes override val iconId: Int 11 | ): TextView, Drawable { 12 | 13 | Name( R.string.sort_artist, R.drawable.text ), 14 | 15 | DateAdded( R.string.sort_date_added, R.drawable.time ); 16 | } 17 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/ArtistsType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class ArtistsType( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Favorites( R.string.favorites ), 12 | Library( R.string.library ); 13 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/AudioQualityFormat.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class AudioQualityFormat( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Auto( R.string.audio_quality_automatic ), 12 | 13 | High( R.string.audio_quality_format_high ), 14 | 15 | Medium( R.string.audio_quality_format_medium ), 16 | 17 | Low( R.string.audio_quality_format_low ); 18 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/BackgroundProgress.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums; 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class BackgroundProgress( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Player( R.string.player ), 12 | 13 | MiniPlayer( R.string.minimized_player ), 14 | 15 | Both( R.string.both ), 16 | 17 | Disabled( R.string.vt_disabled ); 18 | } 19 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/BuiltInPlaylist.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.DrawableRes 4 | import androidx.annotation.StringRes 5 | import app.kreate.android.R 6 | import me.knighthat.enums.TextView 7 | 8 | enum class BuiltInPlaylist( 9 | @field:DrawableRes override val iconId: Int, 10 | @field:StringRes override val textId: Int 11 | ): Drawable, TextView { 12 | 13 | All( R.drawable.musical_notes, R.string.songs ), 14 | 15 | Favorites( R.drawable.heart, R.string.favorites ), 16 | 17 | Offline( R.drawable.sync, R.string.cached ), 18 | 19 | Downloaded( R.drawable.downloaded, R.string.downloaded ), 20 | 21 | Top( R.drawable.trending, R.string.playlist_top ), 22 | 23 | OnDevice( R.drawable.musical_notes, R.string.on_device ) 24 | } 25 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/ButtonState.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class ButtonState { 4 | Pressed, 5 | Idle; 6 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/CacheType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class CacheType { 4 | Images, 5 | CachedSongs, 6 | DownloadedSongs 7 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/CarousalSize.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class CarouselSize( 8 | val size: Int, 9 | @field:StringRes override val textId: Int 10 | ): TextView { 11 | 12 | Small( 90, R.string.small ), 13 | 14 | Medium( 55, R.string.medium ), 15 | 16 | Big( 30, R.string.big ), 17 | 18 | Biggest( 20, R.string.biggest ), 19 | 20 | Expanded( 0, R.string.expanded ); 21 | } 22 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/CheckUpdateState.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class CheckUpdateState( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Enabled( R.string.enabled ), 12 | Disabled( R.string.vt_disabled ), 13 | Ask( R.string.ask ); 14 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/ClickLyricsText.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums; 2 | 3 | enum class ClickLyricsText { 4 | Player, 5 | FullScreen, 6 | Both 7 | } 8 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/ColorPaletteMode.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class ColorPaletteMode( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Light( R.string._light ), 12 | 13 | Dark( R.string.dark ), 14 | 15 | PitchBlack( R.string.system ), 16 | 17 | System( R.string.theme_mode_pitch_black ); 18 | } 19 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/ColorPaletteName.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class ColorPaletteName( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Default( R.string._default ), 12 | 13 | Dynamic( R.string.dynamic ), 14 | 15 | PureBlack( R.string.theme_pure_black ), 16 | 17 | ModernBlack( R.string.theme_modern_black ), 18 | 19 | MaterialYou( R.string.theme_material_you ), 20 | 21 | Customized( R.string.theme_customized ), 22 | 23 | CustomColor( R.string.customcolor); 24 | } 25 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/DeviceLists.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class DeviceLists { 4 | LocalSongs 5 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/DownloadedStateMedia.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.DrawableRes 4 | import app.kreate.android.R 5 | 6 | enum class DownloadedStateMedia( 7 | @field:DrawableRes override val iconId: Int 8 | ): Drawable { 9 | 10 | CACHED( R.drawable.download ), 11 | 12 | CACHED_AND_DOWNLOADED( R.drawable.downloaded ), 13 | 14 | DOWNLOADED( R.drawable.downloaded ), 15 | 16 | NOT_CACHED_OR_DOWNLOADED( R.drawable.download ); 17 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/DragAnchors.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class DragAnchors { 4 | Start, 5 | End, 6 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/Drawable.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.DrawableRes 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.graphics.painter.Painter 6 | import androidx.compose.ui.res.painterResource 7 | 8 | interface Drawable { 9 | 10 | @get:DrawableRes 11 | val iconId: Int 12 | get() = throw NotImplementedError(""" 13 | This setting uses [${this::class.simpleName}#icon] directly 14 | or its [${this::class.simpleName}#iconId] hasn't initialized! 15 | """.trimIndent()) 16 | 17 | val icon: Painter 18 | @Composable 19 | get() = painterResource( this.iconId ) 20 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/ExoPlayerCacheLocation.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class ExoPlayerCacheLocation( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | System( R.string.cache_location_system ), 12 | Private( R.string.cache_location_private ); 13 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/ExoPlayerMinTimeForEvent.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class ExoPlayerMinTimeForEvent( 4 | val asSeconds: Int 5 | ) { 6 | 7 | `10s`( 10 ), 8 | 9 | `15s`( 15 ), 10 | 11 | `20s`( 20 ), 12 | 13 | `30s`( 30 ), 14 | 15 | `40s`( 40 ), 16 | 17 | `60s`( 60 ); 18 | 19 | val asMillis: Long = this.asSeconds * 1000L 20 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/FilterBy.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class FilterBy { 4 | All, 5 | Local, 6 | YoutubeLibrary; 7 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/FontType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class FontType { 4 | Rubik, 5 | Poppins 6 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/HistoryType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class HistoryType { 4 | History, 5 | YTMHistory 6 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/IconsLikeType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class IconLikeType( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Apple( R.string.icon_like_apple ), 12 | 13 | Breaked( R.string.icon_like_breaked ), 14 | 15 | Brilliant( R.string.icon_like_brilliant ), 16 | 17 | Essential( R.string.pcontrols_essential ), 18 | 19 | Gift( R.string.icon_like_gift ), 20 | 21 | Shape( R.string.icon_like_shape ), 22 | 23 | Striped( R.string.icon_like_striped ); 24 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/LandscapeLayout.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class LandscapeLayout { 4 | Layout1, 5 | Layout2; 6 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/LibraryItemSize.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class LibraryItemSize { 4 | Small, 5 | Medium, 6 | Big; 7 | 8 | val size: Int 9 | get() = when (this) { 10 | Small -> 80 11 | Medium -> 108 12 | Big -> 140 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/LogType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class LogType { 4 | Default, 5 | Crash 6 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/LyricsAlignment.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.compose.ui.text.style.TextAlign 4 | 5 | 6 | // TODO: Remove this 7 | enum class LyricsAlignment { 8 | Left, 9 | Center, 10 | Right; 11 | 12 | val selected: TextAlign 13 | get() = when (this) { 14 | Left -> TextAlign.Start 15 | Center -> TextAlign.Center 16 | Right -> TextAlign.End 17 | } 18 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/LyricsBackground.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class LyricsBackground { 4 | None, 5 | Black, 6 | White; 7 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/LyricsColor.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class LyricsColor { 4 | Thememode, 5 | White, 6 | Black, 7 | Accent, 8 | Cover, 9 | FluidRainbow, 10 | FluidTheme; 11 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/LyricsFontSize.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class LyricsFontSize { 4 | Light, 5 | Medium, 6 | Heavy, 7 | Large, 8 | Custom 9 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/LyricsHighlight.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class LyricsHighlight { 4 | None, 5 | White, 6 | Black; 7 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/LyricsOutline.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class LyricsOutline { 4 | None, 5 | Thememode, 6 | White, 7 | Black, 8 | Rainbow, 9 | Glow; 10 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/MaxStatisticsItems.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class MaxStatisticsItems { 4 | `10`, 5 | `20`, 6 | `30`, 7 | `40`, 8 | `50`; 9 | 10 | fun toInt(): Int = this.name.toInt() 11 | 12 | fun toLong(): Long = this.name.toLong() 13 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/MenuStyle.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class MenuStyle( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | List( R.string.style_list ), 12 | Grid( R.string.style_grid ); 13 | } 14 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/MessageType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class MessageType( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Essential( R.string.message_type_essential ), 12 | Modern( R.string.message_type_modern ); 13 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/MiniPlayerType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class MiniPlayerType( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Essential( R.string.pcontrols_essential ), 12 | Modern( R.string.pcontrols_modern ); 13 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/MoodType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class MoodType { 4 | New, 5 | MoodGenres 6 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/MusicAnimationType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class MusicAnimationType( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Disabled( R.string.vt_disabled ), 12 | 13 | Bars( R.string.music_animations_bars ), 14 | 15 | CrazyBars( R.string.music_animations_crazy_bars ), 16 | 17 | CrazyPoints( R.string.music_animations_crazy_points ), 18 | 19 | Bubbles( R.string.music_animations_bubbles ); 20 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/NotificationType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.ui.res.stringResource 5 | import app.kreate.android.R 6 | 7 | enum class NotificationType { 8 | Default, 9 | Advanced; 10 | 11 | val textName: String 12 | @Composable 13 | get() = when (this) { 14 | Default -> stringResource(R.string.notification_type_default) 15 | Advanced -> stringResource(R.string.notification_type_advanced) 16 | 17 | } 18 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/OnDeviceFolderSortBy.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.DrawableRes 4 | import androidx.annotation.StringRes 5 | import app.kreate.android.R 6 | import me.knighthat.enums.TextView 7 | 8 | enum class OnDeviceFolderSortBy( 9 | @field:StringRes override val textId: Int, 10 | @field:DrawableRes override val iconId: Int 11 | ): TextView, Drawable { 12 | 13 | Title( R.string.sort_title, R.drawable.text ), 14 | 15 | Artist( R.string.sort_artist, R.drawable.artist ), 16 | 17 | Duration( R.string.sort_duration, R.drawable.time ); 18 | } 19 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PauseBetweenSongs.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class PauseBetweenSongs { 4 | `0`, 5 | `5`, 6 | `10`, 7 | `15`, 8 | `20`, 9 | `30`, 10 | `40`, 11 | `50`, 12 | `60`; 13 | 14 | val asSeconds: Int = this.name.toInt() 15 | 16 | val asMillis: Long = this.asSeconds * 1000L 17 | } 18 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PipModule.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class PipModule( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Cover( R.string.pipmodule_cover ) 12 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PlayEventsType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class PlayEventsType( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | MostPlayed( R.string.by_most_played_song ), 12 | LastPlayed( R.string.by_last_played_song ), 13 | CasualPlayed( R.string.by_casual_played_song ); 14 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PlayerBackgroundColors.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class PlayerBackgroundColors( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | CoverColor( R.string.bg_colors_background_from_cover ), 12 | 13 | ThemeColor( R.string.bg_colors_background_from_theme ), 14 | 15 | CoverColorGradient( R.string.bg_colors_gradient_background_from_cover ), 16 | 17 | ThemeColorGradient( R.string.bg_colors_gradient_background_from_theme ), 18 | 19 | BlurredCoverColor( R.string.bg_colors_blurred_cover_background ), 20 | 21 | ColorPalette( R.string.colorpalette ), 22 | 23 | AnimatedGradient( R.string.animatedgradient ); 24 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PlayerControlsType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class PlayerControlsType( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Essential( R.string.pcontrols_essential ), 12 | Modern( R.string.pcontrols_modern ); 13 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PlayerInfoType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class PlayerInfoType( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Essential( R.string.pcontrols_essential ), 12 | Modern( R.string.pcontrols_modern ); 13 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PlayerPlayButtonType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class PlayerPlayButtonType( 8 | val height: Int, 9 | val width: Int, 10 | @field:StringRes override val textId: Int 11 | ): TextView { 12 | 13 | Disabled( 60, 60, R.string.vt_disabled ), 14 | 15 | Default( 60, 60, R.string._default ), 16 | 17 | Rectangular( 70, 110, R.string.rectangular ), 18 | 19 | CircularRibbed( 100, 100, R.string.circular_ribbed ), 20 | 21 | Square( 80, 80, R.string.square ); 22 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PlayerPosition.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class PlayerPosition( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Top( R.string.position_top ), 12 | Bottom( R.string.position_bottom ); 13 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PlayerThumbnailSize.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class PlayerThumbnailSize( 8 | val size: Int, 9 | @field:StringRes override val textId: Int 10 | ): TextView { 11 | 12 | Small( 90, R.string.small ), 13 | 14 | Medium( 55, R.string.medium ), 15 | 16 | Big( 30, R.string.big ), 17 | 18 | Biggest( 20, R.string.biggest ), 19 | 20 | Expanded( 0, R.string.expanded ); 21 | } 22 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PlayerTimelineSize.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class PlayerTimelineSize( 8 | val size: Int, 9 | @field:StringRes override val textId: Int 10 | ): TextView { 11 | 12 | Small( 90, R.string.small ), 13 | 14 | Medium( 55, R.string.medium ), 15 | 16 | Big( 30, R.string.big ), 17 | 18 | Biggest( 20, R.string.biggest ), 19 | 20 | Expanded( 0, R.string.expanded ); 21 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PlayerTimelineType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class PlayerTimelineType( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Default( R.string._default ), 12 | 13 | Wavy( R.string.wavy_timeline ), 14 | 15 | PinBar( R.string.bodied_bar ), 16 | 17 | BodiedBar( R.string.pin_bar ), 18 | 19 | FakeAudioBar( R.string.fake_audio_bar ), 20 | 21 | ThinBar( R.string.thin_bar ), 22 | 23 | ColoredBar( R.string.colored_bar ); 24 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PlayerType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class PlayerType( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Essential( R.string.pcontrols_modern ), 12 | Modern( R.string.pcontrols_essential ); 13 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PlaylistSongsTypeFilter.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class PlaylistSongsTypeFilter { 4 | All, 5 | OnlineSongs, 6 | Videos, 7 | Favorites, 8 | Local, 9 | Unmatched, 10 | Downloaded, 11 | Cached, 12 | Explicit 13 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PlaylistSortBy.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.DrawableRes 4 | import androidx.annotation.StringRes 5 | import app.kreate.android.R 6 | import me.knighthat.enums.TextView 7 | 8 | enum class PlaylistSortBy( 9 | @field:StringRes override val textId: Int, 10 | @field:DrawableRes override val iconId: Int 11 | ): TextView, Drawable { 12 | 13 | MostPlayed( R.string.sort_listening_time, R.drawable.trending ), 14 | 15 | Name( R.string.sort_name, R.drawable.text ), 16 | 17 | DateAdded( R.string.sort_date_added, R.drawable.calendar ), 18 | 19 | SongCount( R.string.sort_songs_number, R.drawable.medical ); 20 | } 21 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PlaylistsType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class PlaylistsType { 4 | Playlist, 5 | PinnedPlaylist, 6 | MonthlyPlaylist, 7 | PipedPlaylist, 8 | YTPlaylist 9 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PopupType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class PopupType { 4 | Info, 5 | Error, 6 | Warning, 7 | Success 8 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/PrevNextSongs.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class PrevNextSongs { 4 | Hide, 5 | onesong, 6 | twosongs; 7 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/QueueSelection.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class QueueSelection { 4 | START_OF_QUEUE, CENTERED, END_OF_QUEUE, END_OF_QUEUE_WINDOWED 5 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/QueueType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class QueueType( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Essential( R.string.pcontrols_essential ), 12 | Modern( R.string.pcontrols_modern ); 13 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/RecommendationsNumber.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class RecommendationsNumber { 4 | `5`, 5 | `10`, 6 | `15`, 7 | `20`; 8 | 9 | fun toInt(): Int = this.name.toInt() 10 | } 11 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/Romanization.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class Romanization { 4 | Off, 5 | Original, 6 | Translated, 7 | Both 8 | } 9 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/SearchType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class SearchType { 4 | Online, 5 | Library, 6 | Gotolink; 7 | 8 | val index: Int 9 | get() = when (this) { 10 | Online -> 0 11 | Library -> 1 12 | Gotolink -> 2 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/SongsNumber.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class SongsNumber { 4 | `1`, 5 | `2`, 6 | `3`, 7 | `4`, 8 | `5`, 9 | `6`, 10 | `7`, 11 | `8`, 12 | `9`; 13 | 14 | fun toInt(): Int = this.name.toInt() 15 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/SwipeAnimations.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class SwipeAnimationNoThumbnail { 4 | Sliding, 5 | Fade, 6 | Scale, 7 | Carousel, 8 | Circle 9 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/ThumbnailCoverType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class ThumbnailCoverType( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Vinyl (R.string.cover_type_vinyl ), 12 | CD( R.string.cover_type_cd ), 13 | CDwithCover( R.string.cover_type_cd_with_cover ); 14 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/ThumbnailRoundness.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import androidx.compose.foundation.shape.RoundedCornerShape 5 | import androidx.compose.ui.graphics.Shape 6 | import androidx.compose.ui.unit.dp 7 | import app.kreate.android.R 8 | import me.knighthat.enums.TextView 9 | 10 | enum class ThumbnailRoundness( 11 | val shape: Shape, 12 | @field:StringRes override val textId: Int 13 | ): TextView { 14 | 15 | None( RoundedCornerShape(0.dp), R.string.none ), 16 | 17 | Light( RoundedCornerShape(8.dp), R.string.light ), 18 | 19 | Medium( RoundedCornerShape(12.dp), R.string.medium ), 20 | 21 | Heavy( RoundedCornerShape(16.dp), R.string.heavy ); 22 | } 23 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/ThumbnailType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class ThumbnailType( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | Essential( R.string.pcontrols_essential ), 12 | Modern( R.string.pcontrols_modern ); 13 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/TopPlaylistItems.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class MaxTopPlaylistItems { 4 | `10`, 5 | `20`, 6 | `30`, 7 | `40`, 8 | `50`, 9 | `70`, 10 | `90`, 11 | `100`, 12 | `150`, 13 | `200`; 14 | 15 | fun toInt(): Int = this.name.toInt() 16 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/TransitionEffect.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.annotation.StringRes 4 | import app.kreate.android.R 5 | import me.knighthat.enums.TextView 6 | 7 | enum class TransitionEffect( 8 | @field:StringRes override val textId: Int 9 | ): TextView { 10 | 11 | SlideVertical( R.string.te_slide_vertical ), 12 | 13 | SlideHorizontal( R.string.te_slide_horizontal ), 14 | 15 | Scale( R.string.te_scale ), 16 | 17 | Fade( R.string.te_fade ), 18 | 19 | Expand( R.string.te_expand ), 20 | 21 | None( R.string.none ); 22 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/UiType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.compose.runtime.Composable 4 | import it.fast4x.rimusic.utils.UiTypeKey 5 | import it.fast4x.rimusic.utils.rememberPreference 6 | 7 | enum class UiType { 8 | RiMusic, 9 | ViMusic; 10 | 11 | companion object { 12 | 13 | @Composable 14 | fun current(): UiType = rememberPreference( UiTypeKey, RiMusic ).value 15 | } 16 | 17 | @Composable 18 | fun isCurrent(): Boolean = current() == this 19 | 20 | @Composable 21 | fun isNotCurrent(): Boolean = !isCurrent() 22 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/ValidationType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class ValidationType { 4 | None, 5 | Text, 6 | Ip 7 | } 8 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/WallpaperType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.compose.runtime.Composable 4 | import me.knighthat.enums.TextView 5 | 6 | enum class WallpaperType: TextView { 7 | Home, 8 | Lockscreen, 9 | Both; 10 | 11 | override val text: String 12 | @Composable 13 | get() = this.name 14 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/enums/playerVisualizerType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class PlayerVisualizerType { 4 | Disabled, 5 | Fancy, 6 | Circular, 7 | Stacked, 8 | Full, 9 | Oneside, 10 | Doubleside, 11 | DoublesideCircular 12 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/extensions/connectivity/ConnectivityObserver.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.extensions.connectivity 2 | 3 | import kotlinx.coroutines.flow.Flow 4 | 5 | interface ConnectivityObserver { 6 | val isConnected: Flow 7 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/extensions/games/pacman/models/DialogState.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.extensions.games.pacman.models 2 | 3 | import androidx.compose.runtime.MutableState 4 | 5 | data class DialogState ( 6 | val shouldShow: MutableState, 7 | val message: MutableState, 8 | ) -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/extensions/games/pacman/models/EnemyMovementModel.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.extensions.games.pacman.models 2 | 3 | import androidx.compose.runtime.MutableState 4 | import androidx.compose.runtime.mutableStateOf 5 | import androidx.compose.ui.geometry.Offset 6 | 7 | data class EnemyMovementModel ( 8 | val redEnemyMovement: MutableState = mutableStateOf(Offset(0F, 0F)), 9 | val orangeEnemyMovement: MutableState = mutableStateOf(Offset(0F, 0F)) 10 | ) -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/extensions/games/pacman/models/GameStatsModel.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.extensions.games.pacman.models 2 | 3 | import androidx.compose.runtime.MutableState 4 | 5 | data class GameStatsModel( 6 | val CharacterXOffset: MutableState, 7 | val CharacterYOffset: MutableState, 8 | val isGameStarted: MutableState, 9 | val isReverseMode: MutableState 10 | 11 | ) -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/extensions/games/pacman/ui/theme/Color.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.extensions.games.pacman.ui.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val PacmanYellow = Color(0xFFFFFF00) 6 | val PacmanRed = Color(0xFFFD0000) 7 | val PacmanPink = Color(0xFFdea185) 8 | val PacmanGreen = Color(0xFF00ff00) 9 | val PacmanWhite = Color(0xFFFFFFFF) 10 | val PacmanBackground = Color(0xFF000000) 11 | val PacmanMazeColor = Color(0xFF0051ff) 12 | val PacmanOrange = Color(0xFFffa500) -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/extensions/games/pacman/ui/theme/Type.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.extensions.games.pacman.ui.theme 2 | 3 | import androidx.compose.material3.Typography 4 | import androidx.compose.ui.text.TextStyle 5 | import androidx.compose.ui.text.font.Font 6 | import androidx.compose.ui.text.font.FontFamily 7 | import androidx.compose.ui.text.font.FontWeight 8 | import androidx.compose.ui.unit.sp 9 | import app.kreate.android.R 10 | 11 | 12 | // Set of Material typography styles to start with 13 | val Typography = Typography( 14 | bodyMedium = TextStyle( 15 | fontFamily = FontFamily.Default, 16 | fontWeight = FontWeight.Normal, 17 | fontSize = 16.sp 18 | ) 19 | ) 20 | 21 | val HeaderFont = FontFamily(listOf(Font(R.font.pac_font))) -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/extensions/games/pacman/utils/GameConstants.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.extensions.games.pacman.utils 2 | 3 | object GameConstants { 4 | const val FOOD_COUNTER = 100 // amount of food 5 | var incrementValue = 75f // amount to move the character 6 | const val RED_ENEMY_SPEED = 3000 7 | const val ORANGE_ENEMY_SPEED = 2500 8 | 9 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/extensions/nextvisualizer/utils/FrameManager.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.extensions.nextvisualizer.utils 2 | 3 | class FrameManager { 4 | 5 | private var last: Long = 0 6 | private var span: Long = 0 7 | private var count: Float = 0f 8 | private var fps: Float = 0f 9 | 10 | fun tick() { 11 | val current = System.currentTimeMillis() 12 | span += current - last 13 | if (span > 1000) { 14 | fps = count / span * 1000f 15 | span = 0 16 | count = 0f 17 | } 18 | count++ 19 | last = current 20 | } 21 | 22 | fun fps() = fps 23 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/extensions/webpotoken/PoTokenException.kt: -------------------------------------------------------------------------------- 1 | package com.dd3boh.outertune.utils.potoken 2 | 3 | class PoTokenException(message: String) : Exception(message) 4 | 5 | // to be thrown if the WebView provided by the system is broken 6 | class BadWebViewException(message: String) : Exception(message) 7 | 8 | fun buildExceptionForJsError(error: String): Exception { 9 | return if (error.contains("SyntaxError")) 10 | BadWebViewException(error) 11 | else 12 | PoTokenException(error) 13 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/extensions/webpotoken/PoTokenResult.kt: -------------------------------------------------------------------------------- 1 | package com.dd3boh.outertune.utils.potoken 2 | 3 | class PoTokenResult( 4 | val playerRequestPoToken: String, 5 | val streamingDataPoToken: String, 6 | ) -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/extensions/youtubelogin/YoutubeSession.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.extensions.youtubelogin 2 | 3 | data class YoutubeSession( 4 | val cookie: String = "", 5 | val visitorData: String = "", 6 | val accountName: String = "", 7 | val accountEmail: String = "", 8 | val accountChannelHandle: String = "" 9 | ) 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/Artist.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.models 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | import it.fast4x.rimusic.cleanPrefix 7 | 8 | @Immutable 9 | @Entity 10 | data class Artist( 11 | @PrimaryKey val id: String, 12 | val name: String? = null, 13 | val thumbnailUrl: String? = null, 14 | val timestamp: Long? = null, 15 | val bookmarkedAt: Long? = null, 16 | val isYoutubeArtist: Boolean = false, 17 | ) { 18 | fun cleanName() = cleanPrefix( this.name ?: "" ) 19 | } 20 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/Event.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.models 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.ColumnInfo 5 | import androidx.room.Entity 6 | import androidx.room.ForeignKey 7 | import androidx.room.PrimaryKey 8 | 9 | @Immutable 10 | @Entity( 11 | foreignKeys = [ 12 | ForeignKey( 13 | entity = Song::class, 14 | parentColumns = ["id"], 15 | childColumns = ["songId"], 16 | onDelete = ForeignKey.CASCADE 17 | ) 18 | ] 19 | ) 20 | data class Event( 21 | @PrimaryKey(autoGenerate = true) val id: Long = 0, 22 | @ColumnInfo(index = true) val songId: String, 23 | var timestamp: Long, 24 | val playTime: Long 25 | ) 26 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/Format.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.models 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Entity 5 | import androidx.room.ForeignKey 6 | import androidx.room.PrimaryKey 7 | 8 | @Immutable 9 | @Entity( 10 | foreignKeys = [ 11 | ForeignKey( 12 | entity = Song::class, 13 | parentColumns = ["id"], 14 | childColumns = ["songId"], 15 | onDelete = ForeignKey.CASCADE 16 | ) 17 | ] 18 | ) 19 | data class Format( 20 | @PrimaryKey val songId: String, 21 | val itag: Int? = null, 22 | val mimeType: String? = null, 23 | val bitrate: Long? = null, 24 | val contentLength: Long? = null, 25 | val lastModified: Long? = null, 26 | val loudnessDb: Float? = null 27 | ) 28 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/Info.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.models 2 | 3 | data class Info( 4 | val id: String, 5 | val name: String?, 6 | val size: Int = 0 7 | ) 8 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/Lyrics.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.models 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Entity 5 | import androidx.room.ForeignKey 6 | import androidx.room.PrimaryKey 7 | 8 | @Immutable 9 | @Entity( 10 | foreignKeys = [ 11 | ForeignKey( 12 | entity = Song::class, 13 | parentColumns = ["id"], 14 | childColumns = ["songId"], 15 | onDelete = ForeignKey.CASCADE, 16 | ) 17 | ] 18 | ) 19 | class Lyrics( 20 | @PrimaryKey val songId: String, 21 | val fixed: String?, 22 | val synced: String?, 23 | ) 24 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/Playlist.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.models 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | import it.fast4x.rimusic.cleanPrefix 7 | 8 | @Immutable 9 | @Entity 10 | data class Playlist( 11 | @PrimaryKey(autoGenerate = true) val id: Long = 0, 12 | val name: String, 13 | val browseId: String? = null, 14 | val isEditable: Boolean = true, 15 | val isYoutubePlaylist: Boolean = false, 16 | ) { 17 | fun cleanName() = cleanPrefix( this.name ) 18 | } 19 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/PlaylistPreview.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.models 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Embedded 5 | 6 | @Immutable 7 | data class PlaylistPreview( 8 | @Embedded val playlist: Playlist, 9 | val songCount: Int 10 | ) 11 | 12 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/PlaylistWithSongs.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.models 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Embedded 5 | import androidx.room.Junction 6 | import androidx.room.Relation 7 | 8 | @Immutable 9 | data class PlaylistWithSongs( 10 | @Embedded val playlist: Playlist, 11 | @Relation( 12 | entity = Song::class, 13 | parentColumn = "id", 14 | entityColumn = "id", 15 | associateBy = Junction( 16 | value = SortedSongPlaylistMap::class, 17 | parentColumn = "playlistId", 18 | entityColumn = "songId" 19 | ) 20 | ) 21 | var songs: List 22 | ) 23 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/QueuedMediaItem.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.models 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.media3.common.MediaItem 5 | import androidx.room.ColumnInfo 6 | import androidx.room.Entity 7 | import androidx.room.PrimaryKey 8 | 9 | @Immutable 10 | @Entity 11 | class QueuedMediaItem( 12 | @PrimaryKey(autoGenerate = true) val id: Long = 0, 13 | @ColumnInfo(typeAffinity = ColumnInfo.BLOB) val mediaItem: MediaItem, 14 | var position: Long? 15 | ) 16 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/SearchQuery.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.models 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Entity 5 | import androidx.room.Index 6 | import androidx.room.PrimaryKey 7 | 8 | @Immutable 9 | @Entity( 10 | indices = [ 11 | Index( 12 | value = ["query"], 13 | unique = true 14 | ) 15 | ] 16 | ) 17 | data class SearchQuery( 18 | @PrimaryKey(autoGenerate = true) val id: Long = 0, 19 | val query: String 20 | ) 21 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/SongWithContentLength.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.models 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Embedded 5 | 6 | @Immutable 7 | data class SongWithContentLength( 8 | @Embedded val song: Song, 9 | val contentLength: Long? 10 | ) 11 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/SortedSongPlaylistMap.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.models 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.ColumnInfo 5 | import androidx.room.DatabaseView 6 | 7 | @Immutable 8 | @DatabaseView("SELECT * FROM SongPlaylistMap ORDER BY position") 9 | data class SortedSongPlaylistMap( 10 | @ColumnInfo(index = true) val songId: String, 11 | @ColumnInfo(index = true) val playlistId: Long, 12 | val position: Int 13 | ) 14 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/models/ui/UiMedia.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.models.ui 2 | 3 | import androidx.media3.common.MediaItem 4 | import it.fast4x.rimusic.service.modern.isLocal 5 | 6 | data class UiMedia( 7 | val id: String, 8 | val title: String, 9 | val artist: String, 10 | val duration: Long, 11 | val isLocal: Boolean 12 | ) 13 | 14 | fun MediaItem.toUiMedia(duration: Long) = UiMedia( 15 | id = mediaId, 16 | title = mediaMetadata.title?.toString() ?: "", 17 | artist = mediaMetadata.artist?.toString() ?: "", 18 | duration = duration, 19 | isLocal = isLocal 20 | ) -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/components/navigation/nav/HomeNavigation.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.ui.components.navigation.nav 2 | 3 | object HomeNavigation { 4 | 5 | 6 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/components/tab/toolbar/Button.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.ui.components.tab.toolbar 2 | 3 | import androidx.compose.runtime.Composable 4 | 5 | @FunctionalInterface 6 | interface Button { 7 | 8 | @Composable 9 | fun ToolBarButton() 10 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/components/tab/toolbar/Clickable.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.ui.components.tab.toolbar 2 | 3 | interface Clickable { 4 | 5 | /** 6 | * What happens when user taps on icon. 7 | */ 8 | fun onShortClick() 9 | 10 | /** 11 | * What happens when user holds this icon for a while. 12 | */ 13 | fun onLongClick() 14 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/components/tab/toolbar/Descriptive.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.ui.components.tab.toolbar 2 | 3 | import androidx.annotation.StringRes 4 | import me.knighthat.utils.Toaster 5 | 6 | interface Descriptive: Clickable { 7 | 8 | @get:StringRes 9 | val messageId: Int 10 | 11 | /** 12 | * What happens when user holds this icon for a while. 13 | * 14 | * By default, this will send out message 15 | */ 16 | override fun onLongClick() = Toaster.i(messageId) 17 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/components/tab/toolbar/Dialog.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.ui.components.tab.toolbar 2 | 3 | import androidx.compose.runtime.Composable 4 | 5 | interface Dialog { 6 | 7 | var isActive: Boolean 8 | @get:Composable 9 | val dialogTitle: String 10 | 11 | @Composable 12 | fun Render() 13 | 14 | /** 15 | * What happens when user taps on icon. 16 | * 17 | * By default, this action enables dialog 18 | * by assigning `true` to [isActive] 19 | */ 20 | fun onShortClick() { isActive = true } 21 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/components/tab/toolbar/Menu.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.ui.components.tab.toolbar 2 | 3 | import androidx.compose.runtime.Composable 4 | import it.fast4x.rimusic.enums.MenuStyle 5 | import it.fast4x.rimusic.ui.components.MenuState 6 | 7 | interface Menu { 8 | 9 | val menuState: MenuState 10 | 11 | var menuStyle:MenuStyle 12 | 13 | @Composable 14 | fun ListMenu() 15 | 16 | @Composable 17 | fun GridMenu() 18 | 19 | @Composable 20 | fun MenuComponent() 21 | 22 | fun openMenu() = menuState.display { MenuComponent() } 23 | 24 | fun closeMenu() = menuState.hide() 25 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/ui/components/tab/toolbar/MenuIcon.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.ui.components.tab.toolbar 2 | 3 | import androidx.compose.runtime.Composable 4 | import me.knighthat.component.menu.GridMenu 5 | import me.knighthat.component.menu.ListMenu 6 | 7 | interface MenuIcon: Icon { 8 | 9 | @get:Composable 10 | val menuIconTitle: String 11 | 12 | @Composable 13 | fun GridMenuItem() = GridMenu.Entry( menuIconTitle, { ToolBarButton() }, modifier, isEnabled, ::onShortClick ) 14 | 15 | @Composable 16 | fun ListMenuItem() = ListMenu.Entry( menuIconTitle, { ToolBarButton() }, modifier, isEnabled, ::onShortClick ) 17 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/utils/BitmapUtils.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.utils 2 | 3 | import android.content.Context 4 | import android.graphics.Bitmap 5 | import android.graphics.drawable.BitmapDrawable 6 | import coil.imageLoader 7 | import coil.request.ErrorResult 8 | import coil.request.ImageRequest 9 | import coil.request.SuccessResult 10 | 11 | suspend fun getBitmapFromUrl(context: Context, url: String): Bitmap { 12 | val loading = context.imageLoader 13 | val request = ImageRequest.Builder(context).data(url).allowHardware(false).build() 14 | val result = loading.execute(request) 15 | if(result is ErrorResult) { 16 | throw result.throwable 17 | } 18 | val drawable = (result as SuccessResult).drawable 19 | return (drawable as BitmapDrawable).bitmap 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/utils/Configuration.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.utils 2 | 3 | import android.content.res.Configuration 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.runtime.ReadOnlyComposable 6 | import androidx.compose.ui.platform.LocalConfiguration 7 | 8 | val isLandscape 9 | @Composable 10 | @ReadOnlyComposable 11 | get() = LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE 12 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/utils/CoroutineExtensions.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.utils 2 | 3 | import kotlinx.coroutines.CoroutineExceptionHandler 4 | import kotlinx.coroutines.CoroutineScope 5 | import kotlinx.coroutines.flow.Flow 6 | import kotlinx.coroutines.flow.collectLatest 7 | import kotlinx.coroutines.launch 8 | 9 | fun Flow.collect(scope: CoroutineScope, action: suspend (value: T) -> Unit) { 10 | scope.launch { 11 | collect(action) 12 | } 13 | } 14 | 15 | fun Flow.collectLatest(scope: CoroutineScope, action: suspend (value: T) -> Unit) { 16 | scope.launch { 17 | collectLatest(action) 18 | } 19 | } 20 | 21 | val SilentHandler = CoroutineExceptionHandler { _, _ -> } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/utils/IsCompositionLaunched.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.utils 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.runtime.LaunchedEffect 5 | import androidx.compose.runtime.getValue 6 | import androidx.compose.runtime.mutableStateOf 7 | import androidx.compose.runtime.remember 8 | import androidx.compose.runtime.setValue 9 | 10 | @Composable 11 | fun isCompositionLaunched(): Boolean { 12 | var isLaunched by remember { mutableStateOf(false) } 13 | LaunchedEffect(Unit) { 14 | isLaunched = true 15 | } 16 | return isLaunched 17 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/utils/MenuItemColors.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.utils 2 | 3 | import androidx.compose.material3.MenuItemColors 4 | import androidx.compose.runtime.Composable 5 | import it.fast4x.rimusic.ui.styling.favoritesIcon 6 | import it.fast4x.rimusic.colorPalette 7 | 8 | @Composable 9 | fun menuItemColors(): MenuItemColors { 10 | return MenuItemColors( 11 | leadingIconColor = colorPalette().favoritesIcon, 12 | trailingIconColor = colorPalette().favoritesIcon, 13 | textColor = colorPalette().textSecondary, 14 | disabledTextColor = colorPalette().text, 15 | disabledLeadingIconColor = colorPalette().text, 16 | disabledTrailingIconColor = colorPalette().text, 17 | ) 18 | 19 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/utils/NavControllerUtils.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.utils 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.navigation.NavController 5 | 6 | 7 | /* 8 | @Composable 9 | fun getCurrentRoute (navController: NavController): String? { 10 | return navController.currentBackStackEntry?.destination?.route 11 | } 12 | */ 13 | 14 | 15 | @Composable 16 | fun getCurrentRoute (navController: NavController): String? { 17 | return navController.currentDestination?.route 18 | // or it's same 19 | //return navController.currentBackStackEntry?.destination?.route 20 | } 21 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/it/fast4x/rimusic/utils/SmoothScrollToTop.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.utils 2 | 3 | import androidx.compose.foundation.lazy.LazyListState 4 | import androidx.compose.foundation.lazy.grid.LazyGridState 5 | 6 | suspend fun LazyGridState.smoothScrollToTop() { 7 | if (firstVisibleItemIndex > layoutInfo.visibleItemsInfo.size) { 8 | scrollToItem(layoutInfo.visibleItemsInfo.size) 9 | } 10 | animateScrollToItem(0) 11 | } 12 | 13 | suspend fun LazyListState.smoothScrollToTop() { 14 | if (firstVisibleItemIndex > layoutInfo.visibleItemsInfo.size) { 15 | scrollToItem(layoutInfo.visibleItemsInfo.size) 16 | } 17 | animateScrollToItem(0) 18 | } 19 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/component/ImportFromFile.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.component 2 | 3 | import android.content.ActivityNotFoundException 4 | import android.net.Uri 5 | import androidx.activity.compose.ManagedActivityResultLauncher 6 | import app.kreate.android.R 7 | import me.knighthat.utils.Toaster 8 | 9 | abstract class ImportFromFile( 10 | private val launcher: ManagedActivityResultLauncher, Uri?> 11 | ) { 12 | abstract val supportedMimes: Array 13 | 14 | fun onShortClick() { 15 | try { 16 | launcher.launch( supportedMimes ) 17 | } catch ( _: ActivityNotFoundException ) { 18 | Toaster.e( R.string.info_not_find_app_open_doc ) 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/component/dialog/InputDialogConstraints.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.component.dialog 2 | 3 | object InputDialogConstraints { 4 | 5 | /** 6 | * This REGEX pattern allows all characters 7 | */ 8 | const val ALL = ".*"; 9 | 10 | /** 11 | * This REGEX pattern only allows ASCII characters and numbers 12 | */ 13 | const val NO_SPECIAL_CHARS = "^[a-zA-Z0-9 ]+\$" 14 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/component/menu/MenuConstants.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.component.menu 2 | 3 | object MenuConstants { 4 | 5 | /** 6 | * Maximum height can the content box take of the screen. 7 | * Percentage format with value ranging from 0.0 to 1.0 8 | * with 0.0 means 0% and 1.0 means 100%. 9 | * 10 | * **This value should only be use for content box** 11 | */ 12 | const val CONTENT_HEIGHT_FRACTION = .4f 13 | 14 | const val CONTENT_HORIZONTAL_PADDING = 8 15 | 16 | const val CONTENT_TOP_PADDING = 20 17 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/database/ext/EventWithSong.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.database.ext 2 | 3 | import androidx.room.Embedded 4 | import androidx.room.Relation 5 | import it.fast4x.rimusic.models.Event 6 | import it.fast4x.rimusic.models.Song 7 | 8 | data class EventWithSong( 9 | @Embedded val event: Event, 10 | @Relation( 11 | entity = Song::class, 12 | parentColumn = "songId", 13 | entityColumn = "id" 14 | ) 15 | val song: Song 16 | ) -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/database/ext/FormatWithSong.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.database.ext 2 | 3 | import androidx.room.Embedded 4 | import it.fast4x.rimusic.models.Format 5 | import it.fast4x.rimusic.models.Song 6 | 7 | data class FormatWithSong( 8 | @Embedded val format: Format, 9 | @Embedded val song: Song 10 | ) -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/database/migration/From11To12Migration.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.database.migration 2 | 3 | import androidx.room.RenameTable 4 | import androidx.room.migration.AutoMigrationSpec 5 | 6 | @RenameTable("SongInPlaylist", "SongPlaylistMap") 7 | @RenameTable("SortedSongInPlaylist", "SortedSongPlaylistMap") 8 | class From11To12Migration : AutoMigrationSpec -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/database/migration/From20To21Migration.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.database.migration 2 | 3 | import androidx.room.DeleteColumn 4 | import androidx.room.migration.AutoMigrationSpec 5 | 6 | @DeleteColumn.Entries( 7 | DeleteColumn("Artist", "shuffleVideoId"), 8 | DeleteColumn("Artist", "shufflePlaylistId"), 9 | DeleteColumn("Artist", "radioVideoId"), 10 | DeleteColumn("Artist", "radioPlaylistId"), 11 | ) 12 | class From20To21Migration : AutoMigrationSpec -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/database/migration/From21To22Migration.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.database.migration 2 | 3 | import androidx.room.DeleteColumn 4 | import androidx.room.migration.AutoMigrationSpec 5 | 6 | @DeleteColumn.Entries(DeleteColumn("Artist", "info")) 7 | class From21To22Migration : AutoMigrationSpec -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/database/migration/From23To24Migration.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.database.migration 2 | 3 | import androidx.room.migration.Migration 4 | import androidx.sqlite.db.SupportSQLiteDatabase 5 | 6 | class From23To24Migration : Migration(23, 24) { 7 | 8 | override fun migrate(db: SupportSQLiteDatabase) { 9 | try { 10 | db.execSQL("ALTER TABLE SongPlaylistMap ADD COLUMN setVideoId TEXT;") 11 | } catch (e: Exception) { 12 | println("Database From23To24Migration error ${e.stackTraceToString()}") 13 | } 14 | 15 | } 16 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/database/migration/From24To25Migration.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.database.migration 2 | 3 | import androidx.room.migration.Migration 4 | import androidx.sqlite.db.SupportSQLiteDatabase 5 | 6 | class From24To25Migration : Migration(24, 25) { 7 | 8 | override fun migrate(db: SupportSQLiteDatabase) { 9 | try { 10 | db.execSQL("ALTER TABLE Playlist ADD COLUMN isEditable INTEGER NOT NULL DEFAULT 0;") 11 | } catch (e: Exception) { 12 | println("Database From24To25Migration error ${e.stackTraceToString()}") 13 | } 14 | 15 | } 16 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/database/migration/From25To26Migration.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.database.migration 2 | 3 | import androidx.room.migration.Migration 4 | import androidx.sqlite.db.SupportSQLiteDatabase 5 | 6 | class From25To26Migration : Migration(25, 26) { 7 | 8 | override fun migrate(db: SupportSQLiteDatabase) { 9 | try { 10 | db.execSQL("ALTER TABLE Playlist ADD COLUMN isYoutubePlaylist INTEGER NOT NULL DEFAULT 0;") 11 | } catch (e: Exception) { 12 | println("Database From25To26Migration error ${e.stackTraceToString()}") 13 | } 14 | 15 | } 16 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/database/migration/From3To4Migration.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.database.migration 2 | 3 | import androidx.room.DeleteTable 4 | import androidx.room.migration.AutoMigrationSpec 5 | 6 | @DeleteTable.Entries(DeleteTable(tableName = "QueuedMediaItem")) 7 | class From3To4Migration : AutoMigrationSpec -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/database/migration/From7To8Migration.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.database.migration 2 | 3 | import androidx.room.RenameColumn 4 | import androidx.room.migration.AutoMigrationSpec 5 | 6 | @RenameColumn.Entries(RenameColumn("Song", "albumInfoId", "albumId")) 7 | class From7To8Migration : AutoMigrationSpec -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/enums/TextView.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.enums 2 | 3 | import androidx.annotation.StringRes 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.res.stringResource 6 | 7 | interface TextView { 8 | 9 | @get:StringRes 10 | val textId: Int 11 | get() = throw NotImplementedError(""" 12 | This setting uses [${this::class.simpleName}#text] directly 13 | or its [${this::class.simpleName}#textId] hasn't initialized! 14 | """.trimIndent()) 15 | 16 | val text: String 17 | @Composable 18 | get() = stringResource( this.textId ) 19 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/utils/DurationUtils.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.utils 2 | 3 | object DurationUtils { 4 | 5 | /** 6 | * Human-readable format of "HH:mm:ss" 7 | */ 8 | private val hhmmssRegex = Regex("^\\d{1,2}:\\d{2}:\\d{2}$") 9 | 10 | /** 11 | * Human-readable format of "mm:ss" 12 | */ 13 | private val mmssRegex = Regex("^\\d{1,2}:\\d{2}$") 14 | 15 | fun isHumanReadable( duration: String ) = 16 | hhmmssRegex.matches( duration ) || mmssRegex.matches( duration ) 17 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/kotlin/me/knighthat/utils/Repository.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.utils 2 | 3 | import app.kreate.android.BuildConfig 4 | 5 | object Repository { 6 | 7 | const val GITHUB = "https://github.com" 8 | const val GITHUB_API = "https://api.github.com" 9 | 10 | const val OWNER = "knighthat" 11 | const val REPO = "$OWNER/${BuildConfig.APP_NAME}" 12 | const val REPO_URL = "$GITHUB/$REPO" 13 | 14 | const val LATEST_TAG_URL = "$REPO/releases/latest" 15 | } -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable-anydpi/locked.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable-anydpi/search_circle.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable-anydpi/unlocked.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable-nodpi/a13shape.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/drawable-nodpi/a13shape.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable-nodpi/ghost_orange.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/drawable-nodpi/ghost_orange.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable-nodpi/ghost_red.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/drawable-nodpi/ghost_red.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable-nodpi/ghost_reverse.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/drawable-nodpi/ghost_reverse.webp -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable-nodpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/drawable-nodpi/ic_launcher.png -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable-nodpi/vinyl_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/drawable-nodpi/vinyl_background.png -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/add.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 20 | 21 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/alert_circle.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/arrow_down.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/arrow_forward.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 20 | 21 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/arrow_left.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/arrow_right.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/arrow_up.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/bookmark.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/bookmark_outline.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/burger.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/calendar_clear.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/checked_filled.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/checkmark.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/chevron_back.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/chevron_down.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/chevron_forward.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/chevron_up.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/close.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/copy.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/droplet.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/ellipsis_horizontal.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/ellipsis_vertical.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/explicit.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/export_outline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/folder.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/heart.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/heart_outline.xml: -------------------------------------------------------------------------------- 1 | 6 | 12 | 13 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/history.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/horizontal_bold_line.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/horizontal_bold_line_rounded.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/horizontal_straight_line.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/image.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/images_sharp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/import_outline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/infinite.xml: -------------------------------------------------------------------------------- 1 | 6 | 12 | 18 | 19 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/logo_youtube.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/open.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/pause.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/play.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/play_forward.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/play_skip_back.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/play_skip_forward.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/query_stats.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/refresh.xml: -------------------------------------------------------------------------------- 1 | 6 | 12 | 19 | 20 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/refresh_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/reorder.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 20 | 21 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/search.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/share_social.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/sleep.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/time.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/trash.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/trending.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 20 | 21 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/unchecked_outline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/up_right_arrow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/update.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/drawable/volume_up.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/font/pac_font.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/font/pac_font.TTF -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/font/poppins_w300.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/font/poppins_w300.ttf -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/font/poppins_w400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/font/poppins_w400.ttf -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/font/poppins_w500.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/font/poppins_w500.ttf -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/font/poppins_w600.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/font/poppins_w600.ttf -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/font/poppins_w700.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/font/poppins_w700.ttf -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/font/rubik_w300.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/font/rubik_w300.ttf -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/font/rubik_w400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/font/rubik_w400.ttf -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/font/rubik_w500.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/font/rubik_w500.ttf -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/font/rubik_w600.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/font/rubik_w600.ttf -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/font/rubik_w700.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/font/rubik_w700.ttf -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-hdpi/ic_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/mipmap-hdpi/ic_banner.png -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-mdpi/ic_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/mipmap-mdpi/ic_banner.png -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-xhdpi/ic_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/mipmap-xhdpi/ic_banner.png -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-xxhdpi/ic_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_banner.png -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_banner.png -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/resources.properties: -------------------------------------------------------------------------------- 1 | unqualifiedResLocale=en -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ffffff 4 | #08041D 5 | 6 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/values/ic_banner_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #EE0C0C 4 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #58cc86 4 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/xml/automotive_app_desc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/xml/player_horizontal_widget_info.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | -------------------------------------------------------------------------------- /composeApp/src/androidMain/res/xml/player_vertical_widget_info.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/drawable/arrow_forward.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 20 | 21 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/drawable/arrow_left.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/drawable/bookmark.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/drawable/bookmark_outline.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/drawable/chevron_down.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/drawable/chevron_up.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/drawable/dice.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/commonMain/composeResources/drawable/dice.webp -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/drawable/loader.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/commonMain/composeResources/drawable/loader.webp -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/drawable/pause.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/drawable/pin.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/commonMain/composeResources/drawable/pin.webp -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/drawable/play.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/drawable/play_skip_back.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/drawable/play_skip_forward.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/composeResources/drawable/share_social.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/database/entities/Album.kt: -------------------------------------------------------------------------------- 1 | package database.entities 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | 7 | @Immutable 8 | @Entity 9 | data class Album( 10 | @PrimaryKey val id: String, 11 | val title: String? = null, 12 | val thumbnailUrl: String? = null, 13 | val year: String? = null, 14 | val authorsText: String? = null, 15 | val shareUrl: String? = null, 16 | val timestamp: Long? = null, 17 | val bookmarkedAt: Long? = null 18 | ) { 19 | fun toggleBookmark(): Album { 20 | return copy( 21 | bookmarkedAt = if (bookmarkedAt == null) System.currentTimeMillis() else null 22 | ) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/database/entities/Artist.kt: -------------------------------------------------------------------------------- 1 | package database.entities 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | 7 | @Immutable 8 | @Entity 9 | data class Artist( 10 | @PrimaryKey val id: String, 11 | val name: String? = null, 12 | val thumbnailUrl: String? = null, 13 | val timestamp: Long? = null, 14 | val bookmarkedAt: Long? = null, 15 | ) 16 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/database/entities/Event.kt: -------------------------------------------------------------------------------- 1 | package database.entities 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.ColumnInfo 5 | import androidx.room.Entity 6 | import androidx.room.ForeignKey 7 | import androidx.room.PrimaryKey 8 | 9 | @Immutable 10 | @Entity( 11 | foreignKeys = [ 12 | ForeignKey( 13 | entity = Song::class, 14 | parentColumns = ["id"], 15 | childColumns = ["songId"], 16 | onDelete = ForeignKey.CASCADE 17 | ) 18 | ] 19 | ) 20 | data class Event( 21 | @PrimaryKey(autoGenerate = true) val id: Long = 0, 22 | @ColumnInfo(index = true) val songId: String, 23 | var timestamp: Long, 24 | val playTime: Long 25 | ) 26 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/database/entities/Format.kt: -------------------------------------------------------------------------------- 1 | package database.entities 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Entity 5 | import androidx.room.ForeignKey 6 | import androidx.room.PrimaryKey 7 | 8 | @Immutable 9 | @Entity( 10 | foreignKeys = [ 11 | ForeignKey( 12 | entity = Song::class, 13 | parentColumns = ["id"], 14 | childColumns = ["songId"], 15 | onDelete = ForeignKey.CASCADE 16 | ) 17 | ] 18 | ) 19 | data class Format( 20 | @PrimaryKey val songId: String, 21 | val itag: Int? = null, 22 | val mimeType: String? = null, 23 | val bitrate: Long? = null, 24 | val contentLength: Long? = null, 25 | val lastModified: Long? = null, 26 | val loudnessDb: Float? = null 27 | ) 28 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/database/entities/Lyrics.kt: -------------------------------------------------------------------------------- 1 | package database.entities 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Entity 5 | import androidx.room.ForeignKey 6 | import androidx.room.PrimaryKey 7 | 8 | @Immutable 9 | @Entity( 10 | foreignKeys = [ 11 | ForeignKey( 12 | entity = Song::class, 13 | parentColumns = ["id"], 14 | childColumns = ["songId"], 15 | onDelete = ForeignKey.CASCADE, 16 | ) 17 | ] 18 | ) 19 | class Lyrics( 20 | @PrimaryKey val songId: String, 21 | val fixed: String?, 22 | val synced: String?, 23 | ) 24 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/database/entities/Playlist.kt: -------------------------------------------------------------------------------- 1 | package database.entities 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | 7 | @Immutable 8 | @Entity 9 | data class Playlist( 10 | @PrimaryKey(autoGenerate = true) val id: Long = 0, 11 | val name: String, 12 | val browseId: String? = null 13 | ) 14 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/database/entities/QueuedMediaItem.kt: -------------------------------------------------------------------------------- 1 | package database.entities 2 | 3 | /* 4 | import androidx.compose.runtime.Immutable 5 | import androidx.room.ColumnInfo 6 | import androidx.room.Entity 7 | import androidx.room.PrimaryKey 8 | import androidx.media3.common.MediaItem 9 | 10 | @Immutable 11 | @Entity 12 | class QueuedMediaItem( 13 | @PrimaryKey(autoGenerate = true) val id: Long = 0, 14 | @ColumnInfo(typeAffinity = ColumnInfo.BLOB) val mediaItem: MediaItem, 15 | var position: Long? 16 | ) 17 | */ -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/database/entities/SearchQuery.kt: -------------------------------------------------------------------------------- 1 | package database.entities 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Entity 5 | import androidx.room.Index 6 | import androidx.room.PrimaryKey 7 | 8 | @Immutable 9 | @Entity( 10 | indices = [ 11 | Index( 12 | value = ["query"], 13 | unique = true 14 | ) 15 | ] 16 | ) 17 | data class SearchQuery( 18 | @PrimaryKey(autoGenerate = true) val id: Long = 0, 19 | val query: String 20 | ) 21 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/database/entities/SongEntity.kt: -------------------------------------------------------------------------------- 1 | package database.entities 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.Embedded 5 | 6 | @Immutable 7 | data class SongEntity( 8 | @Embedded val song: Song, 9 | val contentLength: Long? = null, 10 | val albumTitle: String? = null, 11 | ) 12 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/database/entities/SortedSongPlaylistMap.kt: -------------------------------------------------------------------------------- 1 | package database.entities 2 | 3 | import androidx.compose.runtime.Immutable 4 | import androidx.room.ColumnInfo 5 | import androidx.room.DatabaseView 6 | 7 | @Immutable 8 | @DatabaseView("SELECT * FROM SongPlaylistMap ORDER BY position") 9 | data class SortedSongPlaylistMap( 10 | @ColumnInfo(index = true) val songId: String, 11 | @ColumnInfo(index = true) val playlistId: Long, 12 | val position: Int 13 | ) 14 | -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/it/fast4x/rimusic/Greeting.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic 2 | 3 | class Greeting { 4 | private val platform = it.fast4x.rimusic.getPlatform() 5 | 6 | fun greet(): String { 7 | return "Hello, ${platform.name}!" 8 | } 9 | } -------------------------------------------------------------------------------- /composeApp/src/commonMain/kotlin/it/fast4x/rimusic/Platform.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic 2 | 3 | interface Platform { 4 | val name: String 5 | } 6 | 7 | expect fun getPlatform(): Platform -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/database/getMusicDatabase.kt: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | import androidx.room.Room 4 | import androidx.room.RoomDatabase 5 | import java.io.File 6 | 7 | fun getDesktopDatabaseBuilder(): RoomDatabase.Builder { 8 | val dbFile = File(System.getProperty("java.io.tmpdir"), "rimusic.db") 9 | return Room.databaseBuilder( 10 | name = dbFile.absolutePath, 11 | ) 12 | } 13 | 14 | val MusicDatabaseDesktop: MusicDatabaseDao 15 | get() = getRoomDatabase(getDesktopDatabaseBuilder()).getDao() 16 | 17 | val DB = MusicDatabaseDesktop -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/Platform.jvm.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic 2 | 3 | class JVMPlatform: Platform { 4 | override val name: String = "Java ${System.getProperty("java.version")}" 5 | } 6 | 7 | actual fun getPlatform(): Platform = JVMPlatform() -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/enums/ColorPaletteMode.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class ColorPaletteMode { 4 | Light, 5 | Dark, 6 | PitchBlack, 7 | System 8 | } -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/enums/ColorPaletteName.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class ColorPaletteName { 4 | Default, 5 | Dynamic, 6 | PureBlack, 7 | ModernBlack, 8 | MaterialYou, 9 | Customized 10 | } -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/enums/FontType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class FontType { 4 | Rubik, 5 | Poppins 6 | } -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/enums/PageType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | enum class PageType { 4 | ARTIST, 5 | ALBUM, 6 | PLAYLIST, 7 | MOOD, 8 | QUICKPICS 9 | } -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/enums/ThumbnailRoundness.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.enums 2 | 3 | import androidx.compose.foundation.shape.RoundedCornerShape 4 | import androidx.compose.ui.graphics.RectangleShape 5 | import androidx.compose.ui.graphics.Shape 6 | import androidx.compose.ui.unit.dp 7 | 8 | enum class ThumbnailRoundness { 9 | None, 10 | Light, 11 | Medium, 12 | Heavy; 13 | 14 | fun shape(): Shape { 15 | return when (this) { 16 | None -> RectangleShape 17 | Light -> RoundedCornerShape(8.dp) 18 | Medium -> RoundedCornerShape(12.dp) 19 | Heavy -> RoundedCornerShape(16.dp) 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/models/PipedSession.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.models 2 | 3 | import io.ktor.http.Url 4 | import it.fast4x.piped.models.authenticatedWith 5 | 6 | data class PipedSession( 7 | var instanceName: String, 8 | var apiBaseUrl: Url, 9 | var token: String, 10 | var username: String 11 | ) { 12 | 13 | fun toApiSession() = apiBaseUrl authenticatedWith token 14 | 15 | fun serialize() = "$instanceName|$apiBaseUrl|$token|$username" 16 | companion object { 17 | fun deserialize(serialized: String) = serialized.split("|").let { 18 | PipedSession(it[0], Url(it[1]), it[2], it[3]) 19 | } 20 | } 21 | } 22 | 23 | val String.toPipedSession: PipedSession 24 | get() = this.split("|").let { 25 | PipedSession(it[0], Url(it[1]), it[2], it[3]) 26 | } 27 | -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/player/exception/Catch.kt: -------------------------------------------------------------------------------- 1 | package exception 2 | 3 | fun catch(body: () -> Unit) = runCatching { body() }.onFailure { println(it.localizedMessage) }.getOrNull() ?: Unit -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/player/extension/Long.kt: -------------------------------------------------------------------------------- 1 | package extension 2 | 3 | import java.util.concurrent.TimeUnit 4 | 5 | fun Long.formatTimestamp(): String { 6 | val hours = TimeUnit.MILLISECONDS.toHours(this) 7 | val minutes = TimeUnit.MILLISECONDS.toMinutes(this) - TimeUnit.HOURS.toMinutes(hours) 8 | val seconds = TimeUnit.MILLISECONDS.toSeconds(this) - TimeUnit.MINUTES.toSeconds(minutes) - TimeUnit.HOURS.toSeconds(hours) 9 | return String.format("%02d:%02d:%02d", hours, minutes, seconds) 10 | } -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/player/player/PlayerController.kt: -------------------------------------------------------------------------------- 1 | package player 2 | 3 | import kotlinx.coroutines.flow.StateFlow 4 | 5 | interface PlayerController { 6 | val state: StateFlow 7 | fun load(url: String) 8 | fun play() 9 | fun pause() 10 | fun stop() 11 | fun dispose() 12 | fun seekTo(timestamp: Long) 13 | fun setVolume(value: Float) 14 | fun toggleSound() 15 | } -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/player/player/PlayerState.kt: -------------------------------------------------------------------------------- 1 | package player 2 | 3 | data class PlayerState( 4 | val isPlaying: Boolean = false, 5 | val isMuted: Boolean = false, 6 | val volume: Float = .5f, 7 | val timestamp: Long = 0L, 8 | val duration: Long = 0L, 9 | ) -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/player/player/component/ComponentContainer.kt: -------------------------------------------------------------------------------- 1 | package player.component 2 | 3 | import androidx.compose.foundation.layout.Box 4 | import androidx.compose.foundation.layout.fillMaxSize 5 | import androidx.compose.runtime.Composable 6 | import androidx.compose.ui.Alignment 7 | import androidx.compose.ui.Modifier 8 | import androidx.compose.ui.awt.SwingPanel 9 | import androidx.compose.ui.graphics.Color 10 | import java.awt.Component 11 | 12 | @Composable 13 | fun ComponentContainer(modifier: Modifier = Modifier, component: Component) { 14 | Box(modifier = modifier, contentAlignment = Alignment.Center) { 15 | SwingPanel( 16 | background = Color.Transparent, 17 | modifier = Modifier.fillMaxSize(), 18 | factory = { component } 19 | ) 20 | } 21 | } -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/player/player/component/ComponentRenderer.kt: -------------------------------------------------------------------------------- 1 | package player.component 2 | 3 | import java.awt.Component 4 | 5 | interface ComponentRenderer { 6 | val component: Component 7 | } -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/player/player/frame/FrameRenderer.kt: -------------------------------------------------------------------------------- 1 | package player.frame 2 | 3 | import kotlinx.coroutines.flow.StateFlow 4 | 5 | interface FrameRenderer { 6 | val size: StateFlow> 7 | val bytes: StateFlow 8 | } -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/player/vlcj/VlcjComponentController.kt: -------------------------------------------------------------------------------- 1 | package vlcj 2 | 3 | import player.PlayerController 4 | import player.component.ComponentRenderer 5 | import java.awt.Canvas 6 | 7 | class VlcjComponentController constructor( 8 | private val controller: VlcjController = VlcjController(), 9 | ) : ComponentRenderer, PlayerController by controller { 10 | 11 | override val component by lazy { Canvas() } 12 | 13 | private val surface by lazy { controller.factory.videoSurfaces().newVideoSurface(component) } 14 | 15 | override fun load(url: String) { 16 | runCatching { 17 | controller.load(url) 18 | controller.player?.videoSurface()?.set(surface) 19 | }.onFailure { 20 | it.printStackTrace() 21 | 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/styling/Dimensions.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.styling 2 | 3 | import androidx.compose.ui.unit.dp 4 | 5 | object Dimensions { 6 | val itemsVerticalPadding = 8.dp 7 | val layoutColumnTopPadding = 10.dp 8 | val layoutColumnBottomPadding = 40.dp 9 | val layoutColumnsHorizontalPadding = 10.dp 10 | val layoutColumnBottomSpacer = 100.dp 11 | val itemInHorizontalGridWidth = 200.dp 12 | 13 | 14 | val albumThumbnailSize = 100.dp 15 | val artistThumbnailSize = 100.dp 16 | val playlistThumbnailSize = 100.dp 17 | val songThumbnailSize = 100.dp 18 | 19 | val fadeSpacingTop = 30.dp 20 | val fadeSpacingBottom = 64.dp 21 | } -------------------------------------------------------------------------------- /composeApp/src/desktopMain/kotlin/it/fast4x/rimusic/ui/theme/Typography.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.rimusic.ui.theme 2 | 3 | import androidx.compose.material3.Typography 4 | import androidx.compose.ui.text.TextStyle 5 | import androidx.compose.ui.text.font.FontFamily 6 | import androidx.compose.ui.text.font.FontWeight 7 | import androidx.compose.ui.unit.sp 8 | 9 | val Typography = Typography( 10 | bodyLarge = TextStyle( 11 | fontFamily = FontFamily.Default, 12 | fontWeight = FontWeight.Normal, 13 | fontSize = 16.sp, 14 | lineHeight = 24.sp, 15 | letterSpacing = 0.5.sp 16 | ) 17 | ) -------------------------------------------------------------------------------- /composeApp/src/main/res/drawable/preset0.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/main/res/drawable/preset0.webp -------------------------------------------------------------------------------- /composeApp/src/main/res/drawable/preset1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/main/res/drawable/preset1.webp -------------------------------------------------------------------------------- /composeApp/src/main/res/drawable/preset2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/main/res/drawable/preset2.webp -------------------------------------------------------------------------------- /composeApp/src/main/res/drawable/preset3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/main/res/drawable/preset3.webp -------------------------------------------------------------------------------- /composeApp/src/main/res/drawable/preset4.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/main/res/drawable/preset4.webp -------------------------------------------------------------------------------- /composeApp/src/main/res/drawable/preset5.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/composeApp/src/main/res/drawable/preset5.webp -------------------------------------------------------------------------------- /crowdin.yml: -------------------------------------------------------------------------------- 1 | files: 2 | - source: /composeApp/src/androidMain/res/values/strings.xml 3 | translation: /composeApp/src/androidMain/res/values-%two_letters_code%/strings.xml 4 | - source: /docs/res/values/strings.xml 5 | translation: /docs/res/values-%two_letters_code%/strings.xml 6 | -------------------------------------------------------------------------------- /extensions/innertube/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/clients/YouTubeContext.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.clients 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class YouTubeContext( 7 | val client: Client, 8 | val thirdParty: ThirdParty? = null, 9 | ) { 10 | @Serializable 11 | data class Client( 12 | val clientName: String, 13 | val clientVersion: String, 14 | val gl: String, 15 | val hl: String, 16 | val visitorData: String?, 17 | ) 18 | 19 | @Serializable 20 | data class ThirdParty( 21 | val embedUrl: String, 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/clients/YouTubeLocale.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.clients 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class YouTubeLocale( 7 | val gl: String, // geolocation 8 | val hl: String, // host language 9 | ) 10 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/AccountInfo.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | data class AccountInfo( 4 | val name: String?, 5 | val email: String?, 6 | val channelHandle: String?, 7 | val thumbnailUrl: String? 8 | ) 9 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/BadgesRenderer.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class Badges( 7 | val musicInlineBadgeRenderer: MusicInlineBadgeRenderer?, 8 | ) { 9 | @Serializable 10 | data class MusicInlineBadgeRenderer( 11 | val icon: Icon, 12 | ) { 13 | @Serializable 14 | data class Icon( 15 | val iconType: String, 16 | ) 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/ButtonRenderer.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class ButtonRenderer( 7 | val navigationEndpoint: NavigationEndpoint? 8 | ) 9 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/Continuation.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.Serializable 5 | import kotlinx.serialization.json.JsonNames 6 | 7 | @OptIn(ExperimentalSerializationApi::class) 8 | @Serializable 9 | data class Continuation( 10 | @JsonNames("nextContinuationData", "nextRadioContinuationData") 11 | val nextContinuationData: Data? 12 | ) { 13 | @Serializable 14 | data class Data( 15 | val continuation: String? 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/ContinuationResponse.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.Serializable 5 | import kotlinx.serialization.json.JsonNames 6 | 7 | @OptIn(ExperimentalSerializationApi::class) 8 | @Serializable 9 | data class ContinuationResponse( 10 | val continuationContents: ContinuationContents?, 11 | ) { 12 | @Serializable 13 | data class ContinuationContents( 14 | @JsonNames("musicPlaylistShelfContinuation") 15 | val musicShelfContinuation: MusicShelfRenderer?, 16 | val playlistPanelContinuation: NextResponse.MusicQueueRenderer.Content.PlaylistPanelRenderer?, 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/CreatePlaylistResponse.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class CreatePlaylistResponse( 7 | val playlistId: String 8 | ) 9 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/GetQueueResponse.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class GetQueueResponse( 7 | val queueDatas: List?, 8 | ) { 9 | @Serializable 10 | data class QueueData( 11 | val content: NextResponse.MusicQueueRenderer.Content.PlaylistPanelRenderer.Content? 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/GetSearchSuggestionsResponse.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class GetSearchSuggestionsResponse( 7 | val contents: List?, 8 | ) { 9 | @Serializable 10 | data class Content( 11 | val searchSuggestionsSectionRenderer: SearchSuggestionsSectionRenderer, 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/GridRenderer.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class GridRenderer( 7 | val items: List?, 8 | val header: Header?, 9 | val continuations: List?, 10 | ) { 11 | @Serializable 12 | data class Item( 13 | val musicTwoRowItemRenderer: MusicTwoRowItemRenderer? 14 | ) 15 | 16 | @Serializable 17 | data class Header( 18 | val gridHeaderRenderer: GridHeaderRenderer? 19 | ) 20 | 21 | @Serializable 22 | data class GridHeaderRenderer( 23 | val title: Runs? 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/Icon.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class Icon( 7 | val iconType: String? = null, 8 | ) -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/MediaType.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | sealed class MediaType { 4 | data object Song : MediaType() 5 | 6 | data object Video : MediaType() 7 | } -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/MusicNavigationButtonRenderer.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class MusicNavigationButtonRenderer( 7 | val buttonText: Runs, 8 | val solid: Solid?, 9 | val iconStyle: IconStyle?, 10 | val clickCommand: NavigationEndpoint 11 | ) { 12 | @Serializable 13 | data class Solid( 14 | val leftStripeColor: Long 15 | ) 16 | 17 | @Serializable 18 | data class IconStyle( 19 | val icon: Icon 20 | ) 21 | 22 | @Serializable 23 | data class Icon( 24 | val iconType: String 25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/MusicPlaylistShelfRenderer.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class MusicPlaylistShelfRenderer( 7 | val playlistId: String?, 8 | val contents: List?, 9 | val collapsedItemCount: Int?, 10 | val continuations: List?, 11 | ) 12 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/PlaylistPanelVideoRenderer.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class PlaylistPanelVideoRenderer( 7 | val title: Runs?, 8 | val longBylineText: Runs?, 9 | val shortBylineText: Runs?, 10 | val lengthText: Runs?, 11 | val badges: List = emptyList(), 12 | val navigationEndpoint: NavigationEndpoint?, 13 | val thumbnail: ThumbnailRenderer.MusicThumbnailRenderer.Thumbnail?, 14 | ) 15 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/SearchResponse.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class SearchResponse( 7 | val contents: Contents?, 8 | ) { 9 | @Serializable 10 | data class Contents( 11 | val tabbedSearchResultsRenderer: Tabs? 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/SearchSuggestionsSectionRenderer.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class SearchSuggestionsSectionRenderer( 7 | val contents: List, 8 | ) { 9 | @Serializable 10 | data class Content( 11 | val searchSuggestionRenderer: SearchSuggestionRenderer?, 12 | val musicResponsiveListItemRenderer: MusicResponsiveListItemRenderer?, 13 | ) { 14 | @Serializable 15 | data class SearchSuggestionRenderer( 16 | val suggestion: Runs, 17 | val navigationEndpoint: NavigationEndpoint, 18 | ) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/SubscriptionButton.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class SubscriptionButton( 7 | val subscribeButtonRenderer: SubscribeButtonRenderer, 8 | ) { 9 | @Serializable 10 | data class SubscribeButtonRenderer( 11 | val subscriberCountText: Runs, 12 | val subscribed: Boolean, 13 | val channelId: String, 14 | val longSubscriberCountText: Runs 15 | ) 16 | } -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/Thumbnail.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class Thumbnail( 7 | val url: String, 8 | val height: Int?, 9 | val width: Int? 10 | ) { 11 | val isResizable: Boolean 12 | get() = !url.startsWith("https://i.ytimg.com") 13 | 14 | fun size(size: Int): String { 15 | return when { 16 | url.startsWith("https://lh3.googleusercontent.com") -> "$url-w$size-h$size" 17 | url.startsWith("https://yt3.ggpht.com") -> "$url-s$size" 18 | else -> url 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/Thumbnails.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class Thumbnails( 7 | val thumbnails: List, 8 | ) -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/bodies/AccountMenuBody.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models.bodies 2 | 3 | import it.fast4x.innertube.models.Context 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class AccountMenuBody( 8 | val context: Context = Context.DefaultWeb, 9 | val deviceTheme: String = "DEVICE_THEME_SELECTED", 10 | val userInterfaceTheme: String = "USER_INTERFACE_THEME_DARK", 11 | ) 12 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/bodies/BrowseBody.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models.bodies 2 | 3 | import it.fast4x.innertube.models.Context 4 | import it.fast4x.innertube.models.WatchEndpoint 5 | import kotlinx.serialization.Serializable 6 | 7 | @Serializable 8 | data class BrowseBody( 9 | val context: Context = Context.DefaultWeb, 10 | val browseId: String?, 11 | val params: String? = null, 12 | ) 13 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/bodies/ContinuationBody.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models.bodies 2 | 3 | import it.fast4x.innertube.models.Context 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class ContinuationBody( 8 | val context: Context = Context.DefaultWeb, 9 | val continuation: String, 10 | ) 11 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/bodies/ContinuationBodyWithLocale.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models.bodies 2 | 3 | import it.fast4x.innertube.models.Context 4 | import kotlinx.serialization.Serializable 5 | 6 | 7 | @Serializable 8 | data class ContinuationBodyWithLocale( 9 | val context: Context = Context.DefaultWebWithLocale, 10 | val continuation: String, 11 | ) 12 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/bodies/CreatePlaylistBody.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models.bodies 2 | 3 | import it.fast4x.innertube.models.Context 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class CreatePlaylistBody( 8 | val context: Context, 9 | val title: String, 10 | val privacyStatus: String = PrivacyStatus.PRIVATE, 11 | val videoIds: List? = null 12 | ) { 13 | object PrivacyStatus { 14 | const val PRIVATE = "PRIVATE" 15 | const val PUBLIC = "PUBLIC" 16 | const val UNLISTED = "UNLISTED" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/bodies/FormData.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models.bodies 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class FormData ( 7 | val selectedValues: List = listOf("ZZ") 8 | ) -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/bodies/LikeBody.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models.bodies 2 | 3 | import it.fast4x.innertube.models.Context 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class LikeBody( 8 | val context: Context, 9 | val target: Target, 10 | ) { 11 | @Serializable 12 | sealed class Target { 13 | @Serializable 14 | data class VideoTarget(val videoId: String) : Target() 15 | 16 | @Serializable 17 | data class PlaylistTarget(val playlistId: String) : Target() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/bodies/PlaylistDeleteBody.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models.bodies 2 | 3 | import it.fast4x.innertube.models.Context 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class PlaylistDeleteBody( 8 | val context: Context, 9 | val playlistId: String 10 | ) 11 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/bodies/QueueBody.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models.bodies 2 | 3 | import it.fast4x.innertube.models.Context 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class QueueBody( 8 | val context: Context = Context.DefaultWeb, 9 | val videoIds: List? = null, 10 | val playlistId: String? = null, 11 | ) 12 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/bodies/SearchBody.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models.bodies 2 | 3 | import it.fast4x.innertube.models.Context 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class SearchBody( 8 | val context: Context = Context.DefaultWeb, 9 | val query: String, 10 | val params: String 11 | ) 12 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/bodies/SearchSuggestionsBody.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models.bodies 2 | 3 | import it.fast4x.innertube.models.Context 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class SearchSuggestionsBody( 8 | val context: Context = Context.DefaultWeb, 9 | val input: String 10 | ) 11 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/models/bodies/SubscribeBody.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.models.bodies 2 | 3 | import it.fast4x.innertube.models.Context 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class SubscribeBody( 8 | val channelIds: List, 9 | val context: Context, 10 | ) 11 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/requests/ArtistItemsContinuationPage.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.requests 2 | 3 | import it.fast4x.innertube.Innertube 4 | 5 | 6 | data class ArtistItemsContinuationPage( 7 | val items: List, 8 | val continuation: String?, 9 | ) 10 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/requests/LibraryContinuationPage.kt: -------------------------------------------------------------------------------- 1 | package com.zionhuang.innertube.pages 2 | 3 | import it.fast4x.innertube.Innertube 4 | 5 | data class LibraryContinuationPage( 6 | val items: List, 7 | val continuation: String?, 8 | ) -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/requests/PlaylistContinuationPage.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.requests 2 | 3 | import it.fast4x.innertube.Innertube 4 | 5 | 6 | data class PlaylistContinuationPage( 7 | val songs: List, 8 | val continuation: String?, 9 | ) 10 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/utils/LocalePreferences.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.utils 2 | 3 | object LocalePreferences { 4 | var preference: LocalePreferenceItem? = null 5 | } 6 | 7 | data class LocalePreferenceItem( 8 | var hl: String, 9 | var gl: String 10 | ) -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/utils/ProxyPreferences.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.utils 2 | 3 | import java.net.InetSocketAddress 4 | import java.net.Proxy 5 | 6 | object ProxyPreferences { 7 | var preference: ProxyPreferenceItem? = null 8 | } 9 | 10 | data class ProxyPreferenceItem( 11 | var proxyHost: String, 12 | var proxyPort: Int, 13 | var proxyMode: Proxy.Type 14 | ) 15 | 16 | fun getProxy(proxyPreference: ProxyPreferenceItem): Proxy { 17 | return if(proxyPreference.proxyMode == Proxy.Type.DIRECT) { 18 | Proxy.NO_PROXY 19 | } else { 20 | Proxy( 21 | proxyPreference.proxyMode, 22 | InetSocketAddress(proxyPreference.proxyHost, proxyPreference.proxyPort) 23 | ) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/it/fast4x/innertube/utils/YoutubePreferences.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.innertube.utils 2 | 3 | object YoutubePreferences { 4 | var preference: YoutubePreferenceItem? = null 5 | } 6 | 7 | data class YoutubePreferenceItem( 8 | var cookie: String?, 9 | var visitordata: String?, 10 | var dataSyncId: String? 11 | ) -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/me/knighthat/common/response/AudioFormat.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.common.response 2 | 3 | interface AudioFormat: Comparable { 4 | 5 | val itag: UShort 6 | val url: String? 7 | val mimeType: String 8 | val codec: String 9 | val bitrate: UInt 10 | 11 | /** 12 | * Using bitrate as the value to compare between objects 13 | * 14 | * @param other format to compare to 15 | */ 16 | override fun compareTo( other: AudioFormat ): Int = 17 | this.bitrate.compareTo( other.bitrate ) 18 | } -------------------------------------------------------------------------------- /extensions/innertube/src/main/kotlin/me/knighthat/common/response/MediaFormatContainer.kt: -------------------------------------------------------------------------------- 1 | package me.knighthat.common.response 2 | 3 | import java.util.SortedSet 4 | 5 | interface MediaFormatContainer where T: AudioFormat{ 6 | 7 | val formats: SortedSet 8 | 9 | val autoMaxQualityFormat: T 10 | get() = highestQualityFormat 11 | 12 | val highestQualityFormat: T 13 | get() = formats.last() 14 | 15 | val mediumQualityFormat: T 16 | get() = formats.toList()[formats.size / 2] 17 | 18 | val lowestQualityFormat: T 19 | get() = formats.first() 20 | } -------------------------------------------------------------------------------- /extensions/innertube/src/test/kotlin/Test.kt: -------------------------------------------------------------------------------- 1 | import kotlinx.coroutines.runBlocking 2 | //import org.junit.Test 3 | 4 | class Test { 5 | //@Test 6 | @Throws(Exception::class) 7 | fun test() = runBlocking { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /extensions/invidious/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") 3 | @Suppress("DSL_SCOPE_VIOLATION") 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | sourceSets.all { 8 | java.srcDir("src/$name/kotlin") 9 | } 10 | 11 | dependencies { 12 | implementation(libs.kotlinx.coroutines) 13 | implementation(projects.ktorClientBrotli) 14 | implementation(libs.kotlinx.datetime) 15 | implementation(libs.ktor.client.core) 16 | implementation(libs.ktor.client.okhttp) 17 | implementation(libs.ktor.client.content.negotiation) 18 | implementation(libs.ktor.client.encoding) 19 | implementation(libs.ktor.client.serialization) 20 | implementation(libs.ktor.serialization.json) 21 | implementation(libs.okhttp3.logging.interceptor) 22 | } 23 | -------------------------------------------------------------------------------- /extensions/invidious/src/main/kotlin/it/fast4x/invidious/models/Instances.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.invidious.models 2 | 3 | enum class Instances { 4 | YEWTU, 5 | NADEKO, 6 | JIING, 7 | DRGNZ; 8 | 9 | val endpoint = "/api/v1/" 10 | 11 | val apiUrl: String 12 | get() = when (this) { 13 | YEWTU -> "https://yewtu.be$endpoint" 14 | NADEKO -> "https://inv.nadeko.net$endpoint" 15 | JIING -> "https://invidious.jing.rocks$endpoint" 16 | DRGNZ -> "https://yt.drgnz.club$endpoint" 17 | } 18 | 19 | val country: String 20 | get() = when (this) { 21 | YEWTU -> "DE" 22 | NADEKO -> "CL" 23 | JIING -> "JP" 24 | DRGNZ -> "CZ" 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /extensions/invidious/src/main/kotlin/it/fast4x/invidious/utils/Coroutines.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.invidious.utils 2 | 3 | import kotlinx.coroutines.CancellationException 4 | 5 | inline fun runCatchingCancellable(block: () -> T) = 6 | runCatching(block).takeIf { it.exceptionOrNull() !is CancellationException } 7 | 8 | internal inline fun runCatchingNonCancellable(block: () -> R): Result? { 9 | val result = runCatching(block) 10 | return when (result.exceptionOrNull()) { 11 | is CancellationException -> null 12 | else -> result 13 | } 14 | } -------------------------------------------------------------------------------- /extensions/invidious/src/main/kotlin/it/fast4x/invidious/utils/ProxyPreferences.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.invidious.utils 2 | 3 | import java.net.InetSocketAddress 4 | import java.net.Proxy 5 | 6 | object ProxyPreferences { 7 | var preference: ProxyPreferenceItem? = null 8 | } 9 | 10 | data class ProxyPreferenceItem( 11 | var proxyHost: String, 12 | var proxyPort: Int, 13 | var proxyMode: Proxy.Type 14 | ) 15 | 16 | fun getProxy(proxyPreference: ProxyPreferenceItem): Proxy { 17 | return if(proxyPreference.proxyMode == Proxy.Type.DIRECT) { 18 | Proxy.NO_PROXY 19 | } else { 20 | Proxy( 21 | proxyPreference.proxyMode, 22 | InetSocketAddress(proxyPreference.proxyHost, proxyPreference.proxyPort) 23 | ) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /extensions/ktor-client-brotli/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /extensions/ktor-client-brotli/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") 3 | } 4 | 5 | sourceSets.all { 6 | java.srcDir("src/$name/kotlin") 7 | } 8 | 9 | dependencies { 10 | implementation(libs.ktor.client.encoding) 11 | implementation(libs.brotli) 12 | } -------------------------------------------------------------------------------- /extensions/kugou/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /extensions/kugou/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") 3 | @Suppress("DSL_SCOPE_VIOLATION") 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | sourceSets.all { 8 | java.srcDir("src/$name/kotlin") 9 | } 10 | 11 | dependencies { 12 | implementation(libs.kotlinx.coroutines) 13 | 14 | implementation(libs.ktor.client.core) 15 | implementation(libs.ktor.client.okhttp) 16 | implementation(libs.ktor.client.content.negotiation) 17 | implementation(libs.ktor.client.encoding) 18 | implementation(libs.ktor.client.serialization) 19 | implementation(libs.ktor.serialization.json) 20 | } 21 | -------------------------------------------------------------------------------- /extensions/kugou/src/main/kotlin/it/fast4x/kugou/Result.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.kugou 2 | 3 | import kotlin.coroutines.cancellation.CancellationException 4 | 5 | internal fun Result.recoverIfCancelled(): Result? { 6 | return when (exceptionOrNull()) { 7 | is CancellationException -> null 8 | else -> this 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /extensions/kugou/src/main/kotlin/it/fast4x/kugou/models/DownloadLyricsResponse.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.kugou.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | internal class DownloadLyricsResponse( 7 | val content: String 8 | ) 9 | -------------------------------------------------------------------------------- /extensions/kugou/src/main/kotlin/it/fast4x/kugou/models/SearchLyricsResponse.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.kugou.models 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | internal class SearchLyricsResponse( 8 | val candidates: List 9 | ) { 10 | @Serializable 11 | internal class Candidate( 12 | val id: Long, 13 | @SerialName("accesskey") val accessKey: String, 14 | val duration: Long 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /extensions/kugou/src/main/kotlin/it/fast4x/kugou/models/SearchSongResponse.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.kugou.models 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | internal data class SearchSongResponse( 7 | val data: Data 8 | ) { 9 | @Serializable 10 | internal data class Data( 11 | val info: List 12 | ) { 13 | @Serializable 14 | internal data class Info( 15 | val duration: Long, 16 | val hash: String 17 | ) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /extensions/kugou/src/test/kotlin/Test.kt: -------------------------------------------------------------------------------- 1 | import kotlinx.coroutines.runBlocking 2 | //import org.junit.Test 3 | 4 | class Test { 5 | //@Test 6 | @Throws(Exception::class) 7 | fun test() { 8 | runBlocking { 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /extensions/lrclib/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") 3 | @Suppress("DSL_SCOPE_VIOLATION") 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | sourceSets.all { 8 | java.srcDir("src/$name/kotlin") 9 | } 10 | 11 | dependencies { 12 | implementation(libs.kotlinx.coroutines) 13 | implementation(projects.ktorClientBrotli) 14 | 15 | implementation(libs.ktor.client.core) 16 | implementation(libs.ktor.client.okhttp) 17 | implementation(libs.ktor.client.content.negotiation) 18 | implementation(libs.ktor.client.encoding) 19 | implementation(libs.ktor.client.serialization) 20 | implementation(libs.ktor.serialization.json) 21 | } 22 | -------------------------------------------------------------------------------- /extensions/lrclib/src/main/kotlin/it/fast4x/lrclib/utils/Coroutines.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.lrclib.utils 2 | 3 | import kotlinx.coroutines.CancellationException 4 | 5 | inline fun runCatchingCancellable(block: () -> T) = 6 | runCatching(block).takeIf { it.exceptionOrNull() !is CancellationException } 7 | -------------------------------------------------------------------------------- /extensions/lrclib/src/main/kotlin/it/fast4x/lrclib/utils/ProxyPreferences.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.lrclib.utils 2 | 3 | import java.net.InetSocketAddress 4 | import java.net.Proxy 5 | 6 | object ProxyPreferences { 7 | var preference: ProxyPreferenceItem? = null 8 | } 9 | 10 | data class ProxyPreferenceItem( 11 | var proxyHost: String, 12 | var proxyPort: Int, 13 | var proxyMode: Proxy.Type 14 | ) 15 | 16 | fun getProxy(proxyPreference: ProxyPreferenceItem): Proxy { 17 | return if(proxyPreference.proxyMode == Proxy.Type.DIRECT) { 18 | Proxy.NO_PROXY 19 | } else { 20 | Proxy( 21 | proxyPreference.proxyMode, 22 | InetSocketAddress(proxyPreference.proxyHost, proxyPreference.proxyPort) 23 | ) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /extensions/piped/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") 3 | @Suppress("DSL_SCOPE_VIOLATION") 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | sourceSets.all { 8 | java.srcDir("src/$name/kotlin") 9 | } 10 | 11 | dependencies { 12 | implementation(libs.kotlinx.coroutines) 13 | implementation(projects.ktorClientBrotli) 14 | implementation(libs.kotlinx.datetime) 15 | implementation(libs.ktor.client.core) 16 | implementation(libs.ktor.client.okhttp) 17 | implementation(libs.ktor.client.content.negotiation) 18 | implementation(libs.ktor.client.encoding) 19 | implementation(libs.ktor.client.serialization) 20 | implementation(libs.ktor.serialization.json) 21 | implementation(libs.okhttp3.logging.interceptor) 22 | } 23 | -------------------------------------------------------------------------------- /extensions/piped/src/main/kotlin/it/fast4x/piped/models/Session.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.piped.models 2 | 3 | import io.ktor.http.Url 4 | 5 | @JvmInline 6 | value class Session internal constructor(private val value: Pair) { 7 | val apiBaseUrl get() = value.first 8 | val token get() = value.second 9 | } 10 | 11 | infix fun Url.authenticatedWith(token: String) = Session(this to token) 12 | infix fun String.authenticatedWith(token: String) = Url(this) authenticatedWith token 13 | -------------------------------------------------------------------------------- /extensions/piped/src/main/kotlin/it/fast4x/piped/utils/Coroutines.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.piped.utils 2 | 3 | import kotlinx.coroutines.CancellationException 4 | 5 | inline fun runCatchingCancellable(block: () -> T) = 6 | runCatching(block).takeIf { it.exceptionOrNull() !is CancellationException } 7 | -------------------------------------------------------------------------------- /extensions/piped/src/main/kotlin/it/fast4x/piped/utils/ProxyPreferences.kt: -------------------------------------------------------------------------------- 1 | package it.fast4x.piped.utils 2 | 3 | import java.net.InetSocketAddress 4 | import java.net.Proxy 5 | 6 | object ProxyPreferences { 7 | var preference: ProxyPreferenceItem? = null 8 | } 9 | 10 | data class ProxyPreferenceItem( 11 | var proxyHost: String, 12 | var proxyPort: Int, 13 | var proxyMode: Proxy.Type 14 | ) 15 | 16 | fun getProxy(proxyPreference: ProxyPreferenceItem): Proxy { 17 | return if(proxyPreference.proxyMode == Proxy.Type.DIRECT) { 18 | Proxy.NO_PROXY 19 | } else { 20 | Proxy( 21 | proxyPreference.proxyMode, 22 | InetSocketAddress(proxyPreference.proxyHost, proxyPreference.proxyPort) 23 | ) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/100.txt: -------------------------------------------------------------------------------- 1 | Added: 2 | - Locator button in queue 3 | 4 | Fixed: 5 | - Cached songs don't get updated data 6 | - Remaining time showed despite disabled in settings 7 | - Forward/Rewind buttons behaved abnormally 8 | - Remaining time showed large negative number at the beginning of the song 9 | - App crashed while changing language 10 | 11 | Changed: 12 | - Improved performance/Reduce wait time when there's a large playlist to play 13 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/87.txt: -------------------------------------------------------------------------------- 1 | Fixed: 2 | - Empty playlists didn't show up 3 | - New playlist dialog didn't close after confirm 4 | - Total play time reset after playback 5 | - Crash when remove song(s) from a playlist 6 | - Crash when importing new database 7 | - Crash when search for previously seach term 8 | - Songs in "For you" section didn't play 9 | 10 | Added: 11 | - New feature graphic & tv banner (for F-Droid) 12 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/88.txt: -------------------------------------------------------------------------------- 1 | Fixed: 2 | - Random crashes 3 | - Long load time on "cached" & "downloaded" 4 | 5 | New: 6 | - Banners & feature graphics 7 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/89.txt: -------------------------------------------------------------------------------- 1 | Added: 2 | - More options to Top Playlist's period selector 3 | - Song menu in quick picks tab 4 | - Extension to exported file 5 | - Grid/List style in sort menu 6 | - New relative play time icon and text 7 | 8 | Changes: 9 | - Song list only jumps to top with certain actions 10 | - Greatly improve load time in Songs tab thanks to @coolcarp 11 | 12 | Fixed: 13 | - Top Playlist and Statistic don't report correctly 14 | - Online playlist doesn't update after 100 songs 15 | - Awkward scrolling in online playlist 16 | - Previous-search is now ordered in recent searches to older searches 17 | - Random crashes 18 | - Songs on device don't follow sort by & sort order 19 | - Hidden song show in certain sort categories -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/91.txt: -------------------------------------------------------------------------------- 1 | Fixed: 2 | - "No update available" constantly popping up 3 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/92.txt: -------------------------------------------------------------------------------- 1 | Added: 2 | - Real-time blur slider in player 3 | - Real-time back drop slider in player 4 | - Shortcut to Artists tab 5 | - Changelogs dialog on new update 6 | 7 | Changed: 8 | - Go to artist/album in player is always clickable 9 | - New visual on some existing icons 10 | 11 | Fixed: 12 | - Database missing data after exported 13 | - Imported playlists didn't show up 14 | - Hidden downloaded songs in "downloaded" tab 15 | - Unresponsive go to artist/album on tap in player 16 | - Duplicate songs in online playlist caused crash 17 | - Crash when repositioning songs' positions in playlist on older devices 18 | - Click search on keyboard didn't close keyboard on some instances 19 | - App shortcuts 20 | - Useless repeat button in player 21 | - Song removed from playlist if reset in menu 22 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/93.txt: -------------------------------------------------------------------------------- 1 | Fixed: 2 | - Android Auto failed to load -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/94.txt: -------------------------------------------------------------------------------- 1 | Added: 2 | - Rotating background option when "Blurred cover" is enabled 3 | - Playback speed adjuster (enable in "Player Appearance" settings) 4 | 5 | Changed: 6 | - New app logo and banner sets 7 | - Changing localization required restart 8 | 9 | Fixed: 10 | - Player failed to play on logged in sessions 11 | - Inverted like message when toggled in player 12 | - Modified artist name reset on playback 13 | - Lyrics didn't show up 14 | - Only text clickable in different menus 15 | - Radio button didn't show more songs 16 | - Only selected song showed in queue when play from Quick Picks 17 | - Play/pause in widget didn't update in real-time 18 | - App crashed when import CSV file with empty line(s) 19 | 20 | Improved: 21 | - Reduce load time/lag spike in Player on first playback 22 | 23 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/95.txt: -------------------------------------------------------------------------------- 1 | Fixed: 2 | - Unresponsive sort arrow -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/96.txt: -------------------------------------------------------------------------------- 1 | Fixed: 2 | - mofified: prefix showed in miniplayer 3 | - Radio & song discover didn't work properly 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/97.txt: -------------------------------------------------------------------------------- 1 | Fixed: 2 | - Song restart when start new radio 3 | - Duplicate song titles & artists in "next in queue" 4 | - Play song from search didn't do anything while playing another song 5 | - Crash when rearrage song positions in playlist 6 | 7 | Changed: 8 | - Hide menu after "Start radio" 9 | - Improve next song(s) in queue 10 | - "Add to playlist" will not close after selection 11 | - Migrate to material3 (expect subtle changes in UI/UX) 12 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/98.txt: -------------------------------------------------------------------------------- 1 | Changed: 2 | - Widgets backend logics 3 | - Faster "Go to artist" and "Go to album" 4 | - Reduced load time when first load player 5 | - Prompt to get access to certain permissions on "On device" 6 | 7 | Fixed: 8 | - Audio fade out and fade in didn't work with multiple interactions 9 | - Playback stopped after first minute 10 | - Download failed 11 | - Download playback failed 12 | - Player background didn't fill to full screen 13 | - Action bar overlapped navigation bar 14 | - "Next in queue" showed first song sometimes 15 | - Local songs failed to play 16 | - Song failed to indicate "explicit" 17 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/99.txt: -------------------------------------------------------------------------------- 1 | Added: 2 | - More albums in artist page 3 | - Single, double, and long tap to forward/rewind timeline 4 | - Documentation website in About 5 | - Social medias in About 6 | 7 | Changed: 8 | - Hide navigation bar when there's less than 2 items to navigate 9 | - Number of paths showed in address bar in "On device" 10 | 11 | Fixed: 12 | - App crashed after logging out of YT account 13 | - Cover disappeared occasionally 14 | - "modified:" in media control 15 | - Song's total play time reset on each play 16 | - Song's like state reset on each play 17 | - Backdrop didn't apply 18 | - Local songs didn't show up in older Android versions 19 | - App crashed when permission to view local files is denied on older Android versions 20 | - Immediate play when persistent queue is enabled 21 | 22 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/featureGraphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/fastlane/metadata/android/en-US/images/featureGraphic.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/fastlane/metadata/android/en-US/images/icon.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/fastlane/metadata/android/en-US/images/phoneScreenshots/7.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/fastlane/metadata/android/en-US/images/phoneScreenshots/8.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/fastlane/metadata/android/en-US/images/phoneScreenshots/9.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/tvBanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/fastlane/metadata/android/en-US/images/tvBanner.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/short_description.txt: -------------------------------------------------------------------------------- 1 | A multilingual YouTube Music frontend for Android, prioritize performance. 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/title.txt: -------------------------------------------------------------------------------- 1 | Kreate 2 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx6656M -Dfile.encoding=UTF-8 2 | org.gradle.daemon=true 3 | org.gradle.parallel=true 4 | android.useAndroidX=true 5 | android.enableR8.fullMode=true 6 | kotlin.code.style=official 7 | kotlin.mpp.androidGradlePluginCompatibility.nowarn=true 8 | 9 | org.gradle.caching=true 10 | org.gradle.configuration-cache=true 11 | android.enableJetifier=false 12 | android.nonTransitiveRClass=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knighthat/Kreate/9f359aaab4822e2c3b541c35803c2d4ef2599f72/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionSha256Sum=f397b287023acdba1e9f6fc5ea72d22dd63669d59ed4a289a29b1a76eee151c6 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip 5 | networkTimeout=10000 6 | validateDistributionUrl=true 7 | zipStoreBase=GRADLE_USER_HOME 8 | zipStorePath=wrapper/dists 9 | --------------------------------------------------------------------------------