├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml └── workflows │ ├── alpha.yml │ ├── alpha_build_manually_without_sign.yml │ ├── auto_close_issues.yml │ ├── close_inactive_issues.yml │ ├── features.yml │ └── release.yml ├── .gitignore ├── .gitmodules ├── .idea ├── .gitignore ├── kotlinc.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro ├── schemas │ └── dev.aaa1115910.bv.dao.AppDatabase │ │ ├── 1.json │ │ ├── 2.json │ │ └── 3.json └── src │ ├── debug │ ├── AndroidManifest.xml │ └── res │ │ └── values │ │ └── strings.xml │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-playstore.png │ ├── kotlin │ │ ├── coil │ │ │ └── transform │ │ │ │ └── BlurTransformation.kt │ │ ├── de │ │ │ └── schnettler │ │ │ │ └── datastore │ │ │ │ └── manager │ │ │ │ ├── DataStoreManager.kt │ │ │ │ └── PreferenceRequest.kt │ │ └── dev │ │ │ └── aaa1115910 │ │ │ └── bv │ │ │ ├── BVApp.kt │ │ │ ├── activities │ │ │ ├── MainActivity.kt │ │ │ ├── pgc │ │ │ │ ├── PgcIndexActivity.kt │ │ │ │ └── anime │ │ │ │ │ └── AnimeTimelineActivity.kt │ │ │ ├── search │ │ │ │ ├── SearchInputActivity.kt │ │ │ │ └── SearchResultActivity.kt │ │ │ ├── settings │ │ │ │ ├── LogsActivity.kt │ │ │ │ ├── MediaCodecActivity.kt │ │ │ │ ├── SettingsActivity.kt │ │ │ │ └── SpeedTestActivity.kt │ │ │ ├── user │ │ │ │ ├── FavoriteActivity.kt │ │ │ │ ├── FollowActivity.kt │ │ │ │ ├── FollowingSeasonActivity.kt │ │ │ │ ├── HistoryActivity.kt │ │ │ │ ├── LoginActivity.kt │ │ │ │ ├── ToViewActivity.kt │ │ │ │ ├── UserInfoActivity.kt │ │ │ │ ├── UserLockSettingsActivity.kt │ │ │ │ └── UserSwitchActivity.kt │ │ │ └── video │ │ │ │ ├── RemoteControllerPanelDemoActivity.kt │ │ │ │ ├── SeasonInfoActivity.kt │ │ │ │ ├── TagActivity.kt │ │ │ │ ├── UpInfoActivity.kt │ │ │ │ ├── VideoInfoActivity.kt │ │ │ │ ├── VideoPlayerActivity.kt │ │ │ │ └── VideoPlayerV3Activity.kt │ │ │ ├── component │ │ │ ├── BottomTip.kt │ │ │ ├── BvPlayerPreview.kt │ │ │ ├── Carousel.kt │ │ │ ├── DanmakuPlayerCompose.kt │ │ │ ├── DevelopingTip.kt │ │ │ ├── FocusGroup.kt │ │ │ ├── FpsMonitor.kt │ │ │ ├── LibVLCDownloaderDialog.kt │ │ │ ├── LoadingTip.kt │ │ │ ├── RemoteControlPanelDemo.kt │ │ │ ├── TopNav.kt │ │ │ ├── UpIcon.kt │ │ │ ├── UserPanel.kt │ │ │ ├── buttons │ │ │ │ ├── FavoriteButton.kt │ │ │ │ └── SeasonInfoButtons.kt │ │ │ ├── controllers │ │ │ │ ├── BottomControls.kt │ │ │ │ ├── BottomSubtitle.kt │ │ │ │ ├── BufferingTip.kt │ │ │ │ ├── GoBackHistoryTip.kt │ │ │ │ ├── PauseIcon.kt │ │ │ │ ├── TopController.kt │ │ │ │ ├── VideoListController.kt │ │ │ │ ├── VideoPlayerController.kt │ │ │ │ ├── VideoPlayerMenuController.kt │ │ │ │ └── info │ │ │ │ │ └── VideoPlayerInfoTip.kt │ │ │ ├── controllers2 │ │ │ │ ├── BottomSubtitle.kt │ │ │ │ ├── ControllerVideoInfo.kt │ │ │ │ ├── MenuController.kt │ │ │ │ ├── PlayStateTips.kt │ │ │ │ ├── ProgressSeekThumb.kt │ │ │ │ ├── SeekController.kt │ │ │ │ ├── SkipTip.kt │ │ │ │ ├── VideoListController.kt │ │ │ │ ├── VideoPlayerController.kt │ │ │ │ ├── VideoProgressSeek.kt │ │ │ │ ├── VideoShot.kt │ │ │ │ └── playermenu │ │ │ │ │ ├── ClosedCaptionMenu.kt │ │ │ │ │ ├── DanmakuMenu.kt │ │ │ │ │ ├── MenuNav.kt │ │ │ │ │ ├── PictureMenu.kt │ │ │ │ │ └── component │ │ │ │ │ ├── CheckBoxMenuList.kt │ │ │ │ │ ├── MenuListItem.kt │ │ │ │ │ ├── RadioMenuList.kt │ │ │ │ │ └── StepLessMenuItem.kt │ │ │ ├── createCustomInitialFocusRestorerModifiers.kt │ │ │ ├── ifElse.kt │ │ │ ├── pgc │ │ │ │ └── IndexFilter.kt │ │ │ ├── search │ │ │ │ ├── SearchKeyword.kt │ │ │ │ └── SoftKeyboard.kt │ │ │ ├── settings │ │ │ │ ├── CookiesDialog.kt │ │ │ │ ├── SettingListItem.kt │ │ │ │ ├── SettingSwitchListItem.kt │ │ │ │ ├── SettingsMenuSelectItem.kt │ │ │ │ └── UpdateDialog.kt │ │ │ └── videocard │ │ │ │ ├── LargeVideoCard.kt │ │ │ │ ├── SeasonCard.kt │ │ │ │ ├── SmallVideoCard.kt │ │ │ │ └── VideosRow.kt │ │ │ ├── dao │ │ │ ├── AppDatabase.kt │ │ │ ├── SearchHistoryDao.kt │ │ │ └── UserDao.kt │ │ │ ├── entity │ │ │ ├── Audio.kt │ │ │ ├── AuthData.kt │ │ │ ├── DanmakuSize.kt │ │ │ ├── DanmakuTransparency.kt │ │ │ ├── PlayerType.kt │ │ │ ├── Resolution.kt │ │ │ ├── VideoAspectRatio.kt │ │ │ ├── VideoCodec.kt │ │ │ ├── carddata │ │ │ │ ├── SeasonCardData.kt │ │ │ │ └── VideoCardData.kt │ │ │ ├── db │ │ │ │ ├── SearchHistoryDB.kt │ │ │ │ └── UserDB.kt │ │ │ └── proxy │ │ │ │ └── ProxyArea.kt │ │ │ ├── network │ │ │ ├── GithubApi.kt │ │ │ ├── HttpServer.kt │ │ │ ├── VlcLibsApi.kt │ │ │ └── entity │ │ │ │ └── GithubRelease.kt │ │ │ ├── repository │ │ │ ├── UserRepository.kt │ │ │ └── VideoInfoRepository.kt │ │ │ ├── screen │ │ │ ├── MainScreen.kt │ │ │ ├── RegionBlockScreen.kt │ │ │ ├── SeasonInfoScreen.kt │ │ │ ├── TagScreen.kt │ │ │ ├── VideoInfoScreen.kt │ │ │ ├── VideoPlayerScreen.kt │ │ │ ├── VideoPlayerV3Screen.kt │ │ │ ├── login │ │ │ │ ├── AppQRLoginContent.kt │ │ │ │ ├── LoginScreen.kt │ │ │ │ └── SmsLoginContent.kt │ │ │ ├── main │ │ │ │ ├── DrawerContent.kt │ │ │ │ ├── HomeContent.kt │ │ │ │ ├── PgcContent.kt │ │ │ │ ├── UgcContent.kt │ │ │ │ ├── home │ │ │ │ │ ├── DynamicsScreen.kt │ │ │ │ │ ├── PopularScreen.kt │ │ │ │ │ └── RecommendScreen.kt │ │ │ │ ├── pgc │ │ │ │ │ ├── AnimeContent.kt │ │ │ │ │ ├── DocumentaryContent.kt │ │ │ │ │ ├── GuoChuangContent.kt │ │ │ │ │ ├── MovieContent.kt │ │ │ │ │ ├── PgcCommon.kt │ │ │ │ │ ├── PgcIndexScreen.kt │ │ │ │ │ ├── TvContent.kt │ │ │ │ │ ├── VarietyContent.kt │ │ │ │ │ └── anime │ │ │ │ │ │ └── AnimeTimelineScreen.kt │ │ │ │ └── ugc │ │ │ │ │ ├── AnimalContent.kt │ │ │ │ │ ├── CarContent.kt │ │ │ │ │ ├── CinephileContent.kt │ │ │ │ │ ├── DanceContent.kt │ │ │ │ │ ├── DougaContent.kt │ │ │ │ │ ├── EntContent.kt │ │ │ │ │ ├── FashionContent.kt │ │ │ │ │ ├── FoodContent.kt │ │ │ │ │ ├── GameContent.kt │ │ │ │ │ ├── InformationContent.kt │ │ │ │ │ ├── KichikuContent.kt │ │ │ │ │ ├── KnowledgeContent.kt │ │ │ │ │ ├── LifeContent.kt │ │ │ │ │ ├── MuiscContent.kt │ │ │ │ │ ├── SportsContent.kt │ │ │ │ │ ├── TechContent.kt │ │ │ │ │ ├── UgcChildRegionButtons.kt │ │ │ │ │ └── UgcCommon.kt │ │ │ ├── search │ │ │ │ ├── SearchInputScreen.kt │ │ │ │ ├── SearchResultFilter.kt │ │ │ │ └── SearchResultScreen.kt │ │ │ ├── settings │ │ │ │ ├── LogsScreen.kt │ │ │ │ ├── MediaCodecScreen.kt │ │ │ │ ├── SettingsScreen.kt │ │ │ │ ├── SpeedTestScreen.kt │ │ │ │ └── content │ │ │ │ │ ├── AboutSetting.kt │ │ │ │ │ ├── ApiSetting.kt │ │ │ │ │ ├── AudioSetting.kt │ │ │ │ │ ├── InfoSetting.kt │ │ │ │ │ ├── NetworkSetting.kt │ │ │ │ │ ├── OtherSetting.kt │ │ │ │ │ ├── PlayerTypeSetting.kt │ │ │ │ │ ├── ResolutionSetting.kt │ │ │ │ │ ├── StorageSetting.kt │ │ │ │ │ ├── UISetting.kt │ │ │ │ │ └── VideoCodecSetting.kt │ │ │ └── user │ │ │ │ ├── FavoriteScreen.kt │ │ │ │ ├── FollowScreen.kt │ │ │ │ ├── FollowingSeasonFilter.kt │ │ │ │ ├── FollowingSeasonScreen.kt │ │ │ │ ├── HistoryScreen.kt │ │ │ │ ├── ToViewScreen.kt │ │ │ │ ├── UpInfoScreen.kt │ │ │ │ ├── UserInfoScreen.kt │ │ │ │ ├── UserSwitchScreen.kt │ │ │ │ └── lock │ │ │ │ ├── UnlockSwitchUserContent.kt │ │ │ │ ├── UnlockUserScreen.kt │ │ │ │ └── UserLockSettingsScreen.kt │ │ │ ├── ui │ │ │ └── theme │ │ │ │ ├── Theme.kt │ │ │ │ └── Typography.kt │ │ │ ├── util │ │ │ ├── AbiUtil.kt │ │ │ ├── CodecUtil.kt │ │ │ ├── EnumExtends.kt │ │ │ ├── Extends.kt │ │ │ ├── FirebaseUtil.kt │ │ │ ├── ImageExtends.kt │ │ │ ├── KLoggerExtends.kt │ │ │ ├── LogCatcherUtil.kt │ │ │ ├── ModifierExtends.kt │ │ │ ├── NetworkUtil.kt │ │ │ ├── PartitionUtil.kt │ │ │ ├── PgcIndexParamExtends.kt │ │ │ ├── PgcTypeExtends.kt │ │ │ ├── PlayerActivityUtil.kt │ │ │ ├── Prefs.kt │ │ │ ├── Timer.kt │ │ │ ├── UgcTypeExtends.kt │ │ │ └── VideoShotExtends.kt │ │ │ └── viewmodel │ │ │ ├── PlayerVIewModel.kt │ │ │ ├── TagViewModel.kt │ │ │ ├── UserViewModel.kt │ │ │ ├── VideoPlayerV3ViewModel.kt │ │ │ ├── home │ │ │ ├── DynamicViewModel.kt │ │ │ ├── PopularViewModel.kt │ │ │ └── RecommendViewModel.kt │ │ │ ├── index │ │ │ └── PgcIndexViewModel.kt │ │ │ ├── login │ │ │ ├── AppQrLoginViewModel.kt │ │ │ └── SmsLoginViewModel.kt │ │ │ ├── pgc │ │ │ ├── PgcAnimeViewModel.kt │ │ │ ├── PgcDocumentaryViewModel.kt │ │ │ ├── PgcGuoChuangViewModel.kt │ │ │ ├── PgcMovieViewModel.kt │ │ │ ├── PgcTvViewModel.kt │ │ │ ├── PgcVarietyViewModel.kt │ │ │ └── PgcViewModel.kt │ │ │ ├── search │ │ │ ├── SearchInputViewModel.kt │ │ │ └── SearchResultViewModel.kt │ │ │ ├── user │ │ │ ├── FavoriteViewModel.kt │ │ │ ├── FollowViewModel.kt │ │ │ ├── FollowingSeasonViewModel.kt │ │ │ ├── HistoryViewModel.kt │ │ │ ├── ToViewViewModel.kt │ │ │ └── UpInfoViewModel.kt │ │ │ └── video │ │ │ └── VideoDetailViewModel.kt │ └── res │ │ ├── drawable │ │ ├── ic_banner.webp │ │ ├── ic_banner_foreground.xml │ │ ├── ic_danmaku_count.xml │ │ ├── ic_gamer_ani.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── ic_play_count.xml │ │ └── ic_up.xml │ │ ├── font │ │ └── noto_sans_math_regular.ttf │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_banner.xml │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── values │ │ ├── arrays.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── themes.xml │ │ └── xml │ │ ├── network_security_config.xml │ │ └── provider_paths.xml │ ├── r8Test │ ├── AndroidManifest.xml │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── kotlin │ ├── android │ └── util │ │ └── Log.kt │ └── dev │ └── aaa1115910 │ └── bv │ └── network │ └── GithubApiTest.kt ├── bili-api-grpc ├── .gitignore ├── build.gradle.kts └── proto │ ├── bilibili │ ├── account │ │ └── fission │ │ │ └── v1 │ │ │ └── fission.proto │ ├── ad │ │ └── v1 │ │ │ └── ad.proto │ ├── api │ │ ├── player │ │ │ └── v1 │ │ │ │ └── player.proto │ │ ├── probe │ │ │ └── v1 │ │ │ │ └── probe.proto │ │ └── ticket │ │ │ └── v1 │ │ │ └── ticket.proto │ ├── app │ │ ├── archive │ │ │ ├── middleware │ │ │ │ └── v1 │ │ │ │ │ └── preload.proto │ │ │ └── v1 │ │ │ │ └── archive.proto │ │ ├── card │ │ │ └── v1 │ │ │ │ ├── ad.proto │ │ │ │ ├── card.proto │ │ │ │ ├── common.proto │ │ │ │ ├── double.proto │ │ │ │ └── single.proto │ │ ├── click │ │ │ └── v1 │ │ │ │ └── heartbeat.proto │ │ ├── distribution │ │ │ ├── setting │ │ │ │ ├── download.proto │ │ │ │ ├── dynamic.proto │ │ │ │ ├── experimental.proto │ │ │ │ ├── internaldevice.proto │ │ │ │ ├── night.proto │ │ │ │ ├── other.proto │ │ │ │ ├── pegasus.proto │ │ │ │ ├── play.proto │ │ │ │ ├── privacy.proto │ │ │ │ └── search.proto │ │ │ └── v1 │ │ │ │ └── distribution.proto │ │ ├── dynamic │ │ │ ├── common │ │ │ │ └── dynamic.proto │ │ │ ├── v1 │ │ │ │ └── dynamic.proto │ │ │ └── v2 │ │ │ │ ├── campus.proto │ │ │ │ ├── dynamic.proto │ │ │ │ └── opus.proto │ │ ├── interfaces │ │ │ └── v1 │ │ │ │ ├── history.proto │ │ │ │ ├── media.proto │ │ │ │ ├── search.proto │ │ │ │ └── space.proto │ │ ├── listener │ │ │ └── v1 │ │ │ │ └── listener.proto │ │ ├── playeronline │ │ │ └── v1 │ │ │ │ └── playeronline.proto │ │ ├── playerunite │ │ │ ├── pgcanymodel │ │ │ │ └── PGCAnyModel.proto │ │ │ ├── ugcanymodel │ │ │ │ └── UGCAnyModel.proto │ │ │ └── v1 │ │ │ │ └── playerunite.proto │ │ ├── playurl │ │ │ └── v1 │ │ │ │ └── playurl.proto │ │ ├── resource │ │ │ ├── privacy │ │ │ │ └── v1 │ │ │ │ │ └── api.proto │ │ │ └── v1 │ │ │ │ └── module.proto │ │ ├── search │ │ │ └── v2 │ │ │ │ └── search.proto │ │ ├── show │ │ │ ├── gateway │ │ │ │ └── v1 │ │ │ │ │ └── service.proto │ │ │ ├── mixture │ │ │ │ └── v1 │ │ │ │ │ └── mixture.proto │ │ │ ├── popular │ │ │ │ └── v1 │ │ │ │ │ └── popular.proto │ │ │ ├── rank │ │ │ │ └── v1 │ │ │ │ │ └── rank.proto │ │ │ └── region │ │ │ │ └── v1 │ │ │ │ └── region.proto │ │ ├── space │ │ │ └── v1 │ │ │ │ └── space.proto │ │ ├── splash │ │ │ └── v1 │ │ │ │ └── splash.proto │ │ ├── topic │ │ │ └── v1 │ │ │ │ └── topic.proto │ │ ├── view │ │ │ └── v1 │ │ │ │ └── view.proto │ │ ├── viewunite │ │ │ ├── common.proto │ │ │ ├── pgcanymodel.proto │ │ │ ├── ugcanymodel.proto │ │ │ └── v1 │ │ │ │ └── viewunite.proto │ │ └── wall │ │ │ └── v1 │ │ │ └── wall.proto │ ├── broadcast │ │ ├── message │ │ │ ├── editor │ │ │ │ └── notify.proto │ │ │ ├── esports │ │ │ │ └── notify.proto │ │ │ ├── fission │ │ │ │ └── notify.proto │ │ │ ├── im │ │ │ │ └── notify.proto │ │ │ ├── main │ │ │ │ ├── dm.proto │ │ │ │ ├── native.proto │ │ │ │ ├── resource.proto │ │ │ │ └── search.proto │ │ │ ├── note │ │ │ │ └── sync.proto │ │ │ ├── ogv │ │ │ │ ├── freya.proto │ │ │ │ └── live.proto │ │ │ ├── ticket │ │ │ │ └── activitygame.proto │ │ │ └── tv │ │ │ │ └── proj.proto │ │ ├── v1 │ │ │ ├── broadcast.proto │ │ │ ├── laser.proto │ │ │ ├── mod.proto │ │ │ ├── push.proto │ │ │ ├── room.proto │ │ │ └── test.proto │ │ └── v2 │ │ │ └── laser.proto │ ├── cheese │ │ └── gateway │ │ │ └── player │ │ │ └── v1 │ │ │ └── playurl.proto │ ├── community │ │ └── service │ │ │ ├── dm │ │ │ └── v1 │ │ │ │ └── dm.proto │ │ │ └── govern │ │ │ └── v1 │ │ │ └── govern.proto │ ├── dagw │ │ └── component │ │ │ └── avatar │ │ │ ├── common │ │ │ └── common.proto │ │ │ └── v1 │ │ │ ├── avatar.proto │ │ │ └── plugin.proto │ ├── dynamic │ │ ├── common │ │ │ └── dynamic.proto │ │ ├── gw │ │ │ └── gateway.proto │ │ └── interfaces │ │ │ └── feed │ │ │ └── v1 │ │ │ └── api.proto │ ├── gaia │ │ └── gw │ │ │ └── gw_api.proto │ ├── im │ │ ├── interfaces │ │ │ ├── inner-interface │ │ │ │ └── v1 │ │ │ │ │ └── api.proto │ │ │ └── v1 │ │ │ │ └── im.proto │ │ └── type │ │ │ └── im.proto │ ├── live │ │ ├── app │ │ │ └── room │ │ │ │ └── v1 │ │ │ │ └── room.proto │ │ └── general │ │ │ └── interfaces │ │ │ └── v1 │ │ │ └── interfaces.proto │ ├── main │ │ ├── common │ │ │ └── arch │ │ │ │ └── doll │ │ │ │ └── v1 │ │ │ │ └── doll.proto │ │ └── community │ │ │ └── reply │ │ │ └── v1 │ │ │ └── reply.proto │ ├── metadata │ │ ├── device │ │ │ └── device.proto │ │ ├── fawkes │ │ │ └── fawkes.proto │ │ ├── locale │ │ │ └── locale.proto │ │ ├── metadata.proto │ │ ├── network │ │ │ └── network.proto │ │ ├── parabox │ │ │ └── parabox.proto │ │ └── restriction │ │ │ └── restriction.proto │ ├── pagination │ │ └── pagination.proto │ ├── pangu │ │ └── gallery │ │ │ └── v1 │ │ │ └── gallery.proto │ ├── pgc │ │ ├── gateway │ │ │ └── player │ │ │ │ ├── v1 │ │ │ │ └── playurl.proto │ │ │ │ └── v2 │ │ │ │ └── playurl.proto │ │ └── service │ │ │ └── premiere │ │ │ └── v1 │ │ │ └── premiere.proto │ ├── playershared │ │ └── playershared.proto │ ├── polymer │ │ ├── app │ │ │ └── search │ │ │ │ └── v1 │ │ │ │ └── search.proto │ │ ├── community │ │ │ └── govern │ │ │ │ └── v1 │ │ │ │ └── govern.proto │ │ ├── contract │ │ │ └── v1 │ │ │ │ └── contract.proto │ │ ├── demo │ │ │ └── demo.proto │ │ └── list │ │ │ └── v1 │ │ │ └── list.proto │ ├── relation │ │ └── interfaces │ │ │ └── api.proto │ ├── render │ │ └── render.proto │ ├── rpc │ │ └── status.proto │ ├── tv │ │ └── interfaces │ │ │ └── dm │ │ │ └── v1 │ │ │ └── dm.proto │ ├── vega │ │ └── deneb │ │ │ └── v1 │ │ │ └── deneb.proto │ └── web │ │ ├── interfaces │ │ └── v1 │ │ │ └── interfaces.proto │ │ └── space │ │ └── v1 │ │ └── space.proto │ ├── common │ └── ErrorProto.proto │ ├── datacenter │ └── hakase │ │ └── protobuf │ │ └── android_device_info.proto │ └── pgc │ ├── biz │ └── room.proto │ └── gateway │ └── vega │ └── v1 │ └── vega.proto ├── bili-api ├── .gitignore ├── build.gradle.kts ├── example-response │ └── live-event │ │ ├── COMBO_SEND.json5 │ │ ├── DANMU_MSG.json5 │ │ ├── ENTRY_EFFECT.json5 │ │ ├── GUARD_BUY.json5 │ │ ├── HOT_RANK_CHANGED.json5 │ │ ├── HOT_RANK_CHANGED_V2.json5 │ │ ├── HOT_RANK_SETTLEMENT.json5 │ │ ├── HOT_RANK_SETTLEMENT_V2.json5 │ │ ├── HOT_ROOM_NOTIFY.json5 │ │ ├── INTERACT_WORD.json5 │ │ ├── LIKE_INFO_V3_CLICK.json5 │ │ ├── LIKE_INFO_V3_UPDATE.json5 │ │ ├── LIVE_INTERACTIVE_GAME.json5 │ │ ├── LIVE_MULTI_VIEW_CHANGE.json5 │ │ ├── NOTICE_MSG.json5 │ │ ├── ONLINE_RANK_COUNT.json5 │ │ ├── ONLINE_RANK_TOP3.json5 │ │ ├── ONLINE_RANK_V2.json5 │ │ ├── PREPARING.json5 │ │ ├── ROOM_REAL_TIME_MESSAGE_UPDATE.json │ │ ├── SEND_GIFT.json │ │ ├── STOP_LIVE_ROOM_LIST.json5 │ │ ├── SUPER_CHAT_ENTRANCE.json5 │ │ ├── SUPER_CHAT_MESSAGE.json5 │ │ ├── SUPER_CHAT_MESSAGE_JPN.json5 │ │ ├── USER_TOAST_MSG.json5 │ │ ├── WATCHED_CHANGE.json5 │ │ └── WIDGET_BANNER.json5 └── src │ ├── main │ └── kotlin │ │ ├── com │ │ └── tfowl │ │ │ └── ktor │ │ │ └── client │ │ │ └── plugins │ │ │ └── JsoupPlugin.kt │ │ └── dev │ │ └── aaa1115910 │ │ └── biliapi │ │ ├── entity │ │ ├── ApiType.kt │ │ ├── CarouselData.kt │ │ ├── CodeType.kt │ │ ├── Favorite.kt │ │ ├── PlayData.kt │ │ ├── danmaku │ │ │ └── DanmakuMask.kt │ │ ├── home │ │ │ └── RecommendData.kt │ │ ├── login │ │ │ ├── Captcha.kt │ │ │ ├── QR.kt │ │ │ └── Sms.kt │ │ ├── pgc │ │ │ ├── PgcFeedData.kt │ │ │ ├── PgcItem.kt │ │ │ ├── PgcType.kt │ │ │ └── index │ │ │ │ ├── IndexParams.kt │ │ │ │ └── PgcIndexData.kt │ │ ├── rank │ │ │ └── Popular.kt │ │ ├── search │ │ │ └── Hotword.kt │ │ ├── season │ │ │ ├── FollowingSeasons.kt │ │ │ ├── IndexResult.kt │ │ │ └── Timeline.kt │ │ ├── ugc │ │ │ ├── UgcItem.kt │ │ │ ├── UgcType.kt │ │ │ └── region │ │ │ │ ├── UgcRegionData.kt │ │ │ │ ├── UgcRegionListData.kt │ │ │ │ └── UgcRegionPage.kt │ │ ├── user │ │ │ ├── Author.kt │ │ │ ├── Dynamic.kt │ │ │ ├── FollowedUser.kt │ │ │ ├── History.kt │ │ │ ├── Space.kt │ │ │ └── ToView.kt │ │ └── video │ │ │ ├── Dimension.kt │ │ │ ├── Heartbeat.kt │ │ │ ├── RelatedVideo.kt │ │ │ ├── Subtitle.kt │ │ │ ├── Tag.kt │ │ │ ├── VideoDetail.kt │ │ │ ├── VideoPage.kt │ │ │ ├── VideoShot.kt │ │ │ └── season │ │ │ ├── Episode.kt │ │ │ ├── PgcSeason.kt │ │ │ ├── SeasonDetail.kt │ │ │ └── Section.kt │ │ ├── grpc │ │ └── utils │ │ │ ├── Channel.kt │ │ │ └── StatusExtends.kt │ │ ├── http │ │ ├── BiliHttpApi.kt │ │ ├── BiliHttpProxyApi.kt │ │ ├── BiliLiveHttpApi.kt │ │ ├── BiliPassportHttpApi.kt │ │ ├── BiliPlusHttpApi.kt │ │ ├── entity │ │ │ ├── BiliResponse.kt │ │ │ ├── biliplus │ │ │ │ └── View.kt │ │ │ ├── danmaku │ │ │ │ └── DanmakuResponse.kt │ │ │ ├── dynamic │ │ │ │ └── DynamicResponse.kt │ │ │ ├── history │ │ │ │ └── HistoryData.kt │ │ │ ├── home │ │ │ │ ├── RcmdIndexData.kt │ │ │ │ └── RcmdTopData.kt │ │ │ ├── index │ │ │ │ ├── IndexFilter.kt │ │ │ │ ├── IndexFilterArea.kt │ │ │ │ ├── IndexFilterProducerId.kt │ │ │ │ ├── IndexFilterStyle.kt │ │ │ │ ├── IndexOrder.kt │ │ │ │ └── IndexResult.kt │ │ │ ├── live │ │ │ │ ├── HistoryDanmaku.kt │ │ │ │ ├── LiveDanmuInfoResponse.kt │ │ │ │ ├── LiveEvent.kt │ │ │ │ ├── LiveFrame.kt │ │ │ │ └── LiveRoomPlayInfoResponse.kt │ │ │ ├── login │ │ │ │ ├── Captcha.kt │ │ │ │ ├── qr │ │ │ │ │ ├── AppQR.kt │ │ │ │ │ └── WebQR.kt │ │ │ │ └── sms │ │ │ │ │ ├── SendSmsResponse.kt │ │ │ │ │ └── SmsLoginResponse.kt │ │ │ ├── pgc │ │ │ │ ├── PgcFeed.kt │ │ │ │ ├── PgcFeedV3.kt │ │ │ │ └── PgcWebInitialStateData.kt │ │ │ ├── proxy │ │ │ │ └── PlayUrl.kt │ │ │ ├── region │ │ │ │ ├── RegionDynamic.kt │ │ │ │ ├── RegionDynamicList.kt │ │ │ │ └── RegionLocs.kt │ │ │ ├── search │ │ │ │ ├── KeywordSuggest.kt │ │ │ │ ├── SearchCost.kt │ │ │ │ ├── SearchResult.kt │ │ │ │ ├── SearchResultItem.kt │ │ │ │ └── SearchSquare.kt │ │ │ ├── season │ │ │ │ ├── AppSeasonData.kt │ │ │ │ ├── Episode.kt │ │ │ │ ├── Follow.kt │ │ │ │ ├── SeasonSection.kt │ │ │ │ ├── WebFollowingSeason.kt │ │ │ │ └── WebSeasonData.kt │ │ │ ├── subtitle │ │ │ │ └── Subtitle.kt │ │ │ ├── toview │ │ │ │ └── ToViewData.kt │ │ │ ├── user │ │ │ │ ├── Follow.kt │ │ │ │ ├── LevelInfo.kt │ │ │ │ ├── Nameplate.kt │ │ │ │ ├── Official.kt │ │ │ │ ├── Pendant.kt │ │ │ │ ├── Profession.kt │ │ │ │ ├── Relation.kt │ │ │ │ ├── SpaceVideoData.kt │ │ │ │ ├── Staff.kt │ │ │ │ ├── UserCardInfoResponse.kt │ │ │ │ ├── UserGarb.kt │ │ │ │ ├── UserHonours.kt │ │ │ │ ├── UserInfoResponse.kt │ │ │ │ ├── UserSelfInfoResponse.kt │ │ │ │ ├── Vip.kt │ │ │ │ ├── favorite │ │ │ │ │ ├── CntInfo.kt │ │ │ │ │ ├── FavoriteFolderInfo.kt │ │ │ │ │ ├── FavoriteFolderInfoListData.kt │ │ │ │ │ ├── FavoriteItem.kt │ │ │ │ │ ├── Upper.kt │ │ │ │ │ └── UserFavoriteFoldersData.kt │ │ │ │ └── garb │ │ │ │ │ ├── CardBg.kt │ │ │ │ │ ├── Equip.kt │ │ │ │ │ └── Item.kt │ │ │ ├── video │ │ │ │ ├── AddCoin.kt │ │ │ │ ├── PlayUrlResponse.kt │ │ │ │ ├── PopularVideosResponse.kt │ │ │ │ ├── RelatedVideosResponse.kt │ │ │ │ ├── SetVideoFavorite.kt │ │ │ │ ├── Tag.kt │ │ │ │ ├── Timeline.kt │ │ │ │ ├── UgcSeason.kt │ │ │ │ ├── VideoDetail.kt │ │ │ │ ├── VideoInfo.kt │ │ │ │ ├── VideoMoreInfo.kt │ │ │ │ └── VideoShot.kt │ │ │ └── web │ │ │ │ ├── Hover.kt │ │ │ │ └── Nav.kt │ │ └── util │ │ │ ├── ApiSign.kt │ │ │ ├── BiliAppConf.kt │ │ │ ├── Buvid.kt │ │ │ ├── CommonEnumIntSerializer.kt │ │ │ └── Zlib.kt │ │ ├── repositories │ │ ├── AuthRepository.kt │ │ ├── ChannelRepository.kt │ │ ├── FavoriteRepository.kt │ │ ├── HistoryRepository.kt │ │ ├── LoginRepository.kt │ │ ├── PgcRepository.kt │ │ ├── RecommendVideoRepository.kt │ │ ├── SearchRepository.kt │ │ ├── SeasonRepository.kt │ │ ├── ToViewRepository.kt │ │ ├── UgcRepository.kt │ │ ├── UserRepository.kt │ │ ├── VideoDetailRepository.kt │ │ └── VideoPlayRepository.kt │ │ ├── util │ │ ├── AvBvConverter.kt │ │ ├── Extends.kt │ │ └── UrlUtil.kt │ │ └── websocket │ │ └── LiveDataWebSocket.kt │ └── test │ ├── kotlin │ └── dev │ │ └── aaa1115910 │ │ └── biliapi │ │ ├── BvLoginRepositoryTest.kt │ │ ├── entity │ │ └── DanmakuMaskTest.kt │ │ ├── http │ │ ├── BiliHttpApiTest.kt │ │ ├── BiliLiveHttpApiTest.kt │ │ ├── BiliPassportHttpApiTest.kt │ │ └── BiliPlusHttpApiTest.kt │ │ ├── repositories │ │ ├── FavoriteRepositoryTest.kt │ │ ├── HistoryRepositoryTest.kt │ │ ├── PgcRepositoryTest.kt │ │ ├── RecommendVideoRepositoryTest.kt │ │ ├── SearchRepositoryTest.kt │ │ ├── SeasonRepositoryTest.kt │ │ ├── UgcRepositoryTest.kt │ │ ├── UserRepositoryTest.kt │ │ ├── VideoDetailRepositoryTest.kt │ │ └── VideoPlayRepositoryTest.kt │ │ └── websocket │ │ └── LiveDataWebSocketTest.kt │ └── resources │ ├── 3540266_25_2.exp.mobmask │ └── 3540266_25_2.exp.webmask ├── bili-subtitle ├── .gitignore ├── build.gradle.kts └── src │ ├── main │ └── kotlin │ │ └── dev │ │ └── aaa1115910 │ │ └── bilisubtitle │ │ ├── SubtitleEncoder.kt │ │ ├── SubtitleParser.kt │ │ └── entity │ │ ├── BiliSubtitle.kt │ │ ├── SrtSubtitle.kt │ │ ├── SubtitleItem.kt │ │ └── Timestamp.kt │ └── test │ ├── kotlin │ └── dev │ │ └── aaa1115910 │ │ └── bilisubtitle │ │ ├── SubtitleEncoderTest.kt │ │ ├── SubtitleParserTest.kt │ │ └── entity │ │ └── TimestampTest.kt │ └── resources │ ├── example.bcc │ └── example.srt ├── build.gradle.kts ├── buildSrc ├── .gitignore ├── build.gradle.kts └── src │ └── main │ └── kotlin │ ├── AppConfiguration.kt │ └── ProtobufConfiguration.kt ├── bv-player ├── .gitignore ├── build.gradle.kts ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── dev │ │ └── aaa1115910 │ │ └── bv │ │ └── player │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── GlobalSign ECC Root CA R5.crt │ └── kotlin │ │ └── dev │ │ └── aaa1115910 │ │ └── bv │ │ └── player │ │ ├── AbstractVideoPlayer.kt │ │ ├── BvVideoPlayer.kt │ │ ├── Extends.kt │ │ ├── OkHttpUtil.kt │ │ ├── VideoPlayerListener.kt │ │ ├── VideoPlayerOptions.kt │ │ ├── factory │ │ └── PlayerFactory.kt │ │ └── impl │ │ └── exo │ │ ├── ExoMediaPlayer.kt │ │ └── ExoPlayerFactory.kt │ └── test │ └── java │ └── dev │ └── aaa1115910 │ └── bv │ └── player │ └── ExampleUnitTest.kt ├── gradle.properties ├── gradle ├── androidx.versions.toml ├── gradle.versions.toml ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle.kts /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: 功能需求 2 | description: 为项目提供建议 3 | title: "以简单的一段字概括你的建议" 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | ## 反馈须知 9 | - 请务必完整填写下面的内容,如果缺少必要的信息,将无法解决任何问题 10 | - 一个 issue 请只反馈一个 bug 或功能建议,一次性反馈多个不同的问题或建议或将会被直接关闭 11 | - 注意你的标题,以简单的一段字概括你所遇到的问题。不要使用无意义内容或全部复制粘贴 12 | - 提出建议也不一定会做,这不可能是万能的许愿机,如果自己确实想要,建议 fork 项目自己实现 13 | - 该项目不为任何旧版本提供维护支持,请务必确认已更新到最新版本 14 | 15 | - type: textarea 16 | id: problem-description 17 | validations: 18 | required: true 19 | attributes: 20 | label: 问题描述 21 | description: 描述你想要解决的问题或者功能的使用场景 22 | placeholder: 请描述你遇到的问题或者链接到已存在的 issue 23 | - type: textarea 24 | id: solution-description 25 | validations: 26 | required: true 27 | attributes: 28 | label: 描述解决方案 29 | description: 清晰简明地描述你所想要发生的事情,即解决方案 30 | - type: textarea 31 | id: alternatives 32 | attributes: 33 | label: 描述备选方案 34 | description: 解决该问题的备选方案 35 | - type: textarea 36 | id: additional-info 37 | attributes: 38 | label: 附加信息 39 | description: 添加你认为有必要的信息 40 | -------------------------------------------------------------------------------- /.github/workflows/auto_close_issues.yml: -------------------------------------------------------------------------------- 1 | name: Check Issues 2 | 3 | on: 4 | issues: 5 | types: [opened] 6 | jobs: 7 | check: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - if: contains(github.event.issue.body, '我正在使用旧版本' ) 11 | id: close-old-version 12 | name: Close Issue(template) 13 | uses: peter-evans/close-issue@v3 14 | with: 15 | comment: 请先尝试使用最新版本,如果问题依然存在再提交 issue -------------------------------------------------------------------------------- /.github/workflows/close_inactive_issues.yml: -------------------------------------------------------------------------------- 1 | name: Close inactive issues 2 | on: 3 | schedule: 4 | - cron: "30 1 * * *" 5 | 6 | jobs: 7 | close-issues: 8 | name: Close inactive issues 9 | runs-on: ubuntu-latest 10 | if: github.repository == 'aaa1115910/bv' 11 | permissions: 12 | issues: write 13 | steps: 14 | - uses: actions/stale@v5 15 | with: 16 | days-before-issue-stale: 60 17 | days-before-issue-close: 14 18 | days-before-pr-stale: -1 19 | stale-issue-label: "过时" 20 | stale-issue-message: "该 issue 已过时,因为它已经超过 60 天没有任何活动" 21 | close-issue-message: "该 issue 已关闭,因为它在被标记为过时后 14 天依旧没有任何活动" 22 | repo-token: ${{ secrets.GITHUB_TOKEN }} 23 | exempt-issue-labels: "bug,新功能,优化,有待讨论,疑难杂症" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .DS_Store 5 | /build 6 | /captures 7 | .externalNativeBuild 8 | .cxx 9 | /signing.properties 10 | /.idea/jarRepositories.xml 11 | /.idea/migrations.xml 12 | /.idea/codeStyles/ 13 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libs"] 2 | path = libs 3 | url = https://github.com/aaa1115910/bv-libs.git 4 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | /shelf/ 2 | /workspace.xml 3 | /deploymentTargetDropDown.xml 4 | /gradle.xml 5 | /caches 6 | /libraries 7 | /modules.xml 8 | /navEditor.xml 9 | /assetWizardSettings.xml 10 | /misc.xml 11 | /compiler.xml 12 | /inspectionProfiles/Project_Default.xml 13 | /CamelCaseConfigNew.xml 14 | # GitHub Copilot persisted chat sessions 15 | /copilot/chatSessions 16 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 aaa1115910 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | # BVG 6 | ## Big Video God(大唱神) 7 | 8 | [![Android Sdk Require](https://img.shields.io/badge/Android-5.0%2B-informational?logo=android)](https://apilevels.com/#:~:text=Jetpack%20Compose%20requires%20a%20minSdk%20of%2021%20or%20higher) 9 | [![GitHub](https://img.shields.io/github/license/aaa1115910/bv)](https://github.com/aaa1115910/bv) 10 | [![蓝奏云下载](https://img.shields.io/badge/123网盘-下载-informational?logo=123网盘)](https://www.123912.com/s/g8Ufjv-OmMih) 11 | 12 | # 该改版是给带键鼠的安卓设备使用的,严禁tv端使用,若有tv端使用者,请在24小时内删除否则后果自负,若有tv端使用需求,请下载官方小电视![![云视听小电视](https://img.shields.io/badge/bilibili-下载-informational?logo=bilibili)](https://app.bilibili.com) 13 | 14 | 15 | 该改版是基于原bv,已去除中国地区的使用限制,其他额外功能正在研发中,若觉得卡顿,请使用清浊等app对其进行编译 16 | 17 |
18 | 19 | --- 20 | BVG (Big Video God) 是一款 [哔哩哔哩](https://www.bilibili.com) 的第三方 `Android` 21 | 应用,使用 `Jetpack Compose` 开发,支持 `Android 5.0+` 22 | 23 | # 该版本对于某些低配机型消耗极大,由于技术原因暂时无法优化,若有对此方面的进度则会马上更新 24 | 25 | 26 | # 特色 27 | - :bug: 丰富多样的 Bug 28 | - :children_crossing: 反人类设计 29 | - :art: 异样审美 30 | - :disappointed: 巨难用 31 | - :zap: 卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡 32 | # 33 | # 安装 34 | BVG[![蓝奏云下载](https://img.shields.io/badge/123网盘-下载-informational?logo=123网盘)](https://www.123912.com/s/g8Ufjv-OmMih) 35 | 36 | # License 37 | [MIT](LICENSE) © aaa1115910 38 | # 39 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /google-services.json 3 | /release 4 | /r8Test 5 | /debug -------------------------------------------------------------------------------- /app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/debug/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | BVG Debug 4 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QcxFlora/BVG/bdf704e416e48023bf200261f328bc796abcbca7/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/kotlin/de/schnettler/datastore/manager/DataStoreManager.kt: -------------------------------------------------------------------------------- 1 | package de.schnettler.datastore.manager 2 | 3 | import androidx.datastore.core.DataStore 4 | import androidx.datastore.preferences.core.Preferences 5 | import androidx.datastore.preferences.core.edit 6 | import kotlinx.coroutines.flow.first 7 | import kotlinx.coroutines.flow.map 8 | 9 | class DataStoreManager(val dataStore: DataStore) { 10 | val preferenceFlow = dataStore.data 11 | 12 | suspend fun getPreference(preferenceEntry: PreferenceRequest) = 13 | preferenceFlow.first()[preferenceEntry.key] ?: preferenceEntry.defaultValue 14 | 15 | fun getPreferenceFlow(request: PreferenceRequest) = 16 | preferenceFlow.map { 17 | it[request.key] ?: request.defaultValue 18 | } 19 | 20 | suspend fun editPreference(key: Preferences.Key, newValue: T) { 21 | dataStore.edit { preferences -> 22 | preferences[key] = newValue 23 | } 24 | } 25 | 26 | suspend fun clearPreferences() { 27 | dataStore.edit { preferences -> preferences.clear() } 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/de/schnettler/datastore/manager/PreferenceRequest.kt: -------------------------------------------------------------------------------- 1 | package de.schnettler.datastore.manager 2 | 3 | import androidx.datastore.preferences.core.Preferences 4 | 5 | open class PreferenceRequest( 6 | val key: Preferences.Key, 7 | val defaultValue: T, 8 | ) -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/pgc/PgcIndexActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.pgc 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.os.Bundle 6 | import androidx.activity.ComponentActivity 7 | import androidx.activity.compose.setContent 8 | import dev.aaa1115910.biliapi.entity.pgc.PgcType 9 | import dev.aaa1115910.bv.screen.main.pgc.PgcIndexScreen 10 | import dev.aaa1115910.bv.ui.theme.BVTheme 11 | 12 | class PgcIndexActivity : ComponentActivity() { 13 | companion object { 14 | fun actionStart( 15 | context: Context, 16 | pgcType: PgcType 17 | ) { 18 | context.startActivity( 19 | Intent(context, PgcIndexActivity::class.java).apply { 20 | putExtra("pgcType", pgcType.ordinal) 21 | } 22 | ) 23 | } 24 | } 25 | 26 | override fun onCreate(savedInstanceState: Bundle?) { 27 | super.onCreate(savedInstanceState) 28 | setContent { 29 | BVTheme { 30 | PgcIndexScreen() 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/pgc/anime/AnimeTimelineActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.pgc.anime 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import dev.aaa1115910.bv.screen.main.pgc.anime.AnimeTimelineScreen 7 | import dev.aaa1115910.bv.ui.theme.BVTheme 8 | 9 | class AnimeTimelineActivity : ComponentActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContent { 13 | BVTheme { 14 | AnimeTimelineScreen() 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/search/SearchInputActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.search 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.compose.runtime.remember 7 | import androidx.compose.ui.focus.FocusRequester 8 | import dev.aaa1115910.bv.screen.search.SearchInputScreen 9 | import dev.aaa1115910.bv.ui.theme.BVTheme 10 | 11 | class SearchInputActivity : ComponentActivity() { 12 | override fun onCreate(savedInstanceState: Bundle?) { 13 | super.onCreate(savedInstanceState) 14 | setContent { 15 | val defaultFocusRequester = remember { FocusRequester() } 16 | BVTheme { 17 | SearchInputScreen(defaultFocusRequester = defaultFocusRequester) 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/search/SearchResultActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.search 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.os.Bundle 6 | import androidx.activity.ComponentActivity 7 | import androidx.activity.compose.setContent 8 | import dev.aaa1115910.bv.screen.search.SearchResultScreen 9 | import dev.aaa1115910.bv.ui.theme.BVTheme 10 | 11 | class SearchResultActivity : ComponentActivity() { 12 | companion object { 13 | fun actionStart(context: Context, keyword: String, enableProxy: Boolean) { 14 | context.startActivity( 15 | Intent(context, SearchResultActivity::class.java).apply { 16 | putExtra("keyword", keyword) 17 | putExtra("enableProxy", enableProxy) 18 | } 19 | ) 20 | } 21 | } 22 | 23 | override fun onCreate(savedInstanceState: Bundle?) { 24 | super.onCreate(savedInstanceState) 25 | setContent { 26 | BVTheme { 27 | SearchResultScreen() 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/settings/LogsActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.settings 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import dev.aaa1115910.bv.screen.settings.LogsScreen 7 | import dev.aaa1115910.bv.ui.theme.BVTheme 8 | 9 | class LogsActivity : ComponentActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContent { 13 | BVTheme { 14 | LogsScreen() 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/settings/MediaCodecActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.settings 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import dev.aaa1115910.bv.screen.settings.MediaCodecScreen 7 | import dev.aaa1115910.bv.ui.theme.BVTheme 8 | 9 | class MediaCodecActivity : ComponentActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContent { 13 | BVTheme { 14 | MediaCodecScreen() 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/settings/SettingsActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.settings 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import dev.aaa1115910.bv.screen.settings.SettingsScreen 7 | import dev.aaa1115910.bv.ui.theme.BVTheme 8 | 9 | class SettingsActivity : ComponentActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContent { 13 | BVTheme { 14 | SettingsScreen() 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/settings/SpeedTestActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.settings 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import dev.aaa1115910.bv.screen.settings.SpeedTestScreen 7 | import dev.aaa1115910.bv.ui.theme.BVTheme 8 | 9 | class SpeedTestActivity : ComponentActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContent { 13 | BVTheme { 14 | SpeedTestScreen() 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/user/FavoriteActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.user 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import dev.aaa1115910.bv.screen.user.FavoriteScreen 7 | import dev.aaa1115910.bv.ui.theme.BVTheme 8 | 9 | class FavoriteActivity : ComponentActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContent { 13 | BVTheme { 14 | FavoriteScreen() 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/user/FollowActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.user 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import dev.aaa1115910.bv.screen.user.FollowScreen 7 | import dev.aaa1115910.bv.ui.theme.BVTheme 8 | 9 | class FollowActivity : ComponentActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContent { 13 | BVTheme { 14 | FollowScreen() 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/user/FollowingSeasonActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.user 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import dev.aaa1115910.bv.screen.user.FollowingSeasonScreen 7 | import dev.aaa1115910.bv.ui.theme.BVTheme 8 | 9 | class FollowingSeasonActivity : ComponentActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContent { 13 | BVTheme { 14 | FollowingSeasonScreen() 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/user/HistoryActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.user 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import dev.aaa1115910.bv.screen.user.HistoryScreen 7 | import dev.aaa1115910.bv.ui.theme.BVTheme 8 | 9 | class HistoryActivity : ComponentActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContent { 13 | BVTheme { 14 | HistoryScreen() 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/user/LoginActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.user 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import dev.aaa1115910.bv.screen.login.LoginScreen 7 | import dev.aaa1115910.bv.ui.theme.BVTheme 8 | 9 | class LoginActivity : ComponentActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContent { 13 | BVTheme { 14 | LoginScreen() 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/user/ToViewActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.user 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | // import dev.aaa1115910.bv.screen.user.HistoryScreen 7 | import dev.aaa1115910.bv.screen.user.ToViewScreen 8 | import dev.aaa1115910.bv.ui.theme.BVTheme 9 | 10 | class ToViewActivity : ComponentActivity() { 11 | override fun onCreate(savedInstanceState: Bundle?) { 12 | super.onCreate(savedInstanceState) 13 | setContent { 14 | BVTheme { 15 | // HistoryScreen() 16 | ToViewScreen() 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/user/UserInfoActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.user 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import dev.aaa1115910.bv.screen.user.UserInfoScreen 7 | import dev.aaa1115910.bv.ui.theme.BVTheme 8 | 9 | class UserInfoActivity : ComponentActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContent { 13 | BVTheme { 14 | UserInfoScreen() 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/user/UserLockSettingsActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.user 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.os.Bundle 6 | import androidx.activity.ComponentActivity 7 | import androidx.activity.compose.setContent 8 | import dev.aaa1115910.bv.screen.user.lock.UserLockSettingsScreen 9 | import dev.aaa1115910.bv.ui.theme.BVTheme 10 | 11 | class UserLockSettingsActivity : ComponentActivity() { 12 | 13 | companion object { 14 | fun actionStart( 15 | context: Context, 16 | uid: Long 17 | ) { 18 | context.startActivity( 19 | Intent(context, UserLockSettingsActivity::class.java).apply { 20 | putExtra("uid", uid) 21 | } 22 | ) 23 | } 24 | } 25 | 26 | override fun onCreate(savedInstanceState: Bundle?) { 27 | super.onCreate(savedInstanceState) 28 | setContent { 29 | BVTheme { 30 | UserLockSettingsScreen() 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/user/UserSwitchActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.user 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import dev.aaa1115910.bv.screen.user.UserSwitchScreen 7 | import dev.aaa1115910.bv.ui.theme.BVTheme 8 | 9 | class UserSwitchActivity : ComponentActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContent { 13 | BVTheme { 14 | UserSwitchScreen() 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/video/SeasonInfoActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.video 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.os.Bundle 6 | import androidx.activity.ComponentActivity 7 | import androidx.activity.compose.setContent 8 | import dev.aaa1115910.bv.entity.proxy.ProxyArea 9 | import dev.aaa1115910.bv.screen.SeasonInfoScreen 10 | import dev.aaa1115910.bv.ui.theme.BVTheme 11 | 12 | class SeasonInfoActivity : ComponentActivity() { 13 | companion object { 14 | fun actionStart( 15 | context: Context, 16 | epId: Int? = null, 17 | seasonId: Int? = null, 18 | proxyArea: ProxyArea = ProxyArea.MainLand 19 | ) { 20 | context.startActivity( 21 | Intent(context, SeasonInfoActivity::class.java).apply { 22 | epId?.let { putExtra("epid", epId) } 23 | seasonId?.let { putExtra("seasonid", seasonId) } 24 | putExtra("proxy_area", proxyArea.ordinal) 25 | } 26 | ) 27 | } 28 | } 29 | 30 | override fun onCreate(savedInstanceState: Bundle?) { 31 | super.onCreate(savedInstanceState) 32 | setContent { 33 | BVTheme { 34 | SeasonInfoScreen() 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/video/TagActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.video 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.os.Bundle 6 | import androidx.activity.ComponentActivity 7 | import androidx.activity.compose.setContent 8 | import dev.aaa1115910.bv.screen.TagScreen 9 | import dev.aaa1115910.bv.ui.theme.BVTheme 10 | 11 | class TagActivity : ComponentActivity() { 12 | companion object { 13 | fun actionStart(context: Context, tagId: Int, tagName: String) { 14 | context.startActivity( 15 | Intent(context, TagActivity::class.java).apply { 16 | putExtra("tagId", tagId) 17 | putExtra("tagName", tagName) 18 | } 19 | ) 20 | } 21 | } 22 | 23 | override fun onCreate(savedInstanceState: Bundle?) { 24 | super.onCreate(savedInstanceState) 25 | setContent { 26 | BVTheme { 27 | TagScreen() 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/video/UpInfoActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.video 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.os.Bundle 6 | import androidx.activity.ComponentActivity 7 | import androidx.activity.compose.setContent 8 | import dev.aaa1115910.bv.screen.user.UpSpaceScreen 9 | import dev.aaa1115910.bv.ui.theme.BVTheme 10 | 11 | class UpInfoActivity : ComponentActivity() { 12 | companion object { 13 | fun actionStart(context: Context, mid: Long, name: String) { 14 | context.startActivity( 15 | Intent(context, UpInfoActivity::class.java).apply { 16 | putExtra("mid", mid) 17 | putExtra("name", name) 18 | } 19 | ) 20 | } 21 | } 22 | 23 | override fun onCreate(savedInstanceState: Bundle?) { 24 | super.onCreate(savedInstanceState) 25 | setContent { 26 | BVTheme { 27 | UpSpaceScreen() 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/activities/video/VideoInfoActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.activities.video 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.os.Bundle 6 | import androidx.activity.ComponentActivity 7 | import androidx.activity.compose.setContent 8 | import dev.aaa1115910.bv.entity.proxy.ProxyArea 9 | import dev.aaa1115910.bv.screen.VideoInfoScreen 10 | import dev.aaa1115910.bv.ui.theme.BVTheme 11 | 12 | class VideoInfoActivity : ComponentActivity() { 13 | companion object { 14 | fun actionStart( 15 | context: Context, aid: Long, 16 | fromSeason: Boolean = false, 17 | proxyArea: ProxyArea = ProxyArea.MainLand 18 | ) { 19 | context.startActivity( 20 | Intent(context, VideoInfoActivity::class.java).apply { 21 | putExtra("aid", aid) 22 | putExtra("fromSeason", fromSeason) 23 | putExtra("proxy_area", proxyArea.ordinal) 24 | } 25 | ) 26 | } 27 | } 28 | 29 | override fun onCreate(savedInstanceState: Bundle?) { 30 | super.onCreate(savedInstanceState) 31 | setContent { 32 | BVTheme { 33 | VideoInfoScreen() 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/component/BottomTip.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.component 2 | 3 | import androidx.compose.foundation.layout.Column 4 | import androidx.compose.foundation.layout.height 5 | import androidx.compose.material.icons.Icons 6 | import androidx.compose.material.icons.outlined.Info 7 | import androidx.compose.runtime.Composable 8 | import androidx.compose.ui.Modifier 9 | import androidx.compose.ui.unit.dp 10 | import androidx.tv.material3.Icon 11 | import androidx.tv.material3.MaterialTheme 12 | import androidx.tv.material3.Text 13 | 14 | @Composable 15 | fun BottomTip( 16 | modifier: Modifier = Modifier, 17 | text: String 18 | ) { 19 | Column( 20 | modifier = modifier 21 | ) { 22 | Icon( 23 | modifier = Modifier.height(48.dp), 24 | imageVector = Icons.Outlined.Info, 25 | contentDescription = null, 26 | tint = MaterialTheme.colorScheme.onSurface 27 | ) 28 | Text( 29 | text = text.replace("\n", "\n\n"), 30 | style = MaterialTheme.typography.bodySmall 31 | ) 32 | } 33 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/component/LoadingTip.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.component 2 | 3 | import androidx.compose.foundation.layout.Arrangement 4 | import androidx.compose.foundation.layout.Row 5 | import androidx.compose.foundation.layout.size 6 | import androidx.compose.material3.CircularProgressIndicator 7 | import androidx.compose.runtime.Composable 8 | import androidx.compose.ui.Alignment 9 | import androidx.compose.ui.Modifier 10 | import androidx.compose.ui.graphics.Color 11 | import androidx.compose.ui.res.stringResource 12 | import androidx.compose.ui.tooling.preview.Preview 13 | import androidx.compose.ui.unit.dp 14 | import androidx.tv.material3.Text 15 | import dev.aaa1115910.bv.R 16 | 17 | @Composable 18 | fun LoadingTip( 19 | modifier: Modifier = Modifier 20 | ) { 21 | Row( 22 | modifier = modifier, 23 | verticalAlignment = Alignment.CenterVertically, 24 | horizontalArrangement = Arrangement.spacedBy(8.dp) 25 | ) { 26 | CircularProgressIndicator( 27 | modifier = Modifier.size(36.dp) 28 | ) 29 | Text( 30 | text = stringResource(id = R.string.loading), 31 | color = Color.White 32 | ) 33 | } 34 | } 35 | 36 | @Preview 37 | @Composable 38 | private fun LoadingTipPreview() { 39 | LoadingTip() 40 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/component/UpIcon.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.component 2 | 3 | import androidx.compose.foundation.layout.Row 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Alignment 6 | import androidx.compose.ui.Modifier 7 | import androidx.compose.ui.graphics.Color 8 | import androidx.compose.ui.res.painterResource 9 | import androidx.compose.ui.tooling.preview.Preview 10 | import androidx.tv.material3.Icon 11 | import androidx.tv.material3.MaterialTheme 12 | import androidx.tv.material3.Text 13 | import dev.aaa1115910.bv.R 14 | import dev.aaa1115910.bv.ui.theme.BVTheme 15 | 16 | @Composable 17 | fun UpIcon( 18 | modifier: Modifier = Modifier, 19 | color: Color = MaterialTheme.colorScheme.onSurface 20 | ) { 21 | Icon( 22 | modifier = modifier, 23 | painter = painterResource(id = R.drawable.ic_up), 24 | contentDescription = null, 25 | tint = color 26 | ) 27 | } 28 | 29 | @Preview 30 | @Composable 31 | fun UpIconPreview() { 32 | BVTheme { 33 | Row( 34 | verticalAlignment = Alignment.CenterVertically 35 | ) { 36 | UpIcon() 37 | Text(text = "bishi") 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/component/controllers/GoBackHistoryTip.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.component.controllers 2 | 3 | import androidx.compose.foundation.layout.padding 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import androidx.compose.ui.graphics.Color 7 | import androidx.compose.ui.unit.dp 8 | import androidx.tv.material3.MaterialTheme 9 | import androidx.tv.material3.Surface 10 | import androidx.tv.material3.SurfaceDefaults 11 | import androidx.tv.material3.Text 12 | import dev.aaa1115910.bv.util.formatMinSec 13 | 14 | @Composable 15 | fun GoBackHistoryTip( 16 | modifier: Modifier = Modifier, 17 | played: Int 18 | ) { 19 | Surface( 20 | modifier = modifier, 21 | colors = SurfaceDefaults.colors( 22 | containerColor = Color.Black.copy(alpha = 0.6f) 23 | ) 24 | ) { 25 | Text( 26 | modifier = Modifier.padding(8.dp), 27 | text = "上次播放到 “${played.toLong().formatMinSec()}”,按下确认键返回", 28 | style = MaterialTheme.typography.titleLarge 29 | ) 30 | } 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/component/settings/SettingListItem.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.component.settings 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.runtime.getValue 5 | import androidx.compose.runtime.mutableStateOf 6 | import androidx.compose.runtime.remember 7 | import androidx.compose.runtime.setValue 8 | import androidx.compose.ui.Modifier 9 | import androidx.compose.ui.focus.onFocusChanged 10 | import androidx.tv.material3.ListItem 11 | import androidx.tv.material3.Text 12 | 13 | @Composable 14 | fun SettingListItem( 15 | modifier: Modifier = Modifier, 16 | title: String, 17 | supportText: String, 18 | defaultHasFocus: Boolean = false, 19 | onClick: () -> Unit 20 | ) { 21 | var hasFocus by remember { mutableStateOf(defaultHasFocus) } 22 | 23 | ListItem( 24 | modifier = modifier.onFocusChanged { hasFocus = it.hasFocus }, 25 | headlineContent = { Text(text = title) }, 26 | supportingContent = { Text(text = supportText) }, 27 | trailingContent = { }, 28 | onClick = onClick, 29 | selected = false 30 | ) 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/dao/SearchHistoryDao.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.dao 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Delete 5 | import androidx.room.Insert 6 | import androidx.room.Query 7 | import androidx.room.Update 8 | import dev.aaa1115910.bv.entity.db.SearchHistoryDB 9 | 10 | @Dao 11 | interface SearchHistoryDao { 12 | @Query("SELECT * FROM search_history") 13 | suspend fun getAll(): List 14 | 15 | @Query("SELECT * FROM search_history ORDER BY search_date DESC LIMIT :count") 16 | suspend fun getHistories(count: Int): List 17 | 18 | @Query("SELECT * FROM search_history WHERE keyword = :keyword LIMIT 1") 19 | suspend fun findHistory(keyword: String): SearchHistoryDB? 20 | 21 | @Insert 22 | suspend fun insert(vararg searchHistoryDB: SearchHistoryDB) 23 | 24 | @Delete 25 | suspend fun delete(vararg searchHistoryDB: SearchHistoryDB) 26 | 27 | @Update 28 | suspend fun update(searchHistoryDB: SearchHistoryDB) 29 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/dao/UserDao.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.dao 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Delete 5 | import androidx.room.Insert 6 | import androidx.room.Query 7 | import androidx.room.Update 8 | import dev.aaa1115910.bv.entity.db.UserDB 9 | 10 | @Dao 11 | interface UserDao { 12 | @Query("SELECT * FROM user") 13 | suspend fun getAll(): List 14 | 15 | @Query("SELECT * FROM user WHERE uid = :uid LIMIT 1") 16 | suspend fun findUserByUid(uid: Long): UserDB? 17 | 18 | @Insert 19 | suspend fun insert(vararg userDB: UserDB) 20 | 21 | @Delete 22 | suspend fun delete(vararg userDB: UserDB) 23 | 24 | @Update 25 | suspend fun update(userDB: UserDB) 26 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/entity/Audio.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.entity 2 | 3 | import android.content.Context 4 | import dev.aaa1115910.bv.R 5 | 6 | enum class Audio(val code: Int, private val strRes: Int) { 7 | A64K(30216, R.string.audio_64k), 8 | A132K(30232, R.string.audio_132k), 9 | A192K(30280, R.string.audio_192k), 10 | ADolbyAtoms(30250, R.string.audio_dolby_atoms), 11 | AHiRes(30251, R.string.audio_hi_res); 12 | 13 | companion object { 14 | fun fromCode(code: Int) = runCatching { 15 | entries.find { it.code == code } 16 | }.getOrDefault(A64K) 17 | } 18 | 19 | fun getDisplayName(context: Context) = context.getString(strRes) 20 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/entity/DanmakuSize.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.entity 2 | 3 | enum class DanmakuSize(val scale: Float) { 4 | S1(0.25f), S2(0.5f), S3(0.6f), S4(0.7f), S5(0.8f), S6(0.9f), S7(1f), 5 | S8(1.1f), S9(1.2f), S10(1.3f), S11(1.4f), S12(1.5f), S13(2f); 6 | 7 | companion object { 8 | fun fromOrdinal(ordinal: Int) = runCatching { entries[ordinal] } 9 | .getOrDefault(S2) 10 | } 11 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/entity/DanmakuTransparency.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.entity 2 | 3 | enum class DanmakuTransparency(val transparency: Float) { 4 | T1(1f), T2(0.9f), T3(0.8f), T4(0.7f), T5(0.6f), 5 | T6(0.5f), T7(0.3f), T8(0.2f), T9(0.1f); 6 | 7 | companion object { 8 | fun fromOrdinal(ordinal: Int) = runCatching { entries[ordinal] } 9 | .getOrDefault(T1) 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/entity/PlayerType.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.entity 2 | 3 | enum class PlayerType { 4 | Media3 5 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/entity/VideoAspectRatio.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.entity 2 | 3 | import android.content.Context 4 | import dev.aaa1115910.bv.R 5 | 6 | enum class VideoAspectRatio(private val strRes: Int) { 7 | Default(R.string.video_aspect_ratio_default), 8 | FourToThree(R.string.video_aspect_ratio_four_to_three), 9 | SixteenToNine(R.string.video_aspect_ratio_sixteen_to_nine); 10 | 11 | fun getDisplayName(context: Context) = context.getString(strRes) 12 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/entity/carddata/SeasonCardData.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.entity.carddata 2 | 3 | import dev.aaa1115910.biliapi.http.entity.search.SearchMediaResult 4 | import dev.aaa1115910.bv.util.ImageSize 5 | import dev.aaa1115910.bv.util.resizedImageUrl 6 | 7 | data class SeasonCardData( 8 | val seasonId: Int, 9 | val title: String, 10 | val subTitle: String? = null, 11 | val cover: String, 12 | val rating: String? = null, 13 | val badge: SearchMediaResult.Badge? = null, 14 | ) { 15 | companion object { 16 | fun fromPgcItem(pgcItem: dev.aaa1115910.biliapi.entity.pgc.PgcItem): SeasonCardData { 17 | return SeasonCardData( 18 | seasonId = pgcItem.seasonId, 19 | title = pgcItem.title, 20 | subTitle = pgcItem.subTitle, 21 | cover = pgcItem.cover.resizedImageUrl(ImageSize.SeasonCoverThumbnail), 22 | rating = pgcItem.rating, 23 | badge = null 24 | ) 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/entity/carddata/VideoCardData.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.entity.carddata 2 | 3 | import dev.aaa1115910.bv.util.formatMinSec 4 | 5 | data class VideoCardData( 6 | val avid: Long, 7 | val title: String, 8 | val cover: String, 9 | val upName: String, 10 | val reason: String = "", 11 | val play: Int? = null, 12 | var playString: String = "", 13 | val danmaku: Int? = null, 14 | var danmakuString: String = "", 15 | val time: Long? = null, 16 | var timeString: String = "", 17 | val jumpToSeason: Boolean = false, 18 | val epId: Int? = null 19 | ) { 20 | init { 21 | play?.let { 22 | playString = if (it >= 10000) "${it / 10000}万" else "$it" 23 | } 24 | danmaku?.let { 25 | danmakuString = if (it >= 10000) "${it / 10000}万" else "$it" 26 | } 27 | time?.let { 28 | timeString = if (it > 0) it.formatMinSec() else "" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/entity/db/SearchHistoryDB.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.entity.db 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | import java.util.Date 7 | 8 | @Entity(tableName = "search_history") 9 | data class SearchHistoryDB( 10 | @PrimaryKey(autoGenerate = true) val id: Int? = null, 11 | @ColumnInfo(name = "keyword") val keyword: String, 12 | @ColumnInfo(name = "search_date") var searchDate: Date = Date(), 13 | ) 14 | -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/entity/db/UserDB.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.entity.db 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | 7 | @Entity(tableName = "user") 8 | 9 | data class UserDB( 10 | @PrimaryKey(autoGenerate = true) val id: Int? = null, 11 | @ColumnInfo(name = "uid") val uid: Long, 12 | @ColumnInfo(name = "username") var username: String, 13 | @ColumnInfo(name = "avatar") var avatar: String, 14 | @ColumnInfo(name = "auth") var auth: String, 15 | @ColumnInfo(name = "lock", defaultValue = "") var lock: String = "", 16 | ) -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/entity/proxy/ProxyArea.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.entity.proxy 2 | 3 | import dev.aaa1115910.bv.util.Prefs 4 | import io.github.oshai.kotlinlogging.KotlinLogging 5 | 6 | enum class ProxyArea { 7 | MainLand, HongKong, TaiWan; 8 | 9 | companion object { 10 | private val logger = KotlinLogging.logger { } 11 | fun checkProxyArea(title: String): ProxyArea { 12 | val enableProxy = Prefs.enableProxy 13 | val proxyArea = when { 14 | !enableProxy -> MainLand 15 | title.contains(Regex("僅.*港")) -> HongKong 16 | title.contains(Regex("僅.*台")) -> TaiWan 17 | else -> MainLand 18 | } 19 | if (enableProxy) logger.debug { "Check proxy area: $title->$proxyArea" } 20 | return proxyArea 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/repository/VideoInfoRepository.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.repository 2 | 3 | class VideoInfoRepository { 4 | val videoList = mutableListOf() 5 | } 6 | 7 | data class VideoListItem( 8 | val aid: Long, 9 | val cid: Long, 10 | val epid: Int? = null, 11 | val seasonId: Int? = null, 12 | val title: String, 13 | val index: Int, 14 | val isEpisode: Boolean 15 | ) -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/login/LoginScreen.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.login 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.ui.Modifier 5 | 6 | @Composable 7 | fun LoginScreen( 8 | modifier: Modifier = Modifier 9 | ) { 10 | /*when (Prefs.apiType) { 11 | ApiType.Http -> { 12 | WebQRLoginContent(modifier) 13 | } 14 | 15 | ApiType.GRPC -> { 16 | SmsLoginContent(modifier) 17 | } 18 | }*/ 19 | AppQRLoginContent(modifier) 20 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/AnimalContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun AnimalContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { AnimalChildRegionButtons() }, 17 | ) 18 | } 19 | 20 | @Composable 21 | fun AnimalChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.AnimalCat, UgcType.AnimalDog, UgcType.AnimalReptiles, UgcType.AnimalWildAnima, 24 | UgcType.AnimalSecondEdition, UgcType.AnimalComposite 25 | ) 26 | 27 | UgcChildRegionButtons( 28 | modifier = modifier.fillMaxWidth(), 29 | childUgcTypes = ugcTypes 30 | ) 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/CarContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun CarContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { CarChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun CarChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.CarKnowledge, UgcType.CarStrategy, UgcType.CarNewEnergyVehicle, 24 | UgcType.CarRacing, UgcType.CarModifiedVehicle, UgcType.CarMotorcycle, 25 | UgcType.CarTouringCar, UgcType.CarLife 26 | ) 27 | 28 | UgcChildRegionButtons( 29 | modifier = modifier.fillMaxWidth(), 30 | childUgcTypes = ugcTypes 31 | ) 32 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/CinephileContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun CinephileContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { CinephileChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun CinephileChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.CinephileCinecism, UgcType.CinephileNibtage, UgcType.CinephileMashup, 24 | UgcType.CinephileAiImagine, UgcType.CinephileTrailerInfo, UgcType.CinephileShortPlay, 25 | UgcType.CinephileShortFilm, UgcType.CinephileComperhensive 26 | ) 27 | 28 | UgcChildRegionButtons( 29 | modifier = modifier.fillMaxWidth(), 30 | childUgcTypes = ugcTypes 31 | ) 32 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/DanceContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun DanceContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { DanceChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun DanceChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.DanceOtaku, UgcType.DanceHiphop, UgcType.DanceStar, UgcType.DanceChina, 24 | UgcType.DanceGestures, UgcType.DanceThreeD, UgcType.DanceDemo 25 | ) 26 | 27 | UgcChildRegionButtons( 28 | modifier = modifier.fillMaxWidth(), 29 | childUgcTypes = ugcTypes 30 | ) 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/DougaContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun DougaContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { DougaChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun DougaChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.DougaMad, UgcType.DougaMmd, UgcType.DougaHandDrawn, UgcType.DougaVoice, 24 | UgcType.DougaGarageKit, UgcType.DougaTokusatsu, UgcType.DougaAcgnTalks, UgcType.DougaOther 25 | ) 26 | 27 | UgcChildRegionButtons( 28 | modifier = modifier.fillMaxWidth(), 29 | childUgcTypes = ugcTypes 30 | ) 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/EntContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun EntContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { EntChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun EntChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.EntTalker, UgcType.EntCpRecommendation, UgcType.EntBeauty, UgcType.EntFans, 24 | UgcType.EntEntertainmentNews, UgcType.EntCelebrity, UgcType.EntVariety 25 | ) 26 | 27 | UgcChildRegionButtons( 28 | modifier = modifier.fillMaxWidth(), 29 | childUgcTypes = ugcTypes 30 | ) 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/FashionContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun FashionContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { FashionChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun FashionChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.FashionMakeup, UgcType.FashionCos, UgcType.FashionClothing, UgcType.FashionCatwalk 24 | ) 25 | 26 | UgcChildRegionButtons( 27 | modifier = modifier.fillMaxWidth(), 28 | childUgcTypes = ugcTypes 29 | ) 30 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/FoodContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun FoodContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { FoodChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun FoodChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.FoodMake, UgcType.FoodDetective, UgcType.FoodMeasurement, 24 | UgcType.FoodRural, UgcType.FoodRecord 25 | ) 26 | 27 | UgcChildRegionButtons( 28 | modifier = modifier.fillMaxWidth(), 29 | childUgcTypes = ugcTypes 30 | ) 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/GameContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun GameContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { GameChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun GameChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.GameStandAlone, UgcType.GameESports, UgcType.GameMobile, UgcType.GameOnline, 24 | UgcType.GameBoard, UgcType.GameGmv, UgcType.GameMusic, UgcType.GameMugen 25 | ) 26 | 27 | UgcChildRegionButtons( 28 | modifier = modifier.fillMaxWidth(), 29 | childUgcTypes = ugcTypes 30 | ) 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/InformationContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun InformationContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { InformationChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun InformationChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.InformationHotspot, UgcType.InformationGlobal, 24 | UgcType.InformationSocial, UgcType.InformationMultiple 25 | ) 26 | 27 | UgcChildRegionButtons( 28 | modifier = modifier.fillMaxWidth(), 29 | childUgcTypes = ugcTypes 30 | ) 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/KichikuContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun KichikuContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { KichikuChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun KichikuChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.KichikuGuide, UgcType.KichikuMad, UgcType.KichikuManualVocaloid, 24 | UgcType.KichikuTheatre, UgcType.KichikuCourse 25 | ) 26 | 27 | UgcChildRegionButtons( 28 | modifier = modifier.fillMaxWidth(), 29 | childUgcTypes = ugcTypes 30 | ) 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/KnowledgeContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun KnowledgeContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { KnowledgeChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun KnowledgeChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.KnowledgeScience, UgcType.KnowledgeSocialScience, UgcType.KnowledgeHumanity, 24 | UgcType.KnowledgeBusiness, UgcType.KnowledgeCampus, UgcType.KnowledgeCareer, 25 | UgcType.KnowledgeDesign, UgcType.KnowledgeSkill 26 | ) 27 | 28 | UgcChildRegionButtons( 29 | modifier = modifier.fillMaxWidth(), 30 | childUgcTypes = ugcTypes 31 | ) 32 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/LifeContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun LifeContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { LifeChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun LifeChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.LifeFunny, UgcType.LifeParenting, UgcType.LifeTravel, UgcType.LiseRuralLife, 24 | UgcType.LifeHome, UgcType.LifeHandMake, UgcType.LifePainting, UgcType.LifeDaily 25 | ) 26 | 27 | UgcChildRegionButtons( 28 | modifier = modifier.fillMaxWidth(), 29 | childUgcTypes = ugcTypes 30 | ) 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/MuiscContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun MusicContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { MusicChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun MusicChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.MusicOriginal, UgcType.MusicLive, UgcType.MusicCover, UgcType.MusicPerform, 24 | UgcType.MusicCommentary, UgcType.MusicVocaloidUtau, UgcType.MusicMv, UgcType.MusicFanVideos, 25 | UgcType.MusicAiMusic, UgcType.MusicRadio, UgcType.MusicTutorial, UgcType.MusicOther 26 | ) 27 | 28 | UgcChildRegionButtons( 29 | modifier = modifier.fillMaxWidth(), 30 | childUgcTypes = ugcTypes 31 | ) 32 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/SportsContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun SportsContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { SportsChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun SportsChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.SportsBasketball, UgcType.SportsFootball, UgcType.SportsAerobics, 24 | UgcType.SportsAthletic, UgcType.SportsCulture, UgcType.SportsComprehensive 25 | ) 26 | 27 | UgcChildRegionButtons( 28 | modifier = modifier.fillMaxWidth(), 29 | childUgcTypes = ugcTypes 30 | ) 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/screen/main/ugc/TechContent.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.screen.main.ugc 2 | 3 | import androidx.compose.foundation.layout.fillMaxWidth 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import dev.aaa1115910.biliapi.entity.ugc.UgcType 7 | 8 | @Composable 9 | fun TechContent( 10 | modifier: Modifier = Modifier, 11 | state: UgcScaffoldState 12 | ) { 13 | UgcRegionScaffold( 14 | modifier = modifier, 15 | state = state, 16 | childRegionButtons = { TechChildRegionButtons() } 17 | ) 18 | } 19 | 20 | @Composable 21 | fun TechChildRegionButtons(modifier: Modifier = Modifier) { 22 | val ugcTypes = listOf( 23 | UgcType.TechDigital, UgcType.TechApplication, UgcType.TechComputerTech, 24 | UgcType.TechIndustry, UgcType.TechDiy 25 | ) 26 | 27 | UgcChildRegionButtons( 28 | modifier = modifier.fillMaxWidth(), 29 | childUgcTypes = ugcTypes 30 | ) 31 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/util/EnumExtends.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.util 2 | 3 | import android.content.Context 4 | import dev.aaa1115910.biliapi.entity.season.FollowingSeasonStatus 5 | import dev.aaa1115910.biliapi.entity.season.FollowingSeasonType 6 | import dev.aaa1115910.bv.R 7 | 8 | fun FollowingSeasonStatus.getDisplayName(context: Context) = when (this) { 9 | FollowingSeasonStatus.All -> context.getString(R.string.following_season_status_all) 10 | FollowingSeasonStatus.Want -> context.getString(R.string.following_season_status_want) 11 | FollowingSeasonStatus.Watching -> context.getString(R.string.following_season_status_watching) 12 | FollowingSeasonStatus.Watched -> context.getString(R.string.following_season_status_watched) 13 | } 14 | 15 | fun FollowingSeasonType.getDisplayName(context: Context) = when (this) { 16 | FollowingSeasonType.Bangumi -> context.getString(R.string.following_season_type_bangumi) 17 | FollowingSeasonType.Cinema -> context.getString(R.string.following_season_type_film_and_television) 18 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/util/FirebaseUtil.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.util 2 | 3 | import android.content.Context 4 | import com.google.firebase.FirebaseApp 5 | import com.google.firebase.analytics.ktx.analytics 6 | import com.google.firebase.crashlytics.ktx.crashlytics 7 | import com.google.firebase.ktx.Firebase 8 | 9 | object FirebaseUtil { 10 | private var initialized = false 11 | 12 | fun init(context: Context) { 13 | initialized = FirebaseApp.initializeApp(context) != null 14 | } 15 | 16 | fun log(msg: String) { 17 | if (!initialized) return 18 | Firebase.crashlytics.log(msg) 19 | } 20 | 21 | fun recordException(throwable: Throwable) { 22 | if (!initialized) return 23 | Firebase.crashlytics.recordException(throwable) 24 | } 25 | 26 | fun setCrashlyticsCollectionEnabled(enable: Boolean) { 27 | if (!initialized) return 28 | Firebase.crashlytics.setCrashlyticsCollectionEnabled(enable) 29 | Firebase.analytics.setAnalyticsCollectionEnabled(enable) 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/util/ImageExtends.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.util 2 | 3 | fun String.resizedImageUrl(size: ImageSize): String { 4 | return when (size) { 5 | ImageSize.Default -> this 6 | else -> "$this@${size.sizeString}.webp" 7 | } 8 | } 9 | 10 | enum class ImageSize(val sizeString: String) { 11 | Default(""), 12 | Cover("180h_288w_1c"), 13 | SmallVideoCardCover("400h_640w_1c"), 14 | SeasonCoverThumbnail("466h_622w") 15 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/util/PgcTypeExtends.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.util 2 | 3 | import android.content.Context 4 | import dev.aaa1115910.biliapi.entity.pgc.PgcType 5 | import dev.aaa1115910.bv.R 6 | 7 | fun PgcType.getDisplayName(context: Context) = when (this) { 8 | PgcType.Anime -> R.string.pgc_type_anime 9 | PgcType.GuoChuang -> R.string.pgc_type_guochuang 10 | PgcType.Movie -> R.string.pgc_type_movie 11 | PgcType.Documentary -> R.string.pgc_type_documentary 12 | PgcType.Tv -> R.string.pgc_type_tv 13 | PgcType.Variety -> R.string.pgc_type_variety 14 | }.stringRes(context) -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/pgc/PgcAnimeViewModel.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.viewmodel.pgc 2 | 3 | import dev.aaa1115910.biliapi.repositories.PgcRepository 4 | import dev.aaa1115910.biliapi.entity.pgc.PgcType 5 | 6 | class PgcAnimeViewModel( 7 | override val pgcRepository: PgcRepository 8 | ) : PgcViewModel( 9 | pgcRepository = pgcRepository, 10 | pgcType = PgcType.Anime 11 | ) -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/pgc/PgcDocumentaryViewModel.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.viewmodel.pgc 2 | 3 | import dev.aaa1115910.biliapi.repositories.PgcRepository 4 | import dev.aaa1115910.biliapi.entity.pgc.PgcType 5 | 6 | class PgcDocumentaryViewModel( 7 | override val pgcRepository: PgcRepository 8 | ) : PgcViewModel( 9 | pgcRepository = pgcRepository, 10 | pgcType = PgcType.Documentary 11 | ) -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/pgc/PgcGuoChuangViewModel.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.viewmodel.pgc 2 | 3 | import dev.aaa1115910.biliapi.repositories.PgcRepository 4 | import dev.aaa1115910.biliapi.entity.pgc.PgcType 5 | 6 | class PgcGuoChuangViewModel( 7 | override val pgcRepository: PgcRepository 8 | ) : PgcViewModel( 9 | pgcRepository = pgcRepository, 10 | pgcType = PgcType.GuoChuang 11 | ) -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/pgc/PgcMovieViewModel.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.viewmodel.pgc 2 | 3 | import dev.aaa1115910.biliapi.repositories.PgcRepository 4 | import dev.aaa1115910.biliapi.entity.pgc.PgcType 5 | 6 | class PgcMovieViewModel( 7 | override val pgcRepository: PgcRepository 8 | ) : PgcViewModel( 9 | pgcRepository = pgcRepository, 10 | pgcType = PgcType.Movie 11 | ) -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/pgc/PgcTvViewModel.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.viewmodel.pgc 2 | 3 | import dev.aaa1115910.biliapi.repositories.PgcRepository 4 | import dev.aaa1115910.biliapi.entity.pgc.PgcType 5 | 6 | class PgcTvViewModel( 7 | override val pgcRepository: PgcRepository 8 | ) : PgcViewModel( 9 | pgcRepository = pgcRepository, 10 | pgcType = PgcType.Tv 11 | ) -------------------------------------------------------------------------------- /app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/pgc/PgcVarietyViewModel.kt: -------------------------------------------------------------------------------- 1 | package dev.aaa1115910.bv.viewmodel.pgc 2 | 3 | import dev.aaa1115910.biliapi.repositories.PgcRepository 4 | import dev.aaa1115910.biliapi.entity.pgc.PgcType 5 | 6 | class PgcVarietyViewModel( 7 | override val pgcRepository: PgcRepository 8 | ) : PgcViewModel( 9 | pgcRepository = pgcRepository, 10 | pgcType = PgcType.Variety 11 | ) -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_banner.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QcxFlora/BVG/bdf704e416e48023bf200261f328bc796abcbca7/app/src/main/res/drawable/ic_banner.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_banner_foreground.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 14 | 19 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_danmaku_count.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 6 | 11 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_play_count.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/font/noto_sans_math_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QcxFlora/BVG/bdf704e416e48023bf200261f328bc796abcbca7/app/src/main/res/font/noto_sans_math_regular.ttf -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_banner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QcxFlora/BVG/bdf704e416e48023bf200261f328bc796abcbca7/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QcxFlora/BVG/bdf704e416e48023bf200261f328bc796abcbca7/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QcxFlora/BVG/bdf704e416e48023bf200261f328bc796abcbca7/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QcxFlora/BVG/bdf704e416e48023bf200261f328bc796abcbca7/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QcxFlora/BVG/bdf704e416e48023bf200261f328bc796abcbca7/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QcxFlora/BVG/bdf704e416e48023bf200261f328bc796abcbca7/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QcxFlora/BVG/bdf704e416e48023bf200261f328bc796abcbca7/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QcxFlora/BVG/bdf704e416e48023bf200261f328bc796abcbca7/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QcxFlora/BVG/bdf704e416e48023bf200261f328bc796abcbca7/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QcxFlora/BVG/bdf704e416e48023bf200261f328bc796abcbca7/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | #FFFFFF 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 |