├── .github ├── ISSUE_TEMPLATE │ ├── bug-反馈.md │ └── 功能请求.md └── workflows │ ├── alpha.yml │ └── release.yml ├── .gitignore ├── .metadata ├── .vscode ├── launch.json └── settings.json ├── LICENSE ├── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── app │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── debug │ │ ├── AndroidManifest.xml │ │ ├── ic_launcher-playstore.png │ │ └── res │ │ │ ├── drawable │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── 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 │ │ │ └── ic_launcher_background.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── ic_launcher-playstore.png │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── orz12 │ │ │ │ └── PiliPalaX │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-anydpi-v24 │ │ │ └── ic_notification_icon.xml │ │ │ ├── drawable-hdpi-v26 │ │ │ └── ic_launcher_monochrome.png │ │ │ ├── drawable-hdpi │ │ │ ├── ic_notification_icon.png │ │ │ └── splash.png │ │ │ ├── drawable-mdpi-v26 │ │ │ └── ic_launcher_monochrome.png │ │ │ ├── drawable-mdpi │ │ │ ├── ic_notification_icon.png │ │ │ └── splash.png │ │ │ ├── drawable-night-hdpi │ │ │ └── splash.png │ │ │ ├── drawable-night-mdpi │ │ │ └── splash.png │ │ │ ├── drawable-night-v21 │ │ │ ├── background.png │ │ │ └── launch_background.xml │ │ │ ├── drawable-night-xhdpi │ │ │ └── splash.png │ │ │ ├── drawable-night-xxhdpi │ │ │ └── splash.png │ │ │ ├── drawable-night-xxxhdpi │ │ │ └── splash.png │ │ │ ├── drawable-night │ │ │ ├── background.png │ │ │ └── launch_background.xml │ │ │ ├── drawable-v21 │ │ │ ├── background.png │ │ │ └── launch_background.xml │ │ │ ├── drawable-xhdpi-v26 │ │ │ └── ic_launcher_monochrome.png │ │ │ ├── drawable-xhdpi │ │ │ ├── ic_notification_icon.png │ │ │ └── splash.png │ │ │ ├── drawable-xxhdpi-v26 │ │ │ └── ic_launcher_monochrome.png │ │ │ ├── drawable-xxhdpi │ │ │ ├── ic_notification_icon.png │ │ │ └── splash.png │ │ │ ├── drawable-xxxhdpi-v26 │ │ │ └── ic_launcher_monochrome.png │ │ │ ├── drawable-xxxhdpi │ │ │ └── splash.png │ │ │ ├── drawable │ │ │ ├── background.png │ │ │ ├── ic_baseline_forward_10_24.xml │ │ │ ├── ic_baseline_replay_10_24.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── ic_launcher_foreground.xml │ │ │ ├── ic_launcher_monochrome.xml │ │ │ ├── ic_notification_icon.xml │ │ │ └── launch_background.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── raw │ │ │ └── keep.xml │ │ │ ├── values-night-v31 │ │ │ └── styles.xml │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ ├── values-v31 │ │ │ └── styles.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── assets ├── fonts │ ├── Jura-Bold.ttf │ └── fansCard.ttf ├── images │ ├── ai.png │ ├── big-vip.png │ ├── dm.svg │ ├── dm_gray.png │ ├── dm_white.png │ ├── error.svg │ ├── live.gif │ ├── live.png │ ├── live │ │ └── default_bg.webp │ ├── loading.gif │ ├── loading.png │ ├── logo │ │ ├── logo_android.png │ │ ├── logo_android_2.png │ │ └── logo_ios.png │ ├── lv │ │ ├── lv0.png │ │ ├── lv1.png │ │ ├── lv2.png │ │ ├── lv3.png │ │ ├── lv4.png │ │ ├── lv5.png │ │ └── lv6.png │ ├── noface.jpeg │ ├── play.png │ ├── play.svg │ ├── run-pokemon.gif │ ├── tv.svg │ ├── up.svg │ ├── up_gray.png │ ├── view.svg │ ├── view_gray.png │ └── view_white.png └── screenshots │ ├── 174shots_so.png │ ├── 510shots_so.png │ ├── 850shots_so.png │ ├── bangumi.png │ ├── bangumi_detail.png │ ├── dynamic.png │ ├── home.png │ ├── main_screen.png │ ├── media.png │ ├── member.png │ ├── search.png │ └── set.png ├── change_log ├── 1.0.0.0817.md ├── 1.0.1.0817.md ├── 1.0.10.1016.md ├── 1.0.11.1112.md ├── 1.0.12.1114.md ├── 1.0.13.1217.md ├── 1.0.14.1225.md ├── 1.0.15.0101.md ├── 1.0.16.0102.md ├── 1.0.17.0125.md ├── 1.0.18.0130.md ├── 1.0.19.0131.md ├── 1.0.2.0819.md ├── 1.0.3.0821.md ├── 1.0.4.0822.md ├── 1.0.5.0826.md ├── 1.0.6.0902.md ├── 1.0.7.0908.md ├── 1.0.8.0917.md └── 1.0.9.1015.md ├── fastlane └── metadata │ └── android │ ├── en-US │ ├── full_description.txt │ ├── images │ │ ├── featureGraphic.png │ │ ├── icon.png │ │ └── phoneScreenshots │ │ │ ├── 1.png │ │ │ ├── 2.png │ │ │ └── 3.png │ ├── short_description.txt │ └── title.txt │ └── zh-CN │ ├── full_description.txt │ ├── images │ ├── featureGraphic.png │ ├── icon.png │ └── phoneScreenshots │ │ ├── 1.png │ │ ├── 2.png │ │ └── 3.png │ ├── short_description.txt │ └── title.txt ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── 100.png │ │ ├── 1024.png │ │ ├── 114.png │ │ ├── 120.png │ │ ├── 144.png │ │ ├── 152.png │ │ ├── 167.png │ │ ├── 180.png │ │ ├── 20.png │ │ ├── 29.png │ │ ├── 40.png │ │ ├── 50.png │ │ ├── 57.png │ │ ├── 58.png │ │ ├── 60.png │ │ ├── 72.png │ │ ├── 76.png │ │ ├── 80.png │ │ ├── 87.png │ │ └── Contents.json │ ├── LaunchBackground.imageset │ │ ├── Contents.json │ │ ├── background.png │ │ └── darkbackground.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ ├── LaunchImageDark.png │ │ ├── LaunchImageDark@2x.png │ │ ├── LaunchImageDark@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h ├── lib ├── common │ ├── constants.dart │ ├── skeleton │ │ ├── dynamic_card.dart │ │ ├── media_bangumi.dart │ │ ├── skeleton.dart │ │ ├── video_card_h.dart │ │ ├── video_card_v.dart │ │ └── video_reply.dart │ └── widgets │ │ ├── animated_dialog.dart │ │ ├── app_expansion_panel_list.dart │ │ ├── appbar.dart │ │ ├── audio_video_progress_bar.dart │ │ ├── badge.dart │ │ ├── content_container.dart │ │ ├── custom_toast.dart │ │ ├── html_render.dart │ │ ├── http_error.dart │ │ ├── list_sheet.dart │ │ ├── live_card.dart │ │ ├── my_dialog.dart │ │ ├── network_img_layer.dart │ │ ├── no_data.dart │ │ ├── overlay_pop.dart │ │ ├── pull_to_refresh_header.dart │ │ ├── sliver_header.dart │ │ ├── spring_physics.dart │ │ ├── stat │ │ ├── danmu.dart │ │ └── view.dart │ │ ├── video_card_h.dart │ │ ├── video_card_v.dart │ │ └── video_popup_menu.dart ├── http │ ├── api.dart │ ├── bangumi.dart │ ├── black.dart │ ├── common.dart │ ├── constants.dart │ ├── danmaku.dart │ ├── danmaku_block.dart │ ├── dynamics.dart │ ├── fan.dart │ ├── follow.dart │ ├── html.dart │ ├── index.dart │ ├── init.dart │ ├── interceptor.dart │ ├── interceptor_anonymity.dart │ ├── live.dart │ ├── login.dart │ ├── member.dart │ ├── msg.dart │ ├── reply.dart │ ├── search.dart │ ├── user.dart │ └── video.dart ├── main.dart ├── models │ ├── bangumi │ │ ├── info.dart │ │ └── list.dart │ ├── common │ │ ├── business_type.dart │ │ ├── color_type.dart │ │ ├── dynamic_badge_mode.dart │ │ ├── dynamics_type.dart │ │ ├── nav_bar_config.dart │ │ ├── rank_type.dart │ │ ├── rcmd_type.dart │ │ ├── reply_sort_type.dart │ │ ├── reply_type.dart │ │ ├── search_type.dart │ │ ├── side_bar_position.dart │ │ ├── tab_type.dart │ │ ├── theme_type.dart │ │ └── up_panel_position.dart │ ├── danmaku │ │ ├── dm.pb.dart │ │ ├── dm.pbenum.dart │ │ ├── dm.pbjson.dart │ │ ├── dm.pbserver.dart │ │ └── dm.proto │ ├── dynamics │ │ ├── result.dart │ │ └── up.dart │ ├── fans │ │ └── result.dart │ ├── follow │ │ └── result.dart │ ├── github │ │ └── latest.dart │ ├── home │ │ └── rcmd │ │ │ └── result.dart │ ├── live │ │ ├── item.dart │ │ ├── room_info.dart │ │ └── room_info_h5.dart │ ├── login │ │ └── index.dart │ ├── member │ │ ├── archive.dart │ │ ├── coin.dart │ │ ├── info.dart │ │ ├── seasons.dart │ │ └── tags.dart │ ├── model_hot_video_item.dart │ ├── model_owner.dart │ ├── model_owner.g.dart │ ├── model_rec_video_item.dart │ ├── model_rec_video_item.g.dart │ ├── msg │ │ ├── account.dart │ │ ├── msgfeed_at_me.dart │ │ ├── msgfeed_like_me.dart │ │ ├── msgfeed_reply_me.dart │ │ ├── msgfeed_sys_msg.dart │ │ ├── msgfeed_unread.dart │ │ └── session.dart │ ├── search │ │ ├── hot.dart │ │ ├── hot.g.dart │ │ ├── result.dart │ │ └── suggest.dart │ ├── user │ │ ├── black.dart │ │ ├── danmaku_block.dart │ │ ├── fav_detail.dart │ │ ├── fav_folder.dart │ │ ├── history.dart │ │ ├── info.dart │ │ ├── info.g.dart │ │ ├── my_emote.dart │ │ ├── stat.dart │ │ ├── stat.g.dart │ │ ├── sub_detail.dart │ │ └── sub_folder.dart │ ├── video │ │ ├── ai.dart │ │ ├── play │ │ │ ├── CDN.dart │ │ │ ├── quality.dart │ │ │ ├── subtitle.dart │ │ │ └── url.dart │ │ └── reply │ │ │ ├── config.dart │ │ │ ├── content.dart │ │ │ ├── data.dart │ │ │ ├── emote.dart │ │ │ ├── item.dart │ │ │ ├── member.dart │ │ │ ├── page.dart │ │ │ ├── top_replies.dart │ │ │ └── upper.dart │ └── video_detail_res.dart ├── pages │ ├── about │ │ └── index.dart │ ├── bangumi │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ ├── bangumi_card_v.dart │ │ │ └── bangumi_panel.dart │ ├── blacklist │ │ └── index.dart │ ├── danmaku │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── danmaku_block │ │ └── index.dart │ ├── dynamics │ │ ├── controller.dart │ │ ├── detail │ │ │ ├── controller.dart │ │ │ ├── index.dart │ │ │ └── view.dart │ │ ├── index.dart │ │ ├── tab │ │ │ ├── controller.dart │ │ │ ├── index.dart │ │ │ └── view.dart │ │ ├── view.dart │ │ └── widgets │ │ │ ├── action_panel.dart │ │ │ ├── additional_panel.dart │ │ │ ├── article_panel.dart │ │ │ ├── author_panel.dart │ │ │ ├── content_panel.dart │ │ │ ├── dynamic_panel.dart │ │ │ ├── forward_panel.dart │ │ │ ├── live_panel.dart │ │ │ ├── live_rcmd_panel.dart │ │ │ ├── pic_panel.dart │ │ │ ├── rich_node_panel.dart │ │ │ ├── up_panel.dart │ │ │ └── video_panel.dart │ ├── emote │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── fan │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ └── fan_item.dart │ ├── fav │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ └── item.dart │ ├── fav_detail │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widget │ │ │ └── fav_video_card.dart │ ├── fav_search │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── follow │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ ├── follow_item.dart │ │ │ ├── follow_list.dart │ │ │ └── owner_follow_list.dart │ ├── follow_search │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── history │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ └── item.dart │ ├── history_search │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── home │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ └── app_bar.dart │ ├── hot │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── html │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── later │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── live │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ └── live_item.dart │ ├── live_room │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ └── bottom_control.dart │ ├── login │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── main │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── media │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── member │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ ├── conis.dart │ │ │ ├── profile.dart │ │ │ └── seasons.dart │ ├── member_archive │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── member_coin │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ └── item.dart │ ├── member_dynamics │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── member_like │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── member_search │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── member_season │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ └── item.dart │ ├── member_seasons_and_series │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── member_series │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ └── item.dart │ ├── mine │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── msg_feed_top │ │ ├── at_me │ │ │ ├── controller.dart │ │ │ ├── index.dart │ │ │ └── view.dart │ │ ├── like_me │ │ │ ├── controller.dart │ │ │ ├── index.dart │ │ │ └── view.dart │ │ ├── reply_me │ │ │ ├── controller.dart │ │ │ ├── index.dart │ │ │ └── view.dart │ │ └── sys_msg │ │ │ ├── controller.dart │ │ │ ├── index.dart │ │ │ └── view.dart │ ├── preview │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── rank │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── zone │ │ │ ├── controller.dart │ │ │ ├── index.dart │ │ │ └── view.dart │ ├── rcmd │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── search │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ ├── hot_keyword.dart │ │ │ └── search_text.dart │ ├── search_panel │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ ├── article_panel.dart │ │ │ ├── live_panel.dart │ │ │ ├── media_bangumi_panel.dart │ │ │ ├── user_panel.dart │ │ │ └── video_panel.dart │ ├── search_result │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── setting │ │ ├── controller.dart │ │ ├── extra_setting.dart │ │ ├── hidden_settings.dart │ │ ├── index.dart │ │ ├── pages │ │ │ ├── color_select.dart │ │ │ ├── display_mode.dart │ │ │ ├── font_size_select.dart │ │ │ ├── gesture_select.dart │ │ │ ├── home_tabbar_set.dart │ │ │ ├── logs.dart │ │ │ └── play_speed_set.dart │ │ ├── play_setting.dart │ │ ├── privacy_setting.dart │ │ ├── recommend_setting.dart │ │ ├── style_setting.dart │ │ ├── video_setting.dart │ │ ├── view.dart │ │ └── widgets │ │ │ ├── select_dialog.dart │ │ │ ├── select_item.dart │ │ │ ├── slide_dialog.dart │ │ │ └── switch_item.dart │ ├── subscription │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widgets │ │ │ └── item.dart │ ├── subscription_detail │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widget │ │ │ └── sub_video_card.dart │ ├── video │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── introduction │ │ │ ├── bangumi │ │ │ │ ├── controller.dart │ │ │ │ ├── index.dart │ │ │ │ └── view.dart │ │ │ ├── detail │ │ │ │ ├── controller.dart │ │ │ │ ├── index.dart │ │ │ │ └── view.dart │ │ │ └── widgets │ │ │ │ ├── action_item.dart │ │ │ │ ├── action_row_item.dart │ │ │ │ ├── bangumi_intro_detail.dart │ │ │ │ ├── fav_panel.dart │ │ │ │ ├── group_panel.dart │ │ │ │ ├── intro_detail.dart │ │ │ │ ├── menu_row.dart │ │ │ │ ├── page.dart │ │ │ │ └── season.dart │ │ ├── related │ │ │ ├── controller.dart │ │ │ ├── index.dart │ │ │ └── view.dart │ │ ├── reply │ │ │ ├── controller.dart │ │ │ ├── index.dart │ │ │ ├── view.dart │ │ │ └── widgets │ │ │ │ ├── reply_item.dart │ │ │ │ └── zan.dart │ │ ├── reply_new │ │ │ ├── index.dart │ │ │ ├── toolbar_icon_button.dart │ │ │ └── view.dart │ │ ├── reply_reply │ │ │ ├── controller.dart │ │ │ ├── index.dart │ │ │ └── view.dart │ │ ├── view.dart │ │ └── widgets │ │ │ ├── ai_detail.dart │ │ │ ├── app_bar.dart │ │ │ ├── expandable_section.dart │ │ │ └── header_control.dart │ ├── webview │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ ├── whisper │ │ ├── controller.dart │ │ ├── index.dart │ │ └── view.dart │ └── whisper_detail │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── view.dart │ │ └── widget │ │ └── chat_item.dart ├── plugin │ └── pl_player │ │ ├── controller.dart │ │ ├── index.dart │ │ ├── models │ │ ├── bottom_control_type.dart │ │ ├── bottom_progress_behavior.dart │ │ ├── data_source.dart │ │ ├── data_status.dart │ │ ├── duration.dart │ │ ├── fullscreen_mode.dart │ │ ├── play_repeat.dart │ │ ├── play_speed.dart │ │ ├── play_status.dart │ │ ├── player_gesture_action.dart │ │ └── player_middle_gesture.dart │ │ ├── utils.dart │ │ ├── utils │ │ └── fullscreen.dart │ │ ├── view.dart │ │ └── widgets │ │ ├── app_bar_ani.dart │ │ ├── backward_seek.dart │ │ ├── bottom_control.dart │ │ ├── common_btn.dart │ │ ├── forward_seek.dart │ │ └── play_pause_btn.dart ├── router │ └── app_pages.dart ├── scripts │ └── build.sh ├── services │ ├── audio_handler.dart │ ├── audio_session.dart │ ├── loggeer.dart │ ├── service_locator.dart │ └── shutdown_timer_service.dart └── utils │ ├── app_scheme.dart │ ├── cache_manage.dart │ ├── danmaku.dart │ ├── data.dart │ ├── download.dart │ ├── em.dart │ ├── event_bus.dart │ ├── extension.dart │ ├── feed_back.dart │ ├── global_data.dart │ ├── grid.dart │ ├── id_utils.dart │ ├── login.dart │ ├── proxy.dart │ ├── recommend_filter.dart │ ├── storage.dart │ ├── url_utils.dart │ ├── utils.dart │ ├── video_utils.dart │ └── wbi_sign.dart ├── linux ├── .gitignore ├── CMakeLists.txt ├── flutter │ └── CMakeLists.txt ├── main.cc ├── my_application.cc └── my_application.h ├── macos ├── .gitignore ├── Flutter │ ├── Flutter-Debug.xcconfig │ └── Flutter-Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── 1024.png │ │ ├── 128.png │ │ ├── 16.png │ │ ├── 256.png │ │ ├── 32.png │ │ ├── 512.png │ │ ├── 64.png │ │ └── Contents.json │ ├── Base.lproj │ └── MainMenu.xib │ ├── Configs │ ├── AppInfo.xcconfig │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── Warnings.xcconfig │ ├── DebugProfile.entitlements │ ├── Info.plist │ ├── MainFlutterWindow.swift │ └── Release.entitlements ├── pubspec.lock ├── pubspec.yaml ├── test └── widget_test.dart ├── web ├── favicon.png ├── icons │ ├── Icon-192.png │ ├── Icon-512.png │ ├── Icon-maskable-192.png │ └── Icon-maskable-512.png ├── index.html ├── manifest.json └── splash │ └── img │ ├── dark-1x.png │ ├── dark-2x.png │ ├── dark-3x.png │ ├── dark-4x.png │ ├── light-1x.png │ ├── light-2x.png │ ├── light-3x.png │ └── light-4x.png └── windows ├── .gitignore ├── CMakeLists.txt ├── flutter └── CMakeLists.txt └── runner ├── CMakeLists.txt ├── Runner.rc ├── flutter_window.cpp ├── flutter_window.h ├── main.cpp ├── resource.h ├── resources └── app_icon.ico ├── runner.exe.manifest ├── utils.cpp ├── utils.h ├── win32_window.cpp └── win32_window.h /.github/ISSUE_TEMPLATE/bug-反馈.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug 反馈 3 | about: 描述你所遇到的bug 4 | title: "[Bug] " 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### 问题描述 11 | 12 | ### 复现步骤 13 | 14 | 15 | ### 预期行为 16 | 17 | 18 | ### 错误日志 19 | 20 |
21 | 22 | ``` 23 | 24 | ``` 25 | 26 |
27 | 28 | ### 相关信息 29 | 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/功能请求.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 功能请求 3 | about: 对于功能的一些建议 4 | title: "[FR] " 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### 功能描述 11 | 请提供对所请求功能的清晰描述。 12 | 13 | ### 目标 14 | 请描述你希望通过这个功能实现的目标。 15 | 16 | ### 解决方案 17 | 如果你有任何关于如何实现这个功能的想法或建议,请在这里提供。 18 | 19 | ### 其他 20 | 请提供已实现该功能或类似功能的应用 21 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "pilipala", 9 | "request": "launch", 10 | "type": "dart" 11 | }, 12 | { 13 | "name": "pilipala (profile mode)", 14 | "request": "launch", 15 | "type": "dart", 16 | "flutterMode": "profile" 17 | }, 18 | { 19 | "name": "pilipala (release mode)", 20 | "request": "launch", 21 | "type": "dart", 22 | "flutterMode": "release" 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "[dart]": { 4 | "editor.formatOnType": true 5 | } 6 | } -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | -dontwarn com.android.org.conscrypt.SSLParametersImpl 2 | -dontwarn javax.annotation.Nullable 3 | -dontwarn org.apache.harmony.xnet.provider.jsse.SSLParametersImpl -------------------------------------------------------------------------------- /android/app/src/debug/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/debug/ic_launcher-playstore.png -------------------------------------------------------------------------------- /android/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/debug/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/debug/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /android/app/src/debug/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/debug/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /android/app/src/debug/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/debug/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /android/app/src/debug/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/debug/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /android/app/src/debug/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/debug/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /android/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /android/app/src/debug/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/debug/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /android/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /android/app/src/debug/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/debug/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /android/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /android/app/src/debug/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /android/app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/orz12/PiliPalaX/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.orz12.PiliPalaX 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | import io.flutter.embedding.engine.FlutterEngine 5 | //import io.flutter.plugin.common.MethodChannel 6 | import com.ryanheise.audioservice.AudioServiceActivity 7 | import com.ryanheise.audioservice.AudioServicePlugin 8 | import android.os.Build 9 | import android.os.Bundle 10 | //import android.view.WindowManager.LayoutParams 11 | import fl.pip.FlPiPActivity 12 | import android.content.Context 13 | import androidx.annotation.NonNull 14 | 15 | //class AudioServiceActivity : FlPiPActivity() { 16 | class MainActivity: FlPiPActivity() { 17 | // private lateinit var methodChannel: MethodChannel 18 | 19 | override fun provideFlutterEngine(context: Context): FlutterEngine { 20 | return AudioServicePlugin.getFlutterEngine(context) 21 | } 22 | // override fun configureFlutterEngine(flutterEngine: FlutterEngine) { 23 | // super.configureFlutterEngine(flutterEngine) 24 | // methodChannel = MethodChannel(flutterEngine!!.getDartExecutor()!!.getBinaryMessenger(), CHANNEL) 25 | // } 26 | 27 | // override fun onCreate(savedInstanceState: Bundle?) { 28 | // super.onCreate(savedInstanceState) 29 | // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { 30 | // window.attributes.layoutInDisplayCutoutMode = 31 | // LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 32 | // } 33 | // } 34 | 35 | // override fun onUserLeaveHint() { 36 | // super.onUserLeaveHint() 37 | // methodChannel.invokeMethod("onUserLeaveHint", null) 38 | // } 39 | 40 | // companion object { 41 | // private const val CHANNEL = "onUserLeaveHint" 42 | // } 43 | } 44 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-anydpi-v24/ic_notification_icon.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | 16 | 21 | 26 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-hdpi-v26/ic_launcher_monochrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-hdpi-v26/ic_launcher_monochrome.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-hdpi/ic_notification_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-hdpi/ic_notification_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-hdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi-v26/ic_launcher_monochrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-mdpi-v26/ic_launcher_monochrome.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/ic_notification_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-mdpi/ic_notification_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-mdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-night-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-night-hdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-night-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-night-mdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-night-v21/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-night-v21/background.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-night-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-night-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-night-xhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-night-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-night-xxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-night-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-night-xxxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-night/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-night/background.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-night/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-v21/background.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi-v26/ic_launcher_monochrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-xhdpi-v26/ic_launcher_monochrome.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/ic_notification_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-xhdpi/ic_notification_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-xhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi-v26/ic_launcher_monochrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-xxhdpi-v26/ic_launcher_monochrome.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi/ic_notification_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-xxhdpi/ic_notification_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-xxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxxhdpi-v26/ic_launcher_monochrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-xxxhdpi-v26/ic_launcher_monochrome.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable-xxxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/drawable/background.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/ic_baseline_forward_10_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/ic_baseline_replay_10_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 13 | 15 | 17 | 19 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/ic_notification_icon.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | 16 | 21 | 26 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/raw/keep.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night-v31/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 17 | 20 | 21 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 19 | 22 | 23 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-v31/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 17 | 20 | 21 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ffffff 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xms1024m -Xmx4096m 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Oct 14 04:55:29 CST 2024 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | }() 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | maven { url "https://maven.aliyun.com/repository/google" } 14 | maven { url "https://maven.aliyun.com/repository/central" } 15 | maven { url "https://maven.aliyun.com/repository/jcenter" } 16 | maven { url "https://maven.aliyun.com/repository/public" } 17 | maven { url "http://download.flutter.io" 18 | allowInsecureProtocol = true 19 | } 20 | google() 21 | mavenCentral() 22 | gradlePluginPortal() 23 | } 24 | } 25 | 26 | plugins { 27 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 28 | id "com.android.application" version "8.7.0" apply false 29 | // id "com.android.library" version "8.7.0" apply false 30 | id "org.jetbrains.kotlin.android" version "2.0.20" apply false 31 | } 32 | 33 | include ":app" -------------------------------------------------------------------------------- /assets/fonts/Jura-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/fonts/Jura-Bold.ttf -------------------------------------------------------------------------------- /assets/fonts/fansCard.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/fonts/fansCard.ttf -------------------------------------------------------------------------------- /assets/images/ai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/ai.png -------------------------------------------------------------------------------- /assets/images/big-vip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/big-vip.png -------------------------------------------------------------------------------- /assets/images/dm_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/dm_gray.png -------------------------------------------------------------------------------- /assets/images/dm_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/dm_white.png -------------------------------------------------------------------------------- /assets/images/live.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/live.gif -------------------------------------------------------------------------------- /assets/images/live.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/live.png -------------------------------------------------------------------------------- /assets/images/live/default_bg.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/live/default_bg.webp -------------------------------------------------------------------------------- /assets/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/loading.gif -------------------------------------------------------------------------------- /assets/images/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/loading.png -------------------------------------------------------------------------------- /assets/images/logo/logo_android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/logo/logo_android.png -------------------------------------------------------------------------------- /assets/images/logo/logo_android_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/logo/logo_android_2.png -------------------------------------------------------------------------------- /assets/images/logo/logo_ios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/logo/logo_ios.png -------------------------------------------------------------------------------- /assets/images/lv/lv0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/lv/lv0.png -------------------------------------------------------------------------------- /assets/images/lv/lv1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/lv/lv1.png -------------------------------------------------------------------------------- /assets/images/lv/lv2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/lv/lv2.png -------------------------------------------------------------------------------- /assets/images/lv/lv3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/lv/lv3.png -------------------------------------------------------------------------------- /assets/images/lv/lv4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/lv/lv4.png -------------------------------------------------------------------------------- /assets/images/lv/lv5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/lv/lv5.png -------------------------------------------------------------------------------- /assets/images/lv/lv6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/lv/lv6.png -------------------------------------------------------------------------------- /assets/images/noface.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/noface.jpeg -------------------------------------------------------------------------------- /assets/images/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/play.png -------------------------------------------------------------------------------- /assets/images/play.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/run-pokemon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/run-pokemon.gif -------------------------------------------------------------------------------- /assets/images/tv.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/up_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/up_gray.png -------------------------------------------------------------------------------- /assets/images/view.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /assets/images/view_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/view_gray.png -------------------------------------------------------------------------------- /assets/images/view_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/images/view_white.png -------------------------------------------------------------------------------- /assets/screenshots/174shots_so.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/screenshots/174shots_so.png -------------------------------------------------------------------------------- /assets/screenshots/510shots_so.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/screenshots/510shots_so.png -------------------------------------------------------------------------------- /assets/screenshots/850shots_so.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/screenshots/850shots_so.png -------------------------------------------------------------------------------- /assets/screenshots/bangumi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/screenshots/bangumi.png -------------------------------------------------------------------------------- /assets/screenshots/bangumi_detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/screenshots/bangumi_detail.png -------------------------------------------------------------------------------- /assets/screenshots/dynamic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/screenshots/dynamic.png -------------------------------------------------------------------------------- /assets/screenshots/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/screenshots/home.png -------------------------------------------------------------------------------- /assets/screenshots/main_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/screenshots/main_screen.png -------------------------------------------------------------------------------- /assets/screenshots/media.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/screenshots/media.png -------------------------------------------------------------------------------- /assets/screenshots/member.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/screenshots/member.png -------------------------------------------------------------------------------- /assets/screenshots/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/screenshots/search.png -------------------------------------------------------------------------------- /assets/screenshots/set.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/assets/screenshots/set.png -------------------------------------------------------------------------------- /change_log/1.0.0.0817.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0 2 | 3 | ### 初始版本 4 | + 直播、推荐、动态功能 5 | + 投稿、番剧播放功能 6 | + 播放器手势支持 7 | + 画质、音质、解码格式支持 8 | + 点赞、投币、收藏功能 9 | + 关注/取关、用户主页功能 10 | + 评论功能 11 | + 历史记录、稍后再看功能 -------------------------------------------------------------------------------- /change_log/1.0.1.0817.md: -------------------------------------------------------------------------------- 1 | ## 1.0.1 2 | 3 | ### 修复 4 | + 升级播放器依赖 5 | + android平台 AV1格式视频支持 6 | + 视频全屏功能 7 | 8 | -------------------------------------------------------------------------------- /change_log/1.0.10.1016.md: -------------------------------------------------------------------------------- 1 | ## 1.0.10 2 | 3 | ### 修复 4 | + 长按倍速抬起后未恢复默认倍速 -------------------------------------------------------------------------------- /change_log/1.0.11.1112.md: -------------------------------------------------------------------------------- 1 | ## 1.0.11 2 | 3 | ### 新功能 4 | + 适配了原生媒体通知栏 @Daydreamer-riri 5 | + 视频主题图标 @Daydreamer-riri 6 | + 关闭软件后自动画中画播放 7 | + UP主分组管理 8 | + md2样式底栏 9 | + 10 | 11 | 12 | ### 修复 13 | + 历史记录记忆播放 14 | + 部分类型视频连播 15 | + 播放速度选择框不支持返回手势 16 | + 播放速度选择框不支持返回手势 17 | + 视频播放速度总是显示1.0X 18 | + 评论页面计数错误 19 | + 退出视频还有声音 20 | 21 | 22 | ### 优化 23 | + 视频加载速度 24 | 25 | 更多更新日志可在Github上查看 26 | 问题反馈、功能建议请查看「关于」页面。 -------------------------------------------------------------------------------- /change_log/1.0.12.1114.md: -------------------------------------------------------------------------------- 1 | ## 1.0.12 2 | 3 | 4 | ### 修复 5 | + iOS端视频播放时没有声音 6 | + 超过6分钟弹幕不显示 7 | + 视频详情页网络异常 8 | 9 | 10 | 更多更新日志可在Github上查看 11 | 问题反馈、功能建议请查看「关于」页面。 -------------------------------------------------------------------------------- /change_log/1.0.13.1217.md: -------------------------------------------------------------------------------- 1 | ## 1.0.13 2 | 3 | 4 | ### 新功能 5 | + 视频详情页稍后再看 6 | + 发送弹幕 感谢@orz12 7 | + 消息展示 8 | + up主页显示获赞数 9 | + up主页显示合集 10 | + 视频详情页「ai总结」增加开关 11 | 12 | ### 修复 13 | + 首页推荐问题(需要重新登录) 14 | + 长按倍速逻辑 15 | + 视频详情页网络异常 16 | 17 | ### 优化 18 | + 设置面板样式 感谢@GuMengYu @KoolShow 19 | 20 | 21 | 更多更新日志可在Github上查看 22 | 问题反馈、功能建议请查看「关于」页面。 23 | -------------------------------------------------------------------------------- /change_log/1.0.14.1225.md: -------------------------------------------------------------------------------- 1 | ## 1.0.14 2 | 3 | 圣诞节快乐~ 🎉 4 | 5 | 大部分内容由@orz12提供,感谢👏 6 | 7 | ### 修复 8 | + 全屏弹幕消失 9 | + iOS全屏/退出全屏视频暂停 10 | + 个人主页关注状态 11 | + 视频合集向下滑动UI问题 12 | + 媒体库滑动底栏不隐藏 13 | + 个人主页动态加载问题 * 2 14 | + 未登录状态访问个人主页异常 15 | + 视频搜索标题特殊字符转义 16 | + iOS闪退 17 | + 消息页面夜间模式异常 18 | + 消息页面含有撤回消息时异常 19 | + 弹幕速度 20 | 21 | ### 优化 22 | + 全屏播放方案优化 23 | + 弹幕加载逻辑优化 24 | + 点赞、投币逻辑优化 25 | + 进度条及播放时间渲染优化 26 | 27 | 更多更新日志可在Github上查看 28 | 问题反馈、功能建议请查看「关于」页面。 29 | -------------------------------------------------------------------------------- /change_log/1.0.15.0101.md: -------------------------------------------------------------------------------- 1 | ## 1.0.15 2 | 3 | 元旦快乐~ 🎉 4 | 5 | ### 功能 6 | + 转发动态评论展示 7 | + 推荐、最热、收藏视频增肌日期显示 8 | 9 | ### 修复 10 | + 全屏播放相关问题 11 | + 评论区@用户展示问题 12 | + 登录状态闪退问题 13 | + pip意外触发问题 14 | + 动态页tab切换样式问题 15 | 16 | ### 优化 17 | + 首页默认使用web端推荐 18 | + 取消iOS路由切换效果 19 | + 视频分享中添加Up主 20 | 21 | 更多更新日志可在Github上查看 22 | 问题反馈、功能建议请查看「关于」页面。 23 | -------------------------------------------------------------------------------- /change_log/1.0.16.0102.md: -------------------------------------------------------------------------------- 1 | ## 1.0.16 2 | 3 | 4 | ### 功能 5 | + toast 背景支持透明度调节 6 | 7 | ### 修复 8 | + web端推荐未展示【已关注】 9 | + up主动态页异常 10 | + 未打开自动播放时,视频详情页异常 11 | + 视频暂停状态取消自动ip 12 | 13 | 14 | 更多更新日志可在Github上查看 15 | 问题反馈、功能建议请查看「关于」页面。 16 | -------------------------------------------------------------------------------- /change_log/1.0.17.0125.md: -------------------------------------------------------------------------------- 1 | ## 1.0.17 2 | 3 | 4 | ### 功能 5 | + 视频全屏时隐藏进度条 6 | + 动态内容增加投稿跳转 7 | + 未开启自动播放时点击封面播放 8 | + 弹幕发送标识 9 | + 定时关闭 10 | + 推荐视频卡片拉黑up功能 11 | + 首页tabbar编辑排序 12 | 13 | ### 修复 14 | + 连续跳转搜索页未刷新 15 | + 搜索结果为空时页面异常 16 | + 评论区链接解析 17 | + 视频全屏状态栏背景色 18 | + 私信对话气泡位置 19 | + 设置up关注分组样式 20 | + 每次推荐请求数据相同 21 | + iOS代理网络异常 22 | + 双击切换播放状态无声 23 | + 设置自定义倍速白屏 24 | + 免登录查看1080p 25 | 26 | ### 优化 27 | + 首页web端推荐观看数展示 28 | + 首页web端推荐接口更新 29 | + 首页样式 30 | + 搜索页跳转 31 | + 弹幕资源优化 32 | + 图片渲染占用内存优化(部分) 33 | + 两次返回退出应用 34 | + schame 补充 35 | 36 | 37 | 38 | 更多更新日志可在Github上查看 39 | 问题反馈、功能建议请查看「关于」页面。 40 | -------------------------------------------------------------------------------- /change_log/1.0.18.0130.md: -------------------------------------------------------------------------------- 1 | ## 1.0.18 2 | 3 | 4 | ### 功能 5 | 6 | 7 | ### 修复 8 | 9 | 10 | ### 优化 11 | 12 | 13 | 14 | 15 | 更多更新日志可在Github上查看 16 | 问题反馈、功能建议请查看「关于」页面。 17 | -------------------------------------------------------------------------------- /change_log/1.0.19.0131.md: -------------------------------------------------------------------------------- 1 | ## 1.0.19 2 | 3 | 4 | ### 修复 5 | + 视频404、评论加载错误 6 | + bvav转换 7 | 8 | ### 优化 9 | + 视频详情页内存占用 10 | 11 | 12 | 13 | 14 | 更多更新日志可在Github上查看 15 | 问题反馈、功能建议请查看「关于」页面。 16 | -------------------------------------------------------------------------------- /change_log/1.0.2.0819.md: -------------------------------------------------------------------------------- 1 | ## 1.0.2 2 | 3 | ### 新功能 4 | + 自动检查更新 5 | + 封面图片保存 6 | + 动态跳转番剧 7 | + 历史记录番剧记忆播放 8 | + 一键清空稍后再看 9 | 10 | ### 修复 11 | + 切换分P cid未切换 12 | + cookie存储问题 13 | + 登录/退出登录问题 14 | 15 | ### 优化 16 | + 页面空/异常状态样式 17 | + 退出登录提示 18 | + 请求节流 19 | + 全屏播放 -------------------------------------------------------------------------------- /change_log/1.0.3.0821.md: -------------------------------------------------------------------------------- 1 | ## 1.0.3 2 | 3 | 建议卸载1.0.2版本,重新安装 4 | ### 新功能 5 | + 底部播放进度条设置 6 | + 复制图片链接 7 | 8 | 9 | ### 修复 10 | + 用户数据格式修改 11 | + video Fit 12 | + 没有audio 资源的视频异常 13 | + 评论区域图片无法点击 14 | + 视频进度条拖动问题 15 | 16 | ### 优化 17 | + 页面空/异常状态样式 18 | + 部分页面样式 19 | + 图片预览页面样式 -------------------------------------------------------------------------------- /change_log/1.0.4.0822.md: -------------------------------------------------------------------------------- 1 | ## 1.0.4 2 | 3 | ### 新功能 4 | + 热搜刷新 5 | + 视频搜索排序、筛选 6 | + app字体大小自定义 7 | + app主题色自定义 8 | + 「课堂」类动态渲染 9 | 10 | 11 | ### 修复 12 | + 搜索词联想richText渲染异常 13 | + 部分动态点赞异常 14 | + 默认视频解码格式 15 | + 搜索页面返回搜索词未清空 16 | + 动态详情评论加载异常 17 | + 动态页面下拉刷新数据异常 18 | 19 | ### 优化 20 | + 一些样式修改 21 | + 取消热搜词缓存 -------------------------------------------------------------------------------- /change_log/1.0.5.0826.md: -------------------------------------------------------------------------------- 1 | ## 1.0.5 2 | 3 | 主要是bug修复跟一部分小功能,弹幕功能需要下一版。 4 | 问题反馈请前往QQ频道或提交issues。 5 | 感谢🙏酷友「无力感*」「斤斤计较呀」「Pseudopamine」 6 | 7 | ### 新功能 8 | + 高帧率支持 9 | + 默认评论排序设置 10 | + 默认动态类别设置 11 | + 动态合集查看 12 | + 同时观看人数 13 | + iOS路由切换效果 14 | 15 | 16 | ### 修复 17 | + 收藏夹翻页 18 | + 首页搜索框频繁点击消失 19 | + 评论排序切换空白 20 | + 快速返回首页 21 | + 重复进入个人中心页面数据未刷新 22 | + 动态goods数据异常 23 | + 大会员切换番剧 24 | + 高画质codes匹配 25 | 26 | 27 | ### 优化 28 | + 倍速选择 29 | + 播放器亮度记忆 30 | + 下载对应版本apk -------------------------------------------------------------------------------- /change_log/1.0.6.0902.md: -------------------------------------------------------------------------------- 1 | ## 1.0.6 2 | 3 | 问题反馈、功能建议请查看「关于」页面。 4 | 5 | ### 新功能 6 | + 首页单列布局 7 | + 首页推荐展示播放量、弹幕数 8 | + 简单弹幕功能实现(持续开发中...) 9 | + 评论区搜索关键词开关 issues#46 10 | + 热搜榜隐藏功能 issues#35 11 | + 自动全屏 issues#37 12 | + 快速收藏功能 13 | + 双击快进/快退开关 14 | + 评论链接跳转视频 15 | + 支持移除单个稍后再看 16 | + app scheme外链跳转 17 | 18 | 19 | ### 修复 20 | + 杜比、无损音频切换 21 | + 收藏夹展示 issues#42 22 | + 搜索建议次 issues#47 23 | 24 | 25 | ### 优化 26 | + 倍速选择优化 27 | + 导航条沉浸 28 | + 取消Hero动画 29 | + 视频锁定逻辑 30 | + 登录逻辑优化 31 | + 图片预览样式 32 | + +评论区用户点击范围 33 | + 关注、粉丝页面优化 34 | + 关闭自动播放时播放器初始化逻辑 -------------------------------------------------------------------------------- /change_log/1.0.7.0908.md: -------------------------------------------------------------------------------- 1 | ## 1.0.7 2 | 3 | 默认倍速、直播弹幕、专栏等功能开发中 4 | 5 | ### 新功能 6 | + 弹幕设置、屏蔽功能 7 | + 不是很完美的后台播放功能 8 | + 不是很完美的画中画(pip)功能(Android端) 9 | 10 | ### 修复 11 | + 动态页面加载异常 12 | + 网络异常时页面空白 13 | + 竖屏全屏状态栏问题 14 | + iOS端代理请求异常 15 | 16 | ### 优化 17 | + 图片预览 18 | + 全屏播放时自动旋转 19 | + 转发内容增加视频标题 20 | 21 | 更多更新日志可在Github上查看 22 | 问题反馈、功能建议请查看「关于」页面。 23 | -------------------------------------------------------------------------------- /change_log/1.0.8.0917.md: -------------------------------------------------------------------------------- 1 | ## 1.0.8 2 | 3 | 直播弹幕、循环播放等功能开发中 4 | 5 | ### 新功能 6 | + 用户拉黑功能 7 | + gif图片保存 8 | + 删除已看历史记录 9 | 10 | ### 修复 11 | + 弹幕数量较少 12 | + 弹幕屏蔽设置自动记忆 13 | + 动态页面渲染 14 | + 用户主页数据错乱 15 | + 大家都在搜空白 16 | + 默认自动全屏,顶部操作栏丢失 17 | 18 | 19 | ### 优化 20 | + 全屏状态栏区域显示优化 21 | + 图片保存至PiliPala文件夹 22 | 23 | 更多更新日志可在Github上查看 24 | 问题反馈、功能建议请查看「关于」页面。 25 | -------------------------------------------------------------------------------- /change_log/1.0.9.1015.md: -------------------------------------------------------------------------------- 1 | ## 1.0.9 2 | 3 | 4 | ### 新功能 5 | + 自定义倍速、默认倍速 6 | + 历史记录搜索 7 | + 收藏夹搜索 8 | + 历史记录多选删除 9 | + 视频循环播放 10 | + 免登录看1080P 11 | + 评论区视频链接跳转 12 | + up主分组 13 | + up主投稿搜索 14 | 15 | ### 修复 16 | + 搜索视频标题乱码 17 | + 屏幕帧率 18 | + 动态页面渲染 19 | 20 | 21 | 22 | ### 优化 23 | + 快进手势 24 | + 视频简介链接匹配 25 | + 视频全屏时安全区域 26 | 27 | 更多更新日志可在Github上查看 28 | 问题反馈、功能建议请查看「关于」页面。 29 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/full_description.txt: -------------------------------------------------------------------------------- 1 | PiliPalaX is a third-party Bilibili client developed in Flutter, 2 | fork from PiliPala (https://github.com/guozhigq/pilipala). 3 | 4 | Top Features: 5 | 6 | * List of recommended videos 7 | * List of hottest videos 8 | * Popular live streams 9 | * List of bangumis 10 | * Block videos from blacklisted users 11 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/featureGraphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/fastlane/metadata/android/en-US/images/featureGraphic.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/fastlane/metadata/android/en-US/images/icon.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/short_description.txt: -------------------------------------------------------------------------------- 1 | A third-party Bilibili client developed in Flutter 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/title.txt: -------------------------------------------------------------------------------- 1 | PiliPalaX 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/zh-CN/full_description.txt: -------------------------------------------------------------------------------- 1 | PiliPalaX 是使用 Flutter 开发的 BiliBili 第三方客户端, 2 | 是由PiliPala仓库fork并进行了差异化开发的版本 3 | 4 | 主要功能: 5 | 6 | * 推荐视频列表 7 | * 最热视频列表 8 | * 热门直播 9 | * 番剧列表 10 | * 屏蔽黑名单内用户视频 11 | -------------------------------------------------------------------------------- /fastlane/metadata/android/zh-CN/images/featureGraphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/fastlane/metadata/android/zh-CN/images/featureGraphic.png -------------------------------------------------------------------------------- /fastlane/metadata/android/zh-CN/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/fastlane/metadata/android/zh-CN/images/icon.png -------------------------------------------------------------------------------- /fastlane/metadata/android/zh-CN/images/phoneScreenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/1.png -------------------------------------------------------------------------------- /fastlane/metadata/android/zh-CN/images/phoneScreenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/2.png -------------------------------------------------------------------------------- /fastlane/metadata/android/zh-CN/images/phoneScreenshots/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/3.png -------------------------------------------------------------------------------- /fastlane/metadata/android/zh-CN/short_description.txt: -------------------------------------------------------------------------------- 1 | 使用 Flutter 开发的 BiliBili 第三方客户端 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/zh-CN/title.txt: -------------------------------------------------------------------------------- 1 | PiliPalaX 2 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import fl_pip 2 | import UIKit 3 | import Flutter 4 | 5 | @main 6 | @objc class AppDelegate: FlFlutterAppDelegate { 7 | override func application( 8 | _ application: UIApplication, 9 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 10 | ) -> Bool { 11 | GeneratedPluginRegistrant.register(with: self) 12 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 13 | } 14 | 15 | override func registerPlugin(_ registry: FlutterPluginRegistry) { 16 | GeneratedPluginRegistrant.register(with: registry) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "background.png", 5 | "idiom" : "universal" 6 | }, 7 | { 8 | "appearances" : [ 9 | { 10 | "appearance" : "luminosity", 11 | "value" : "dark" 12 | } 13 | ], 14 | "filename" : "darkbackground.png", 15 | "idiom" : "universal" 16 | } 17 | ], 18 | "info" : { 19 | "author" : "xcode", 20 | "version" : 1 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "LaunchImage.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "filename" : "LaunchImageDark.png", 16 | "idiom" : "universal", 17 | "scale" : "1x" 18 | }, 19 | { 20 | "filename" : "LaunchImage@2x.png", 21 | "idiom" : "universal", 22 | "scale" : "2x" 23 | }, 24 | { 25 | "appearances" : [ 26 | { 27 | "appearance" : "luminosity", 28 | "value" : "dark" 29 | } 30 | ], 31 | "filename" : "LaunchImageDark@2x.png", 32 | "idiom" : "universal", 33 | "scale" : "2x" 34 | }, 35 | { 36 | "filename" : "LaunchImage@3x.png", 37 | "idiom" : "universal", 38 | "scale" : "3x" 39 | }, 40 | { 41 | "appearances" : [ 42 | { 43 | "appearance" : "luminosity", 44 | "value" : "dark" 45 | } 46 | ], 47 | "filename" : "LaunchImageDark@3x.png", 48 | "idiom" : "universal", 49 | "scale" : "3x" 50 | } 51 | ], 52 | "info" : { 53 | "author" : "xcode", 54 | "version" : 1 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /lib/common/widgets/appbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class AppBarWidget extends StatelessWidget implements PreferredSizeWidget { 4 | const AppBarWidget({ 5 | required this.child, 6 | required this.controller, 7 | required this.visible, 8 | super.key, 9 | }); 10 | 11 | final PreferredSizeWidget child; 12 | final AnimationController controller; 13 | final bool visible; 14 | 15 | @override 16 | Size get preferredSize => child.preferredSize; 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | visible ? controller.reverse() : controller.forward(); 21 | return SlideTransition( 22 | position: Tween( 23 | begin: Offset.zero, 24 | end: const Offset(0, -1), 25 | ).animate(CurvedAnimation( 26 | parent: controller, 27 | curve: Curves.easeInOutBack, 28 | )), 29 | child: child, 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/common/widgets/content_container.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ContentContainer extends StatelessWidget { 4 | final Widget? contentWidget; 5 | final Widget? bottomWidget; 6 | final bool isScrollable; 7 | final Clip? childClipBehavior; 8 | 9 | const ContentContainer( 10 | {super.key, 11 | this.contentWidget, 12 | this.bottomWidget, 13 | this.isScrollable = true, 14 | this.childClipBehavior}); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return LayoutBuilder( 19 | builder: (BuildContext context, BoxConstraints constraints) { 20 | return SingleChildScrollView( 21 | clipBehavior: childClipBehavior ?? Clip.hardEdge, 22 | physics: isScrollable ? null : const NeverScrollableScrollPhysics(), 23 | child: ConstrainedBox( 24 | constraints: constraints.copyWith( 25 | minHeight: constraints.maxHeight, 26 | maxHeight: double.infinity, 27 | ), 28 | child: IntrinsicHeight( 29 | child: Column( 30 | children: [ 31 | if (contentWidget != null) 32 | Expanded( 33 | child: contentWidget!, 34 | ) 35 | else 36 | const Spacer(), 37 | if (bottomWidget != null) bottomWidget!, 38 | ], 39 | ), 40 | ), 41 | ), 42 | ); 43 | }, 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/common/widgets/custom_toast.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:hive/hive.dart'; 3 | import 'package:PiliPalaX/utils/storage.dart'; 4 | 5 | Box setting = GStorage.setting; 6 | 7 | class CustomToast extends StatelessWidget { 8 | const CustomToast({super.key, required this.msg}); 9 | 10 | final String msg; 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | final double toastOpacity = 15 | setting.get(SettingBoxKey.defaultToastOp, defaultValue: 1.0).toDouble(); 16 | return Container( 17 | margin: 18 | EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom + 30), 19 | padding: const EdgeInsets.symmetric(horizontal: 17, vertical: 10), 20 | decoration: BoxDecoration( 21 | color: Theme.of(context) 22 | .colorScheme 23 | .primaryContainer 24 | .withOpacity(toastOpacity), 25 | borderRadius: BorderRadius.circular(20), 26 | ), 27 | child: Text( 28 | msg, 29 | style: TextStyle( 30 | fontSize: 13, 31 | color: Theme.of(context).colorScheme.primary, 32 | ), 33 | ), 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/common/widgets/http_error.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_svg/flutter_svg.dart'; 3 | 4 | class HttpError extends StatelessWidget { 5 | const HttpError( 6 | {required this.errMsg, required this.fn, this.btnText, super.key}); 7 | 8 | final String? errMsg; 9 | final Function()? fn; 10 | final String? btnText; 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return SliverToBoxAdapter( 15 | child: SizedBox( 16 | height: 400, 17 | child: Column( 18 | crossAxisAlignment: CrossAxisAlignment.center, 19 | mainAxisAlignment: MainAxisAlignment.center, 20 | children: [ 21 | SvgPicture.asset( 22 | "assets/images/error.svg", 23 | height: 200, 24 | ), 25 | const SizedBox(height: 30), 26 | Text( 27 | errMsg ?? '请求异常', 28 | textAlign: TextAlign.center, 29 | style: Theme.of(context).textTheme.titleSmall, 30 | ), 31 | const SizedBox(height: 20), 32 | FilledButton.tonal( 33 | onPressed: () { 34 | fn!(); 35 | }, 36 | style: ButtonStyle( 37 | backgroundColor: WidgetStateProperty.resolveWith((states) { 38 | return Theme.of(context).colorScheme.primary.withAlpha(20); 39 | }), 40 | ), 41 | child: Text( 42 | btnText ?? '点击重试', 43 | style: TextStyle(color: Theme.of(context).colorScheme.primary), 44 | ), 45 | ), 46 | ], 47 | ), 48 | ), 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/common/widgets/my_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:PiliPalaX/common/constants.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_html/flutter_html.dart'; 4 | 5 | class MyDialog { 6 | static Future show(BuildContext context, Widget child) { 7 | return showDialog( 8 | barrierDismissible: true, 9 | context: context, 10 | builder: (BuildContext context) => Dialog( 11 | insetPadding: const EdgeInsets.all(0), 12 | child: Material( 13 | clipBehavior: Clip.hardEdge, 14 | borderRadius: StyleString.mdRadius, 15 | child: child, 16 | )), 17 | ); 18 | } 19 | 20 | static Future showCorner(BuildContext context, Widget child) { 21 | return showDialog( 22 | barrierDismissible: true, 23 | context: context, 24 | builder: (BuildContext context) => Align( 25 | alignment: MediaQuery.of(context).orientation == Orientation.portrait 26 | ? Alignment.bottomRight 27 | : Alignment.topRight, 28 | child: Padding( 29 | padding: const EdgeInsets.all(8.0), // 设置外边距 30 | child: Material( 31 | clipBehavior: Clip.hardEdge, 32 | borderRadius: StyleString.mdRadius, 33 | child: child, 34 | )), 35 | ), 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/common/widgets/no_data.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_svg/flutter_svg.dart'; 3 | 4 | class NoData extends StatelessWidget { 5 | const NoData({super.key}); 6 | 7 | @override 8 | Widget build(BuildContext context) { 9 | return SliverToBoxAdapter( 10 | child: SizedBox( 11 | height: 400, 12 | child: Column( 13 | crossAxisAlignment: CrossAxisAlignment.center, 14 | mainAxisAlignment: MainAxisAlignment.center, 15 | children: [ 16 | SvgPicture.asset( 17 | "assets/images/error.svg", 18 | height: 200, 19 | ), 20 | const SizedBox(height: 20), 21 | Text( 22 | '没有数据', 23 | textAlign: TextAlign.center, 24 | style: Theme.of(context).textTheme.titleSmall, 25 | ), 26 | ], 27 | ), 28 | ), 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/common/widgets/sliver_header.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class SliverHeaderDelegate extends SliverPersistentHeaderDelegate { 4 | SliverHeaderDelegate({required this.height, required this.child}); 5 | 6 | final double height; 7 | final Widget child; 8 | 9 | @override 10 | Widget build( 11 | BuildContext context, double shrinkOffset, bool overlapsContent) { 12 | return child; 13 | } 14 | 15 | @override 16 | double get maxExtent => height; 17 | 18 | @override 19 | double get minExtent => height; 20 | 21 | @override 22 | bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) => 23 | true; 24 | } 25 | -------------------------------------------------------------------------------- /lib/common/widgets/spring_physics.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | 3 | class CustomTabBarViewScrollPhysics extends ScrollPhysics { 4 | const CustomTabBarViewScrollPhysics({super.parent}); 5 | 6 | @override 7 | CustomTabBarViewScrollPhysics applyTo(ScrollPhysics? ancestor) { 8 | return CustomTabBarViewScrollPhysics(parent: buildParent(ancestor)!); 9 | } 10 | 11 | @override 12 | SpringDescription get spring => const SpringDescription( 13 | mass: 40, 14 | stiffness: 10, 15 | damping: 1, 16 | ); 17 | } -------------------------------------------------------------------------------- /lib/common/widgets/stat/danmu.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:PiliPalaX/utils/utils.dart'; 3 | 4 | class StatDanMu extends StatelessWidget { 5 | final String? theme; 6 | final dynamic danmu; 7 | final String? size; 8 | 9 | const StatDanMu({super.key, this.theme, this.danmu, this.size}); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | Map colorObject = { 14 | 'white': Colors.white, 15 | 'gray': Theme.of(context).colorScheme.outline.withOpacity(0.8), 16 | 'black': Theme.of(context).colorScheme.onSurface.withOpacity(0.7), 17 | }; 18 | Color color = colorObject[theme]!; 19 | return Row( 20 | children: [ 21 | Icon( 22 | Icons.subtitles_outlined, 23 | size: 14, 24 | color: color, 25 | ), 26 | const SizedBox(width: 2), 27 | Text( 28 | Utils.numFormat(danmu!), 29 | style: TextStyle( 30 | fontSize: size == 'medium' ? 12 : 11, 31 | color: color, 32 | ), 33 | overflow: TextOverflow.clip, 34 | semanticsLabel: '${Utils.numFormat(danmu!)}条弹幕', 35 | ) 36 | ], 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/common/widgets/stat/view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:PiliPalaX/utils/utils.dart'; 3 | 4 | class StatView extends StatelessWidget { 5 | final String? theme; 6 | final dynamic view; 7 | final String? size; 8 | final String? goto; 9 | 10 | const StatView({super.key, this.theme, this.view, this.size, this.goto}); 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | Map colorObject = { 15 | 'white': Colors.white, 16 | 'gray': Theme.of(context).colorScheme.outline.withOpacity(0.8), 17 | 'black': Theme.of(context).colorScheme.onSurface.withOpacity(0.7), 18 | }; 19 | Color color = colorObject[theme]!; 20 | return Row( 21 | children: [ 22 | Icon( 23 | goto == 'picture' 24 | ? Icons.remove_red_eye_outlined 25 | : Icons.play_circle_outlined, 26 | size: 13, 27 | color: color, 28 | ), 29 | const SizedBox(width: 2), 30 | Text( 31 | Utils.numFormat(view!), 32 | style: TextStyle( 33 | fontSize: size == 'medium' ? 12 : 11, 34 | color: color, 35 | ), 36 | overflow: TextOverflow.clip, 37 | semanticsLabel: 38 | '${Utils.numFormat(view!)}次${goto == "picture" ? "浏览" : "播放"}', 39 | ), 40 | ], 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/http/bangumi.dart: -------------------------------------------------------------------------------- 1 | import '../models/bangumi/list.dart'; 2 | import 'index.dart'; 3 | 4 | class BangumiHttp { 5 | static Future bangumiList({int? page}) async { 6 | var res = await Request().get(Api.bangumiList, data: {'page': page}); 7 | if (res.data['code'] == 0) { 8 | return { 9 | 'status': true, 10 | 'data': BangumiListDataModel.fromJson(res.data['data']) 11 | }; 12 | } else { 13 | return { 14 | 'status': false, 15 | 'data': [], 16 | 'msg': res.data['message'], 17 | }; 18 | } 19 | } 20 | 21 | static Future bangumiFollow({int? mid}) async { 22 | var res = await Request().get(Api.bangumiFollow, data: {'vmid': mid}); 23 | if (res.data['code'] == 0) { 24 | return { 25 | 'status': true, 26 | 'data': BangumiListDataModel.fromJson(res.data['data']) 27 | }; 28 | } else { 29 | return { 30 | 'status': false, 31 | 'data': [], 32 | 'msg': res.data['message'], 33 | }; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/http/black.dart: -------------------------------------------------------------------------------- 1 | import '../models/user/black.dart'; 2 | import 'index.dart'; 3 | 4 | class BlackHttp { 5 | static Future blackList({required int pn, int? ps}) async { 6 | var res = await Request().get(Api.blackLst, data: { 7 | 'pn': pn, 8 | 'ps': ps ?? 50, 9 | 're_version': 0, 10 | 'jsonp': 'jsonp', 11 | 'csrf': await Request.getCsrf(), 12 | }); 13 | if (res.data['code'] == 0) { 14 | return { 15 | 'status': true, 16 | 'data': BlackListDataModel.fromJson(res.data['data']) 17 | }; 18 | } else { 19 | return { 20 | 'status': false, 21 | 'data': [], 22 | 'msg': res.data['message'], 23 | }; 24 | } 25 | } 26 | 27 | // 移除黑名单 28 | static Future removeBlack({required int fid}) async { 29 | var res = await Request().post( 30 | Api.removeBlack, 31 | queryParameters: { 32 | 'act': 6, 33 | 'csrf': await Request.getCsrf(), 34 | 'fid': fid, 35 | 'jsonp': 'jsonp', 36 | 're_src': 116, 37 | }, 38 | ); 39 | if (res.data['code'] == 0) { 40 | return { 41 | 'status': true, 42 | 'data': [], 43 | 'msg': '操作成功', 44 | }; 45 | } else { 46 | return { 47 | 'status': false, 48 | 'data': [], 49 | 'msg': res.data['message'], 50 | }; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/http/common.dart: -------------------------------------------------------------------------------- 1 | import 'index.dart'; 2 | 3 | class CommonHttp { 4 | static Future unReadDynamic() async { 5 | var res = await Request().get(Api.getUnreadDynamic, 6 | data: {'alltype_offset': 0, 'video_offset': '', 'article_offset': 0}); 7 | if (res.data['code'] == 0) { 8 | return {'status': true, 'data': res.data['data']['dyn_basic_infos']}; 9 | } else { 10 | return { 11 | 'status': false, 12 | 'data': [], 13 | 'msg': res.data['message'], 14 | }; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/http/constants.dart: -------------------------------------------------------------------------------- 1 | class HttpString { 2 | static const String baseUrl = 'https://www.bilibili.com'; 3 | static const String apiBaseUrl = 'https://api.bilibili.com'; 4 | static const String tUrl = 'https://api.vc.bilibili.com'; 5 | static const String appBaseUrl = 'https://app.bilibili.com'; 6 | static const String liveBaseUrl = 'https://api.live.bilibili.com'; 7 | static const String passBaseUrl = 'https://passport.bilibili.com'; 8 | static const String messageBaseUrl = 'https://message.bilibili.com'; 9 | static const String spaceBaseUrl = 'https://space.bilibili.com'; 10 | static const List validateStatusCodes = [ 11 | 302, 12 | 304, 13 | 307, 14 | 400, 15 | 401, 16 | 403, 17 | 404, 18 | 405, 19 | 409, 20 | 412, 21 | 500, 22 | 503, 23 | 504, 24 | 509, 25 | 616, 26 | 617, 27 | 625, 28 | 626, 29 | 628, 30 | 629, 31 | 632, 32 | 643, 33 | 650, 34 | 652, 35 | 658, 36 | 662, 37 | 688, 38 | 689, 39 | 701, 40 | 799, 41 | 8888 42 | ]; 43 | } 44 | -------------------------------------------------------------------------------- /lib/http/danmaku_block.dart: -------------------------------------------------------------------------------- 1 | import '../models/user/danmaku_block.dart'; 2 | import 'index.dart'; 3 | 4 | class DanmakuFilterHttp { 5 | static Future danmakuFilter() async { 6 | var res = await Request().get(Api.danmakuFilter); 7 | if (res.data['code'] == 0) { 8 | return { 9 | 'status': true, 10 | 'data': DanmakuBlockDataModel.fromJson(res.data['data']) 11 | }; 12 | } else { 13 | return { 14 | 'status': false, 15 | 'data': [], 16 | 'msg': res.data['message'], 17 | }; 18 | } 19 | } 20 | 21 | static Future danmakuFilterDel({required int ids}) async { 22 | var res = await Request().post( 23 | Api.danmakuFilterDel, 24 | queryParameters: { 25 | 'ids': ids, 26 | 'csrf': await Request.getCsrf(), 27 | }, 28 | ); 29 | if (res.data['code'] == 0) { 30 | return { 31 | 'status': true, 32 | 'msg': '操作成功', 33 | }; 34 | } else { 35 | return { 36 | 'status': false, 37 | 'msg': res.data['message'], 38 | }; 39 | } 40 | } 41 | 42 | static Future danmakuFilterAdd({required String filter, required int type}) async { 43 | var res = await Request().post( 44 | Api.danmakuFilterAdd, 45 | queryParameters: { 46 | 'type': type, 47 | 'filter': filter, 48 | 'csrf': await Request.getCsrf(), 49 | }, 50 | ); 51 | if (res.data['code'] == 0) { 52 | return { 53 | 'status': true, 54 | 'data': Rule.fromJson(res.data['data']), 55 | }; 56 | } else { 57 | return { 58 | 'status': false, 59 | 'msg': res.data['message'], 60 | }; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/http/fan.dart: -------------------------------------------------------------------------------- 1 | import '../models/fans/result.dart'; 2 | import 'index.dart'; 3 | 4 | class FanHttp { 5 | static Future fans({int? vmid, int? pn, int? ps, String? orderType}) async { 6 | var res = await Request().get(Api.fans, data: { 7 | 'vmid': vmid, 8 | 'pn': pn, 9 | 'ps': ps, 10 | 'order': 'desc', 11 | 'order_type': orderType, 12 | }); 13 | if (res.data['code'] == 0) { 14 | return {'status': true, 'data': FansDataModel.fromJson(res.data['data'])}; 15 | } else { 16 | return { 17 | 'status': false, 18 | 'data': [], 19 | 'msg': res.data['message'], 20 | }; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/http/follow.dart: -------------------------------------------------------------------------------- 1 | import '../models/follow/result.dart'; 2 | import 'index.dart'; 3 | 4 | class FollowHttp { 5 | static Future followings( 6 | {int? vmid, int? pn, int? ps, String? orderType}) async { 7 | var res = await Request().get(Api.followings, data: { 8 | 'vmid': vmid, 9 | 'pn': pn, 10 | 'ps': ps, 11 | 'order': 'desc', 12 | 'order_type': orderType, 13 | }); 14 | if (res.data['code'] == 0) { 15 | return { 16 | 'status': true, 17 | 'data': FollowDataModel.fromJson(res.data['data']) 18 | }; 19 | } else { 20 | return { 21 | 'status': false, 22 | 'data': [], 23 | 'msg': res.data['message'], 24 | }; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/http/index.dart: -------------------------------------------------------------------------------- 1 | export 'api.dart'; 2 | export 'init.dart'; 3 | -------------------------------------------------------------------------------- /lib/http/interceptor_anonymity.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: avoid_print 2 | 3 | import 'dart:io'; 4 | import 'package:dio/dio.dart'; 5 | // import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; 6 | import '../pages/mine/controller.dart'; 7 | import 'api.dart'; 8 | 9 | class AnonymityInterceptor extends Interceptor { 10 | static const List anonymityList = [ 11 | Api.videoUrl, 12 | Api.videoIntro, 13 | Api.relatedList, 14 | Api.replyList, 15 | Api.replyReplyList, 16 | Api.searchSuggest, 17 | Api.searchByType, 18 | Api.heartBeat, 19 | Api.ab2c, 20 | Api.bangumiInfo, 21 | Api.liveRoomInfo, 22 | Api.onlineTotal, 23 | Api.webDanmaku, 24 | Api.dynamicDetail, 25 | Api.aiConclusion, 26 | Api.getSeasonDetailApi, 27 | ]; 28 | 29 | 30 | @override 31 | void onRequest(RequestOptions options, RequestInterceptorHandler handler) { 32 | if (MineController.anonymity) { 33 | String uri = options.uri.toString(); 34 | for (var i in anonymityList) { 35 | // 如果请求的url包含无痕列表中的url,则清空cookie 36 | // 但需要保证匹配到url的后半部分不再出现/符号,否则会误伤 37 | int index = uri.indexOf(i); 38 | if (index == -1) continue; 39 | if (uri.lastIndexOf('/') >= index + i.length) continue; 40 | //SmartDialog.showToast('触发无痕模式\n\n$i\n\n${options.uri}'); 41 | options.headers[HttpHeaders.cookieHeader] = ""; 42 | if (options.data != null && options.data.csrf != null) { 43 | options.data.csrf = ""; 44 | } 45 | break; 46 | } 47 | } 48 | handler.next(options); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/models/common/business_type.dart: -------------------------------------------------------------------------------- 1 | enum BusinessType { 2 | // 普通视频 3 | archive, 4 | // 剧集(番剧 / 影视) 5 | pgc, 6 | // 直播 7 | live, 8 | // 文章 9 | articleList, 10 | // 文章 11 | article, 12 | hiddenDurationType, 13 | showBadge 14 | } 15 | 16 | extension BusinessTypeExtension on BusinessType { 17 | String get type => 18 | ['archive', 'pgc', 'live', 'article-list', 'article'][index]; 19 | // 隐藏时长 20 | List get hiddenDurationType => ['live', 'article-list', 'article']; 21 | // 右上 22 | List get showBadge => ['pgc', 'article-list', 'article']; 23 | } 24 | -------------------------------------------------------------------------------- /lib/models/common/color_type.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | final List> colorThemeTypes = [ 4 | {'color': Colors.lime, 'label': '鲜绿'}, 5 | {'color': Colors.lightGreen, 'label': '浅绿'}, 6 | {'color': const Color(0xFF91AE84), 'label': '豆绿'}, 7 | {'color': Colors.green, 'label': '松绿'}, 8 | {'color': Colors.teal, 'label': '湖绿'}, 9 | {'color': Colors.blueGrey[400], 'label': '灰蓝'}, 10 | {'color': Colors.cyan, 'label': '青蓝'}, 11 | {'color': Colors.lightBlue, 'label': '天蓝'}, 12 | {'color': Colors.blue, 'label': '亮蓝'}, 13 | {'color': const Color(0xFF191970), 'label': '深蓝'}, 14 | {'color': Colors.indigo, 'label': '靛蓝'}, 15 | {'color': Colors.deepPurple, 'label': '深紫'}, 16 | {'color': Colors.purple, 'label': '魏紫'}, 17 | {'color': const Color(0xFF8C4356), 'label': '绛紫'}, 18 | {'color': const Color(0xFFB5001D), 'label': '大红'}, 19 | {'color': Colors.pink, 'label': '枚红'}, 20 | {'color': const Color(0xFFED5736), 'label': '妃红'}, 21 | {'color': const Color(0xFFFB7299), 'label': '粉红'}, 22 | {'color': Colors.red, 'label': '桃红'}, 23 | {'color': Colors.deepOrange, 'label': '橙红'}, 24 | {'color': const Color(0xFF993300), 'label': '棕红'}, 25 | {'color': Colors.brown, 'label': '棕褐'}, 26 | {'color': Colors.orange, 'label': '鲜橙'}, 27 | {'color': Colors.amber, 'label': '橙黄'}, 28 | {'color': Colors.yellow, 'label': '明黄'}, 29 | ]; 30 | -------------------------------------------------------------------------------- /lib/models/common/dynamic_badge_mode.dart: -------------------------------------------------------------------------------- 1 | enum DynamicBadgeMode { hidden, point, number } 2 | 3 | extension DynamicBadgeModeDesc on DynamicBadgeMode { 4 | String get description => ['隐藏', '红点', '数字'][index]; 5 | } 6 | 7 | extension DynamicBadgeModeCode on DynamicBadgeMode { 8 | int get code => [0, 1, 2][index]; 9 | } 10 | -------------------------------------------------------------------------------- /lib/models/common/dynamics_type.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | import '../../pages/dynamics/tab/controller.dart'; 3 | import '../../pages/dynamics/tab/view.dart'; 4 | 5 | enum DynamicsType { 6 | all, 7 | video, 8 | pgc, 9 | article, 10 | up, 11 | } 12 | 13 | extension BusinessTypeExtension on DynamicsType { 14 | String get values => ['all', 'video', 'pgc', 'article', 'up'][index]; 15 | String get labels => ['全部', '投稿', '番剧', '专栏', 'Up'][index]; 16 | } 17 | 18 | List tabsConfig = [ 19 | { 20 | 'value': DynamicsType.all, 21 | 'label': '全部', 22 | 'enabled': true, 23 | 'ctr': Get.put(DynamicsTabController(), tag: 'all'), 24 | 'page': const DynamicsTabPage(dynamicsType: 'all'), 25 | }, 26 | { 27 | 'value': DynamicsType.video, 28 | 'label': '投稿', 29 | 'enabled': true, 30 | 'ctr': 31 | Get.put(DynamicsTabController(), tag: 'video'), 32 | 'page': const DynamicsTabPage(dynamicsType: 'video'), 33 | }, 34 | { 35 | 'value': DynamicsType.pgc, 36 | 'label': '番剧', 37 | 'enabled': true, 38 | 'ctr': Get.put(DynamicsTabController(), tag: 'pgc'), 39 | 'page': const DynamicsTabPage(dynamicsType: 'pgc'), 40 | }, 41 | { 42 | 'value': DynamicsType.article, 43 | 'label': '专栏', 44 | 'enabled': true, 45 | 'ctr': 46 | Get.put(DynamicsTabController(), tag: 'article'), 47 | 'page': const DynamicsTabPage(dynamicsType: 'article'), 48 | }, 49 | { 50 | 'value': DynamicsType.up, 51 | 'label': 'Up', 52 | 'enabled': true, 53 | 'ctr': Get.put(DynamicsTabController(), tag: 'up'), 54 | 'page': const DynamicsTabPage(dynamicsType: 'up'), 55 | }, 56 | ]; 57 | -------------------------------------------------------------------------------- /lib/models/common/nav_bar_config.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | List defaultNavigationBars = [ 4 | { 5 | 'id': 0, 6 | 'icon': const Icon( 7 | Icons.home_outlined, 8 | size: 23, 9 | ), 10 | 'selectIcon': const Icon( 11 | Icons.home, 12 | size: 23, 13 | ), 14 | 'label': "首页", 15 | 'count': 0, 16 | }, 17 | { 18 | 'id': 1, 19 | 'icon': const Icon( 20 | Icons.motion_photos_on_outlined, 21 | size: 21, 22 | ), 23 | 'selectIcon': const Icon( 24 | Icons.motion_photos_on, 25 | size: 21, 26 | ), 27 | 'label': "动态", 28 | 'count': 0, 29 | }, 30 | { 31 | 'id': 2, 32 | 'icon': const Icon( 33 | Icons.video_collection_outlined, 34 | size: 21, 35 | ), 36 | 'selectIcon': const Icon( 37 | Icons.video_collection, 38 | size: 21, 39 | ), 40 | 'label': "媒体库", 41 | 'count': 0, 42 | } 43 | ]; 44 | -------------------------------------------------------------------------------- /lib/models/common/rcmd_type.dart: -------------------------------------------------------------------------------- 1 | // 首页推荐类型 2 | enum RcmdType { web, app, notLogin } 3 | 4 | extension RcmdTypeExtension on RcmdType { 5 | String get values => ['web', 'app', 'notLogin'][index]; 6 | String get labels => ['web端', 'app端', '游客模式'][index]; 7 | } 8 | -------------------------------------------------------------------------------- /lib/models/common/reply_sort_type.dart: -------------------------------------------------------------------------------- 1 | enum ReplySortType { time, like } 2 | 3 | extension ReplySortTypeExtension on ReplySortType { 4 | String get titles => ['最新评论', '最热评论'][index]; 5 | String get labels => ['最新', '最热'][index]; 6 | } 7 | -------------------------------------------------------------------------------- /lib/models/common/reply_type.dart: -------------------------------------------------------------------------------- 1 | enum ReplyType { 2 | unset, 3 | // 视频 4 | video, 5 | // 话题 6 | topic, 7 | // 8 | unset2, 9 | // 活动 10 | activity, 11 | // 小视频 12 | videoS, 13 | // 小黑屋封禁信息 14 | blockMsg, 15 | // 公告信息 16 | publicMsg, 17 | // 直播活动 18 | liveActivity, 19 | // 活动稿件 20 | activityFile, 21 | // 直播公告 22 | livePublic, 23 | // 相簿 24 | album, 25 | // 专栏 26 | column, 27 | // 票务 28 | ticket, 29 | // 音频 30 | audio, 31 | // 风纪委员会 32 | unset3, 33 | // 点评 34 | comment, 35 | // 动态 36 | dynamics, 37 | // 播单 38 | playList, 39 | // 音乐播单 40 | musicPlayList, 41 | // 漫画 42 | comics1, 43 | // 漫画 44 | comics2, 45 | // 漫画 46 | comics3, 47 | // 课程 48 | course, 49 | } 50 | -------------------------------------------------------------------------------- /lib/models/common/search_type.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: constant_identifier_names 2 | enum SearchType { 3 | // 视频:video 4 | video, 5 | // 番剧:media_bangumi, 6 | media_bangumi, 7 | // 影视:media_ft 8 | // media_ft, 9 | // 直播间及主播:live 10 | // live, 11 | // 直播间:live_room 12 | live_room, 13 | // 主播:live_user 14 | // live_user, 15 | // 话题:topic 16 | // topic, 17 | // 用户:bili_user 18 | bili_user, 19 | // 专栏:article 20 | article, 21 | // 相簿:photo 22 | // photo 23 | } 24 | 25 | extension SearchTypeExtension on SearchType { 26 | String get type => 27 | ['video', 'media_bangumi', 'live_room', 'bili_user', 'article'][index]; 28 | String get label => ['视频', '番剧', '直播间', '用户', '专栏'][index]; 29 | } 30 | 31 | // 搜索类型为视频、专栏及相簿时 32 | enum ArchiveFilterType { 33 | totalrank, 34 | click, 35 | pubdate, 36 | dm, 37 | stow, 38 | scores, 39 | // 专栏 40 | // attention, 41 | } 42 | 43 | extension ArchiveFilterTypeExtension on ArchiveFilterType { 44 | String get description => 45 | ['默认排序', '播放多', '新发布', '弹幕多', '收藏多', '评论多', '最多喜欢'][index]; 46 | } 47 | -------------------------------------------------------------------------------- /lib/models/common/side_bar_position.dart: -------------------------------------------------------------------------------- 1 | enum SideBarPosition { 2 | none, 3 | leftFixed, 4 | rightFixed, 5 | leftHorizontal, 6 | rightHorizontal 7 | } 8 | 9 | extension SideBarPositionDesc on SideBarPosition { 10 | String get values => [ 11 | 'none', 12 | 'left_fixed', 13 | 'right_fixed', 14 | 'left_horizontal', 15 | 'right_horizontal' 16 | ][index]; 17 | String get labels => ['不使用侧栏', '左侧常驻', '右侧常驻', '左侧(仅横屏)', '右侧(仅横屏)'][index]; 18 | } 19 | 20 | extension SideBarPositionCode on SideBarPosition { 21 | int get code => index; 22 | static SideBarPosition? fromCode(int code) { 23 | if (code >= 0 && code < SideBarPosition.values.length) { 24 | return SideBarPosition.values[code]; 25 | } 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/models/common/theme_type.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | enum ThemeType { 4 | light, 5 | dark, 6 | system, 7 | } 8 | 9 | extension ThemeTypeDesc on ThemeType { 10 | String get description => ['浅色', '深色', '跟随系统'][index]; 11 | } 12 | 13 | extension ThemeTypeCode on ThemeType { 14 | int get code => [0, 1, 2][index]; 15 | } 16 | 17 | extension ThemeTypeToThemeMode on ThemeType { 18 | ThemeMode get toThemeMode => [ThemeMode.light, ThemeMode.dark, ThemeMode.system][index]; 19 | } 20 | -------------------------------------------------------------------------------- /lib/models/common/up_panel_position.dart: -------------------------------------------------------------------------------- 1 | enum UpPanelPosition { 2 | leftFixed, 3 | rightFixed, 4 | leftDrawer, 5 | rightDrawer, 6 | } 7 | 8 | extension UpPanelPositionDesc on UpPanelPosition { 9 | String get values => ['left_fixed', 'right_fixed', 'left_drawer', 'right_drawer'][index]; 10 | String get labels => ['左侧常驻','右侧常驻','左侧抽屉','右侧抽屉'][index]; 11 | } 12 | 13 | extension UpPanelPositionCode on UpPanelPosition { 14 | int get code => [0, 1, 2, 3][index]; 15 | } 16 | -------------------------------------------------------------------------------- /lib/models/fans/result.dart: -------------------------------------------------------------------------------- 1 | class FansDataModel { 2 | FansDataModel({ 3 | this.total, 4 | this.list, 5 | }); 6 | 7 | int? total; 8 | List? list; 9 | 10 | FansDataModel.fromJson(Map json) { 11 | total = json['total']; 12 | list = json['list'] 13 | .map((e) => FansItemModel.fromJson(e)) 14 | .toList(); 15 | } 16 | } 17 | 18 | class FansItemModel { 19 | FansItemModel({ 20 | this.mid, 21 | this.attribute, 22 | this.mtime, 23 | this.tag, 24 | this.special, 25 | this.uname, 26 | this.face, 27 | this.sign, 28 | this.officialVerify, 29 | }); 30 | 31 | int? mid; 32 | int? attribute; 33 | int? mtime; 34 | List? tag; 35 | int? special; 36 | String? uname; 37 | String? face; 38 | String? sign; 39 | Map? officialVerify; 40 | 41 | FansItemModel.fromJson(Map json) { 42 | mid = json['mid']; 43 | attribute = json['attribute']; 44 | mtime = json['mtime']; 45 | tag = json['tag']; 46 | special = json['special']; 47 | uname = json['uname']; 48 | face = json['face']; 49 | sign = json['sign'] == '' ? '还没有签名' : json['sign']; 50 | officialVerify = json['official_verify']; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/models/follow/result.dart: -------------------------------------------------------------------------------- 1 | class FollowDataModel { 2 | FollowDataModel({ 3 | this.total, 4 | this.list, 5 | }); 6 | 7 | int? total; 8 | List? list; 9 | 10 | FollowDataModel.fromJson(Map json) { 11 | total = json['total'] ?? 0; 12 | list = json['list'] 13 | .map((e) => FollowItemModel.fromJson(e)) 14 | .toList(); 15 | } 16 | } 17 | 18 | class FollowItemModel { 19 | FollowItemModel({ 20 | this.mid, 21 | this.attribute, 22 | // this.mtime, 23 | this.tag, 24 | this.special, 25 | this.uname, 26 | this.face, 27 | this.sign, 28 | this.officialVerify, 29 | }); 30 | 31 | int? mid; 32 | int? attribute; 33 | // int? mtime; 34 | List? tag; 35 | int? special; 36 | String? uname; 37 | String? face; 38 | String? sign; 39 | Map? officialVerify; 40 | 41 | FollowItemModel.fromJson(Map json) { 42 | mid = json['mid']; 43 | attribute = json['attribute']; 44 | // mtime = json['mtime']; 45 | tag = json['tag']; 46 | special = json['special']; 47 | uname = json['uname']; 48 | face = json['face']; 49 | sign = json['sign'] == '' ? '还没有签名' : json['sign']; 50 | officialVerify = json['official_verify']; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/models/github/latest.dart: -------------------------------------------------------------------------------- 1 | class LatestDataModel { 2 | LatestDataModel({ 3 | this.url, 4 | this.tagName, 5 | this.createdAt, 6 | this.assets, 7 | this.body, 8 | }); 9 | 10 | String? url; 11 | String? tagName; 12 | String? createdAt; 13 | List? assets; 14 | String? body; 15 | 16 | LatestDataModel.fromJson(Map json) { 17 | url = json['url']; 18 | tagName = json['tag_name']; 19 | createdAt = json['created_at']; 20 | assets = json['assets'] != null 21 | ? json['assets'].map((e) => AssetItem.fromJson(e)).toList() 22 | : []; 23 | body = json['body']; 24 | } 25 | } 26 | 27 | class AssetItem { 28 | AssetItem({ 29 | this.url, 30 | this.name, 31 | this.size, 32 | this.downloadCount, 33 | this.downloadUrl, 34 | }); 35 | 36 | String? url; 37 | String? name; 38 | int? size; 39 | int? downloadCount; 40 | String? downloadUrl; 41 | 42 | AssetItem.fromJson(Map json) { 43 | url = json['url']; 44 | name = json['name']; 45 | size = json['size']; 46 | downloadCount = json['download_count']; 47 | downloadUrl = json['browser_download_url']; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/models/login/index.dart: -------------------------------------------------------------------------------- 1 | class CaptchaDataModel { 2 | CaptchaDataModel({ 3 | this.type, 4 | this.token, 5 | this.geetest, 6 | this.tencent, 7 | this.validate, 8 | this.seccode, 9 | }); 10 | 11 | String? type; 12 | String? token; 13 | GeetestData? geetest; 14 | Tencent? tencent; 15 | String? validate; 16 | String? seccode; 17 | 18 | CaptchaDataModel.fromJson(Map json) { 19 | type = json["type"]; 20 | token = json["token"]; 21 | geetest = 22 | json["geetest"] != null ? GeetestData.fromJson(json["geetest"]) : null; 23 | tencent = 24 | json["tencent"] != null ? Tencent.fromJson(json["tencent"]) : null; 25 | } 26 | } 27 | 28 | class GeetestData { 29 | GeetestData({ 30 | this.challenge, 31 | this.gt, 32 | }); 33 | 34 | String? challenge; 35 | String? gt; 36 | 37 | GeetestData.fromJson(Map json) { 38 | challenge = json["challenge"]; 39 | gt = json["gt"]; 40 | } 41 | } 42 | 43 | class Tencent { 44 | Tencent({this.appid}); 45 | String? appid; 46 | Tencent.fromJson(Map json) { 47 | appid = json["appid"]; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/models/member/tags.dart: -------------------------------------------------------------------------------- 1 | class MemberTagItemModel { 2 | MemberTagItemModel({ 3 | this.count, 4 | this.name, 5 | this.tagid, 6 | this.tip, 7 | this.checked, 8 | }); 9 | 10 | int? count; 11 | String? name; 12 | int? tagid; 13 | String? tip; 14 | bool? checked; 15 | 16 | MemberTagItemModel.fromJson(Map json) { 17 | count = json['count']; 18 | name = json['name']; 19 | tagid = json['tagid']; 20 | tip = json['tip']; 21 | checked = false; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/models/model_owner.dart: -------------------------------------------------------------------------------- 1 | import 'package:hive/hive.dart'; 2 | 3 | part 'model_owner.g.dart'; 4 | 5 | @HiveType(typeId: 3) 6 | class Owner { 7 | Owner({ 8 | this.mid, 9 | this.name, 10 | this.face, 11 | }); 12 | @HiveField(0) 13 | int? mid; 14 | @HiveField(1) 15 | String? name; 16 | @HiveField(2) 17 | String? face; 18 | 19 | Owner.fromJson(Map json) { 20 | mid = json["mid"]; 21 | name = json["name"]; 22 | face = json['face']; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/models/model_owner.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'model_owner.dart'; 4 | 5 | // ************************************************************************** 6 | // TypeAdapterGenerator 7 | // ************************************************************************** 8 | 9 | class OwnerAdapter extends TypeAdapter { 10 | @override 11 | final int typeId = 3; 12 | 13 | @override 14 | Owner read(BinaryReader reader) { 15 | final numOfFields = reader.readByte(); 16 | final fields = { 17 | for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), 18 | }; 19 | return Owner( 20 | mid: fields[0] as int?, 21 | name: fields[1] as String?, 22 | face: fields[2] as String?, 23 | ); 24 | } 25 | 26 | @override 27 | void write(BinaryWriter writer, Owner obj) { 28 | writer 29 | ..writeByte(3) 30 | ..writeByte(0) 31 | ..write(obj.mid) 32 | ..writeByte(1) 33 | ..write(obj.name) 34 | ..writeByte(2) 35 | ..write(obj.face); 36 | } 37 | 38 | @override 39 | int get hashCode => typeId.hashCode; 40 | 41 | @override 42 | bool operator ==(Object other) => 43 | identical(this, other) || 44 | other is OwnerAdapter && 45 | runtimeType == other.runtimeType && 46 | typeId == other.typeId; 47 | } 48 | -------------------------------------------------------------------------------- /lib/models/msg/msgfeed_unread.dart: -------------------------------------------------------------------------------- 1 | class MsgFeedUnread { 2 | MsgFeedUnread({ 3 | this.at = 0, 4 | this.chat = 0, 5 | this.like = 0, 6 | this.reply = 0, 7 | this.sys_msg = 0, 8 | this.up = 0, 9 | }); 10 | 11 | int at = 0; 12 | int chat = 0; 13 | int like = 0; 14 | int reply = 0; 15 | int sys_msg = 0; 16 | int up = 0; 17 | 18 | MsgFeedUnread.fromJson(Map json) { 19 | at = json['at'] ?? 0; 20 | chat = json['chat'] ?? 0; 21 | like = json['like'] ?? 0; 22 | reply = json['reply'] ?? 0; 23 | sys_msg = json['sys_msg'] ?? 0; 24 | up = json['up'] ?? 0; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/models/search/hot.dart: -------------------------------------------------------------------------------- 1 | import 'package:hive/hive.dart'; 2 | 3 | part 'hot.g.dart'; 4 | 5 | @HiveType(typeId: 6) 6 | class HotSearchModel { 7 | HotSearchModel({ 8 | this.list, 9 | }); 10 | 11 | @HiveField(0) 12 | List? list; 13 | 14 | HotSearchModel.fromJson(Map json) { 15 | list = json['list'] 16 | .map((e) => HotSearchItem.fromJson(e)) 17 | .toList(); 18 | } 19 | } 20 | 21 | @HiveType(typeId: 7) 22 | class HotSearchItem { 23 | HotSearchItem({ 24 | this.keyword, 25 | this.showName, 26 | this.wordType, 27 | this.icon, 28 | }); 29 | 30 | @HiveField(0) 31 | String? keyword; 32 | @HiveField(1) 33 | String? showName; 34 | // 4/5热 11话题 8普通 7直播 35 | @HiveField(2) 36 | int? wordType; 37 | @HiveField(3) 38 | String? icon; 39 | 40 | HotSearchItem.fromJson(Map json) { 41 | keyword = json['keyword']; 42 | showName = json['show_name']; 43 | wordType = json['word_type']; 44 | icon = json['icon']; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/models/user/black.dart: -------------------------------------------------------------------------------- 1 | class BlackListDataModel { 2 | BlackListDataModel({ 3 | this.list, 4 | this.total, 5 | }); 6 | 7 | List? list; 8 | int? total; 9 | 10 | BlackListDataModel.fromJson(Map json) { 11 | list = json['list'] 12 | .map((e) => BlackListItem.fromJson(e)) 13 | .toList(); 14 | total = json['total']; 15 | } 16 | } 17 | 18 | class BlackListItem { 19 | BlackListItem({ 20 | this.face, 21 | this.mid, 22 | this.mtime, 23 | this.uname, 24 | }); 25 | 26 | String? face; 27 | int? mid; 28 | int? mtime; 29 | String? uname; 30 | 31 | BlackListItem.fromJson(Map json) { 32 | face = json['face']; 33 | mid = json['mid']; 34 | mtime = json['mtime']; 35 | uname = json['uname']; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/models/user/stat.dart: -------------------------------------------------------------------------------- 1 | import 'package:hive/hive.dart'; 2 | 3 | part 'stat.g.dart'; 4 | 5 | @HiveType(typeId: 1) 6 | class UserStat { 7 | UserStat({ 8 | this.following, 9 | this.follower, 10 | this.dynamicCount, 11 | }); 12 | 13 | @HiveField(0) 14 | int? following; 15 | @HiveField(1) 16 | int? follower; 17 | @HiveField(2) 18 | int? dynamicCount; 19 | 20 | UserStat.fromJson(Map json) { 21 | following = json['following']; 22 | follower = json['follower']; 23 | dynamicCount = json['dynamic_count']; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/models/user/stat.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'stat.dart'; 4 | 5 | // ************************************************************************** 6 | // TypeAdapterGenerator 7 | // ************************************************************************** 8 | 9 | class UserStatAdapter extends TypeAdapter { 10 | @override 11 | final int typeId = 1; 12 | 13 | @override 14 | UserStat read(BinaryReader reader) { 15 | final numOfFields = reader.readByte(); 16 | final fields = { 17 | for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), 18 | }; 19 | return UserStat( 20 | following: fields[0] as int?, 21 | follower: fields[1] as int?, 22 | dynamicCount: fields[2] as int?, 23 | ); 24 | } 25 | 26 | @override 27 | void write(BinaryWriter writer, UserStat obj) { 28 | writer 29 | ..writeByte(3) 30 | ..writeByte(0) 31 | ..write(obj.following) 32 | ..writeByte(1) 33 | ..write(obj.follower) 34 | ..writeByte(2) 35 | ..write(obj.dynamicCount); 36 | } 37 | 38 | @override 39 | int get hashCode => typeId.hashCode; 40 | 41 | @override 42 | bool operator ==(Object other) => 43 | identical(this, other) || 44 | other is UserStatAdapter && 45 | runtimeType == other.runtimeType && 46 | typeId == other.typeId; 47 | } 48 | -------------------------------------------------------------------------------- /lib/models/video/play/subtitle.dart: -------------------------------------------------------------------------------- 1 | enum SubtitlePreference { off, on, withoutAi } 2 | 3 | extension SubtitlePreferenceDesc on SubtitlePreference { 4 | static final List _descList = [ 5 | '默认不显示字幕', 6 | '默认显示,优先选择非自动生成(ai)字幕', 7 | '默认仅显示非自动生成(ai)字幕', 8 | ]; 9 | get description => _descList[index]; 10 | } 11 | 12 | extension SubtitlePreferenceCode on SubtitlePreference { 13 | static final List _codeList = ['off', 'on', 'withoutAi']; 14 | get code => _codeList[index]; 15 | 16 | static SubtitlePreference? fromCode(String code) { 17 | final index = _codeList.indexOf(code); 18 | if (index != -1) { 19 | return SubtitlePreference.values[index]; 20 | } 21 | return null; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/models/video/reply/config.dart: -------------------------------------------------------------------------------- 1 | class ReplyConfig { 2 | ReplyConfig({ 3 | this.showtopic, 4 | this.showUpFlag, 5 | this.readOnly, 6 | }); 7 | 8 | int? showtopic; 9 | bool? showUpFlag; 10 | bool? readOnly; 11 | 12 | ReplyConfig.fromJson(Map json) { 13 | showtopic = json['showtopic']; 14 | showUpFlag = json['show_up_flag']; 15 | readOnly = json['read_only']; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/models/video/reply/content.dart: -------------------------------------------------------------------------------- 1 | class ReplyContent { 2 | ReplyContent({ 3 | this.message, 4 | this.atNameToMid, // @的用户的mid null 5 | this.members, // 被@的用户List 如果有的话 [] 6 | this.emote, // 表情包 如果有的话 null 7 | this.jumpUrl, // {} 8 | this.pictures, // {} 9 | this.vote, 10 | this.richText, 11 | this.isText, 12 | this.topicsMeta, 13 | }); 14 | 15 | String? message; 16 | Map? atNameToMid; 17 | List? members; 18 | Map? emote; 19 | Map? jumpUrl; 20 | List? pictures; 21 | Map? vote; 22 | Map? richText; 23 | bool? isText; 24 | Map? topicsMeta; 25 | 26 | ReplyContent.fromJson(Map json) { 27 | message = json['message'] 28 | .replaceAll('>', '>') 29 | .replaceAll('"', '"') 30 | .replaceAll(''', "'"); 31 | atNameToMid = json['at_name_to_mid'] ?? {}; 32 | members = json['members'] != null 33 | ? json['members'] 34 | .map((e) => MemberItemModel.fromJson(e)) 35 | .toList() 36 | : []; 37 | emote = json['emote'] ?? {}; 38 | jumpUrl = json['jump_url'] ?? {}; 39 | pictures = json['pictures'] ?? []; 40 | vote = json['vote'] ?? {}; 41 | richText = json['rich_text'] ?? {}; 42 | // 不包含@ 笔记 图片的时候,文字可折叠 43 | isText = atNameToMid!.isEmpty && vote!.isEmpty && pictures!.isEmpty; 44 | topicsMeta = json['topics_meta'] ?? {}; 45 | } 46 | } 47 | 48 | class MemberItemModel { 49 | MemberItemModel({ 50 | required this.mid, 51 | required this.uname, 52 | }); 53 | 54 | late String mid; 55 | late String uname; 56 | 57 | MemberItemModel.fromJson(Map json) { 58 | mid = json['mid']; 59 | uname = json['uname']; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/models/video/reply/member.dart: -------------------------------------------------------------------------------- 1 | class ReplyMember { 2 | ReplyMember({ 3 | this.mid, 4 | this.uname, 5 | this.sign, 6 | this.avatar, 7 | this.level, 8 | this.pendant, 9 | this.officialVerify, 10 | this.vip, 11 | this.fansDetail, 12 | }); 13 | 14 | String? mid; 15 | String? uname; 16 | String? sign; 17 | String? avatar; 18 | int? level; 19 | Pendant? pendant; 20 | Map? officialVerify; 21 | Map? vip; 22 | Map? fansDetail; 23 | UserSailing? userSailing; 24 | 25 | ReplyMember.fromJson(Map json) { 26 | mid = json['mid']; 27 | uname = json['uname']; 28 | sign = json['sign']; 29 | avatar = json['avatar']; 30 | level = json['level_info']['current_level']; 31 | pendant = Pendant.fromJson(json['pendant']); 32 | officialVerify = json['official_verify']; 33 | vip = json['vip']; 34 | fansDetail = json['fans_detail']; 35 | userSailing = json['user_sailing'] != null 36 | ? UserSailing.fromJson(json['user_sailing']) 37 | : UserSailing(); 38 | } 39 | } 40 | 41 | class Pendant { 42 | Pendant({ 43 | this.pid, 44 | this.name, 45 | this.image, 46 | }); 47 | 48 | int? pid; 49 | String? name; 50 | String? image; 51 | 52 | Pendant.fromJson(Map json) { 53 | pid = json['pid']; 54 | name = json['name']; 55 | image = json['image']; 56 | } 57 | } 58 | 59 | class UserSailing { 60 | UserSailing({this.pendant, this.cardbg}); 61 | 62 | Map? pendant; 63 | Map? cardbg; 64 | 65 | UserSailing.fromJson(Map json) { 66 | pendant = json['pendant']; 67 | cardbg = json['cardbg']; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/models/video/reply/top_replies.dart: -------------------------------------------------------------------------------- 1 | class ReplyTop {} 2 | -------------------------------------------------------------------------------- /lib/models/video/reply/upper.dart: -------------------------------------------------------------------------------- 1 | import 'item.dart'; 2 | 3 | class ReplyUpper { 4 | ReplyUpper({ 5 | this.mid, 6 | this.top, 7 | }); 8 | 9 | int? mid; 10 | ReplyItemModel? top; 11 | 12 | ReplyUpper.fromJson(Map json) { 13 | mid = json['mid']; 14 | top = json['top'] != null 15 | ? ReplyItemModel.fromJson(json['top'], json['mid']) 16 | : null; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/pages/bangumi/index.dart: -------------------------------------------------------------------------------- 1 | library bangumi_panel; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/danmaku/index.dart: -------------------------------------------------------------------------------- 1 | library pldanmaku; 2 | 3 | export './controller.dart'; 4 | export 'view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/dynamics/detail/index.dart: -------------------------------------------------------------------------------- 1 | library dynamic_detail; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/dynamics/index.dart: -------------------------------------------------------------------------------- 1 | library dynamics; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/dynamics/tab/index.dart: -------------------------------------------------------------------------------- 1 | library dynamics.tab; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; -------------------------------------------------------------------------------- /lib/pages/emote/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | 4 | import '../../http/reply.dart'; 5 | import '../../models/video/reply/emote.dart'; 6 | 7 | class EmotePanelController extends GetxController 8 | with GetTickerProviderStateMixin { 9 | late List emotePackage; 10 | late TabController tabController; 11 | 12 | Future getEmote() async { 13 | var res = await ReplyHttp.getEmoteList(business: 'reply'); 14 | if (res['status']) { 15 | emotePackage = res['data'].packages; 16 | tabController = TabController(length: emotePackage.length, vsync: this); 17 | } 18 | return res; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/pages/emote/index.dart: -------------------------------------------------------------------------------- 1 | library emote; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/fan/index.dart: -------------------------------------------------------------------------------- 1 | library fan; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/fan/widgets/fan_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | import 'package:PiliPalaX/common/widgets/network_img_layer.dart'; 4 | import 'package:PiliPalaX/utils/utils.dart'; 5 | 6 | Widget fanItem({item}) { 7 | String heroTag = Utils.makeHeroTag(item!.mid); 8 | return ListTile( 9 | onTap: () => Get.toNamed('/member?mid=${item.mid}', 10 | arguments: {'face': item.face, 'heroTag': heroTag}), 11 | leading: Hero( 12 | tag: heroTag, 13 | child: NetworkImgLayer( 14 | width: 38, 15 | height: 38, 16 | type: 'avatar', 17 | src: item.face, 18 | ), 19 | ), 20 | title: Text(item.uname), 21 | subtitle: Text( 22 | item.sign, 23 | maxLines: 1, 24 | overflow: TextOverflow.ellipsis, 25 | ), 26 | dense: true, 27 | trailing: const SizedBox(width: 6), 28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /lib/pages/fav/index.dart: -------------------------------------------------------------------------------- 1 | library fav; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/fav_detail/index.dart: -------------------------------------------------------------------------------- 1 | library favdetail; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/fav_search/index.dart: -------------------------------------------------------------------------------- 1 | library fav_search; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/follow/index.dart: -------------------------------------------------------------------------------- 1 | library following; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/follow_search/index.dart: -------------------------------------------------------------------------------- 1 | library follow_search; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/history/index.dart: -------------------------------------------------------------------------------- 1 | library history; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/history_search/index.dart: -------------------------------------------------------------------------------- 1 | library history_search; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/home/index.dart: -------------------------------------------------------------------------------- 1 | library home; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/hot/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:PiliPalaX/utils/extension.dart'; 2 | import 'package:get/get.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:PiliPalaX/http/video.dart'; 5 | import 'package:PiliPalaX/models/model_hot_video_item.dart'; 6 | 7 | class HotController extends GetxController { 8 | final ScrollController scrollController = ScrollController(); 9 | final int _count = 20; 10 | int _currentPage = 1; 11 | RxList videoList = [].obs; 12 | bool isLoadingMore = false; 13 | bool flag = false; 14 | 15 | // 获取推荐 16 | Future queryHotFeed(type) async { 17 | if (type != 'onLoad') { 18 | _currentPage = 1; 19 | } 20 | var res = await VideoHttp.hotVideoList( 21 | pn: _currentPage, 22 | ps: _count, 23 | ); 24 | if (res['status']) { 25 | if (type == 'init') { 26 | videoList.value = res['data']; 27 | } else if (type == 'onRefresh') { 28 | // videoList.insertAll(0, res['data']); 29 | videoList.value = res['data']; 30 | } else if (type == 'onLoad') { 31 | videoList.addAll(res['data']); 32 | } 33 | _currentPage += 1; 34 | if (_currentPage == 2) queryHotFeed('onLoad'); 35 | } 36 | isLoadingMore = false; 37 | return res; 38 | } 39 | 40 | // 下拉刷新 41 | Future onRefresh() async { 42 | await queryHotFeed('onRefresh'); 43 | } 44 | 45 | // 上拉加载 46 | Future onLoad() async { 47 | await queryHotFeed('onLoad'); 48 | } 49 | 50 | // 返回顶部 51 | void animateToTop() { 52 | scrollController.animToTop(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /lib/pages/hot/index.dart: -------------------------------------------------------------------------------- 1 | library hot; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/html/index.dart: -------------------------------------------------------------------------------- 1 | library html_render; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/later/index.dart: -------------------------------------------------------------------------------- 1 | library later; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/live/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:PiliPalaX/utils/extension.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:get/get.dart'; 4 | import 'package:hive/hive.dart'; 5 | import 'package:PiliPalaX/http/live.dart'; 6 | import 'package:PiliPalaX/models/live/item.dart'; 7 | import 'package:PiliPalaX/utils/storage.dart'; 8 | 9 | class LiveController extends GetxController { 10 | final ScrollController scrollController = ScrollController(); 11 | int count = 12; 12 | int _currentPage = 1; 13 | RxInt crossAxisCount = 2.obs; 14 | RxList liveList = [].obs; 15 | bool flag = false; 16 | List popupDialog = []; 17 | Box setting = GStorage.setting; 18 | 19 | // 获取推荐 20 | Future queryLiveList(type) async { 21 | // if (type == 'init') { 22 | // _currentPage = 1; 23 | // } 24 | var res = await LiveHttp.liveList( 25 | pn: _currentPage, 26 | ); 27 | if (res['status']) { 28 | if (type == 'init') { 29 | liveList.value = res['data']; 30 | } else if (type == 'onLoad') { 31 | liveList.addAll(res['data']); 32 | } 33 | _currentPage += 1; 34 | } 35 | return res; 36 | } 37 | 38 | // 下拉刷新 39 | Future onRefresh() async { 40 | queryLiveList('init'); 41 | } 42 | 43 | // 上拉加载 44 | Future onLoad() async { 45 | queryLiveList('onLoad'); 46 | } 47 | 48 | // 返回顶部并刷新 49 | void animateToTop() { 50 | scrollController.animToTop(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/pages/live/index.dart: -------------------------------------------------------------------------------- 1 | library live; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/live_room/index.dart: -------------------------------------------------------------------------------- 1 | library liveroom; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/login/index.dart: -------------------------------------------------------------------------------- 1 | library login; 2 | 3 | export './controller.dart'; 4 | export 'view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/main/index.dart: -------------------------------------------------------------------------------- 1 | library main; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/media/index.dart: -------------------------------------------------------------------------------- 1 | library media; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/member/index.dart: -------------------------------------------------------------------------------- 1 | library member; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/member/widgets/conis.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:PiliPalaX/common/constants.dart'; 3 | import 'package:PiliPalaX/models/member/coin.dart'; 4 | import 'package:PiliPalaX/pages/member_coin/widgets/item.dart'; 5 | 6 | class MemberCoinsPanel extends StatelessWidget { 7 | final List? data; 8 | const MemberCoinsPanel({super.key, this.data}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return LayoutBuilder( 13 | builder: (context, boxConstraints) { 14 | return GridView.builder( 15 | gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( 16 | crossAxisCount: 2, // Use a fixed count for GridView 17 | crossAxisSpacing: StyleString.safeSpace, 18 | mainAxisSpacing: StyleString.safeSpace, 19 | childAspectRatio: 0.94, 20 | ), 21 | physics: const NeverScrollableScrollPhysics(), 22 | shrinkWrap: true, 23 | itemCount: data!.length, 24 | itemBuilder: (context, i) { 25 | return MemberCoinsItem(coinItem: data![i]); 26 | }, 27 | ); 28 | }, 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/pages/member_archive/index.dart: -------------------------------------------------------------------------------- 1 | library member_archive; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/member_coin/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | 3 | class MemberCoinController extends GetxController {} 4 | -------------------------------------------------------------------------------- /lib/pages/member_coin/index.dart: -------------------------------------------------------------------------------- 1 | library member_coin; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/member_coin/view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class MemberCoinPage extends StatefulWidget { 4 | const MemberCoinPage({super.key}); 5 | 6 | @override 7 | State createState() => _MemberCoinPageState(); 8 | } 9 | 10 | class _MemberCoinPageState extends State { 11 | @override 12 | Widget build(BuildContext context) { 13 | return Scaffold(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/pages/member_dynamics/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | import 'package:PiliPalaX/http/member.dart'; 3 | import 'package:PiliPalaX/models/dynamics/result.dart'; 4 | 5 | class MemberDynamicsController extends GetxController { 6 | MemberDynamicsController({required this.mid}); 7 | final int mid; 8 | String offset = ''; 9 | int count = 0; 10 | bool hasMore = true; 11 | RxList dynamicsList = [].obs; 12 | 13 | Future getMemberDynamic(type) async { 14 | if (type == 'onRefresh') { 15 | offset = ''; 16 | dynamicsList.clear(); 17 | } 18 | if (offset == '-1') { 19 | return; 20 | } 21 | var res = await MemberHttp.memberDynamic( 22 | offset: offset, 23 | mid: mid, 24 | ); 25 | if (res['status']) { 26 | dynamicsList.addAll(res['data'].items); 27 | offset = res['data'].offset != '' ? res['data'].offset : '-1'; 28 | hasMore = res['data'].hasMore; 29 | } 30 | return res; 31 | } 32 | 33 | // 上拉加载 34 | Future onLoad() async { 35 | await getMemberDynamic('onLoad'); 36 | } 37 | 38 | Future onRefresh() async { 39 | await getMemberDynamic('onRefresh'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/pages/member_dynamics/index.dart: -------------------------------------------------------------------------------- 1 | library member_dynamics; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/member_like/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | 3 | class MemberLikeController extends GetxController {} 4 | -------------------------------------------------------------------------------- /lib/pages/member_like/index.dart: -------------------------------------------------------------------------------- 1 | library member_like; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/member_like/view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class MemberLikePage extends StatefulWidget { 4 | const MemberLikePage({super.key}); 5 | 6 | @override 7 | State createState() => _MemberLikePageState(); 8 | } 9 | 10 | class _MemberLikePageState extends State { 11 | @override 12 | Widget build(BuildContext context) { 13 | return Scaffold(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/pages/member_search/index.dart: -------------------------------------------------------------------------------- 1 | library member_search; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/member_season/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | import 'package:PiliPalaX/http/member.dart'; 4 | import 'package:PiliPalaX/models/member/seasons.dart'; 5 | 6 | class MemberSeasonController extends GetxController { 7 | final ScrollController scrollController = ScrollController(); 8 | late int mid; 9 | late int seasonId; 10 | int pn = 1; 11 | int ps = 30; 12 | int count = 0; 13 | Rx meta = SeasonMeta(name: "Ta的合集", total: 0).obs; 14 | RxList seasonsList = [].obs; 15 | late Map page; 16 | 17 | @override 18 | void onInit() { 19 | super.onInit(); 20 | mid = int.parse(Get.parameters['mid']!); 21 | seasonId = int.parse(Get.parameters['seasonId']!); 22 | } 23 | 24 | // 获取合集详情 25 | Future getSeasonDetail(type) async { 26 | if (type == 'onRefresh') { 27 | pn = 1; 28 | } 29 | var res = await MemberHttp.getSeasonDetail( 30 | mid: mid, 31 | seasonId: seasonId, 32 | pn: pn, 33 | ps: ps, 34 | sortReverse: false, 35 | ); 36 | if (res['status']) { 37 | seasonsList.addAll(res['data'].archives); 38 | page = res['data'].page; 39 | pn += 1; 40 | meta.value = res['data'].meta; 41 | } 42 | return res; 43 | } 44 | 45 | // 上拉加载 46 | Future onLoad() async { 47 | getSeasonDetail('onLoad'); 48 | } 49 | 50 | Future onRefresh() async { 51 | getSeasonDetail('onRefresh'); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/pages/member_season/index.dart: -------------------------------------------------------------------------------- 1 | library member_season; 2 | 3 | export 'controller.dart'; 4 | export 'view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/member_seasons_and_series/index.dart: -------------------------------------------------------------------------------- 1 | library member_seasons_and_series; 2 | 3 | export 'controller.dart'; 4 | export 'view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/member_series/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | import 'package:PiliPalaX/http/member.dart'; 4 | import 'package:PiliPalaX/models/member/seasons.dart'; 5 | 6 | class MemberSeriesController extends GetxController { 7 | final ScrollController scrollController = ScrollController(); 8 | late int mid; 9 | late int seriesId; 10 | int pn = 1; 11 | int ps = 30; 12 | int count = 0; 13 | // Rx meta = SeriesMeta(name: "Ta的视频列表", total: 0).obs; 14 | RxList seriesList = [].obs; 15 | Rx?> page = Rx>({"total": 0}); 16 | 17 | @override 18 | void onInit() { 19 | super.onInit(); 20 | mid = int.parse(Get.parameters['mid']!); 21 | seriesId = int.parse(Get.parameters['seriesId']!); 22 | } 23 | 24 | // 获取视频列表详情 25 | Future getSeriesDetail(type) async { 26 | if (type == 'onRefresh') { 27 | pn = 1; 28 | } 29 | var res = await MemberHttp.getSeriesDetail( 30 | mid: mid, 31 | seriesId: seriesId, 32 | pn: pn, 33 | ps: ps, 34 | sortReverse: false, 35 | ); 36 | if (res['status']) { 37 | seriesList.addAll(res['data'].archives); 38 | page.value = res['data'].page; 39 | pn += 1; 40 | // meta.value = res['data'].meta; 41 | } 42 | return res; 43 | } 44 | 45 | // 上拉加载 46 | Future onLoad() async { 47 | await getSeriesDetail('onLoad'); 48 | } 49 | 50 | Future onRefresh() async { 51 | await getSeriesDetail('onRefresh'); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/pages/member_series/index.dart: -------------------------------------------------------------------------------- 1 | library member_series; 2 | 3 | export 'controller.dart'; 4 | export 'view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/mine/index.dart: -------------------------------------------------------------------------------- 1 | library mine; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/msg_feed_top/at_me/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; 2 | import 'package:get/get.dart'; 3 | import 'package:PiliPalaX/http/msg.dart'; 4 | import 'package:PiliPalaX/models/msg/msgfeed_at_me.dart'; 5 | 6 | class AtMeController extends GetxController { 7 | RxList msgFeedAtMeList = [].obs; 8 | bool isLoading = false; 9 | int cursor = -1; 10 | int cursorTime = -1; 11 | bool isEnd = false; 12 | 13 | Future queryMsgFeedAtMe() async { 14 | if (isLoading) return; 15 | isLoading = true; 16 | var res = await MsgHttp.msgFeedAtMe(cursor: cursor, cursorTime: cursorTime); 17 | isLoading = false; 18 | if (res['status']) { 19 | MsgFeedAtMe data = MsgFeedAtMe.fromJson(res['data']); 20 | isEnd = data.cursor?.isEnd ?? false; 21 | if (cursor == -1) { 22 | msgFeedAtMeList.assignAll(data.items!); 23 | } else { 24 | msgFeedAtMeList.addAll(data.items!); 25 | } 26 | cursor = data.cursor?.id ?? -1; 27 | cursorTime = data.cursor?.time ?? -1; 28 | } else { 29 | SmartDialog.showToast(res['msg']); 30 | } 31 | } 32 | 33 | Future onLoad() async { 34 | if (isEnd) return; 35 | queryMsgFeedAtMe(); 36 | } 37 | 38 | Future onRefresh() async { 39 | cursor = -1; 40 | cursorTime = -1; 41 | queryMsgFeedAtMe(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /lib/pages/msg_feed_top/at_me/index.dart: -------------------------------------------------------------------------------- 1 | library whisper; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/msg_feed_top/like_me/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; 2 | import 'package:get/get.dart'; 3 | import 'package:PiliPalaX/http/msg.dart'; 4 | import '../../../models/msg/msgfeed_like_me.dart'; 5 | 6 | class LikeMeController extends GetxController { 7 | RxList msgFeedLikeMeLatestList = [].obs; 8 | RxList msgFeedLikeMeTotalList = [].obs; 9 | bool isLoading = false; 10 | int cursor = -1; 11 | int cursorTime = -1; 12 | bool isEnd = false; 13 | 14 | Future queryMsgFeedLikeMe() async { 15 | if (isLoading) return; 16 | isLoading = true; 17 | var res = await MsgHttp.msgFeedLikeMe(cursor: cursor, cursorTime: cursorTime); 18 | isLoading = false; 19 | if (res['status']) { 20 | MsgFeedLikeMe data = MsgFeedLikeMe.fromJson(res['data']); 21 | isEnd = data.total?.cursor?.isEnd ?? false; 22 | if (cursor == -1) { 23 | msgFeedLikeMeLatestList.assignAll(data.latest?.items??[]); 24 | msgFeedLikeMeTotalList.assignAll(data.total?.items??[]); 25 | } else { 26 | msgFeedLikeMeLatestList.addAll(data.latest?.items??[]); 27 | msgFeedLikeMeTotalList.addAll(data.total?.items??[]); 28 | } 29 | cursor = data.total?.cursor?.id ?? -1; 30 | cursorTime = data.total?.cursor?.time ?? -1; 31 | } else { 32 | SmartDialog.showToast(res['msg']); 33 | } 34 | } 35 | 36 | Future onLoad() async { 37 | if (isEnd) return; 38 | queryMsgFeedLikeMe(); 39 | } 40 | 41 | Future onRefresh() async { 42 | cursor = -1; 43 | cursorTime = -1; 44 | queryMsgFeedLikeMe(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /lib/pages/msg_feed_top/like_me/index.dart: -------------------------------------------------------------------------------- 1 | library whisper; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/msg_feed_top/reply_me/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; 2 | import 'package:get/get.dart'; 3 | import 'package:PiliPalaX/http/msg.dart'; 4 | 5 | import '../../../models/msg/msgfeed_reply_me.dart'; 6 | 7 | class ReplyMeController extends GetxController { 8 | RxList msgFeedReplyMeList = [].obs; 9 | bool isLoading = false; 10 | int cursor = -1; 11 | int cursorTime = -1; 12 | bool isEnd = false; 13 | 14 | Future queryMsgFeedReplyMe() async { 15 | if (isLoading) return; 16 | isLoading = true; 17 | var res = await MsgHttp.msgFeedReplyMe(cursor: cursor, cursorTime: cursorTime); 18 | isLoading = false; 19 | if (res['status']) { 20 | MsgFeedReplyMe data = MsgFeedReplyMe.fromJson(res['data']); 21 | isEnd = data.cursor?.isEnd ?? false; 22 | if (cursor == -1) { 23 | msgFeedReplyMeList.assignAll(data.items!); 24 | } else { 25 | msgFeedReplyMeList.addAll(data.items!); 26 | } 27 | cursor = data.cursor?.id ?? -1; 28 | cursorTime = data.cursor?.time ?? -1; 29 | } else { 30 | SmartDialog.showToast(res['msg']); 31 | } 32 | } 33 | 34 | Future onLoad() async { 35 | if (isEnd) return; 36 | queryMsgFeedReplyMe(); 37 | } 38 | 39 | Future onRefresh() async { 40 | cursor = -1; 41 | cursorTime = -1; 42 | queryMsgFeedReplyMe(); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /lib/pages/msg_feed_top/reply_me/index.dart: -------------------------------------------------------------------------------- 1 | library whisper; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/msg_feed_top/sys_msg/index.dart: -------------------------------------------------------------------------------- 1 | library whisper; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/preview/index.dart: -------------------------------------------------------------------------------- 1 | library preview; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/rank/index.dart: -------------------------------------------------------------------------------- 1 | library rank; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/rank/zone/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:PiliPalaX/utils/extension.dart'; 2 | import 'package:get/get.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:PiliPalaX/http/video.dart'; 5 | import 'package:PiliPalaX/models/model_hot_video_item.dart'; 6 | 7 | class ZoneController extends GetxController { 8 | final ScrollController scrollController = ScrollController(); 9 | RxList videoList = [].obs; 10 | bool isLoadingMore = false; 11 | bool flag = false; 12 | int? rid; 13 | int? tid; 14 | 15 | // 获取推荐 16 | Future queryRankFeed(String type, int? rid, int? tid) async { 17 | print('queryRankFeed: $type, $rid, $tid'); 18 | this.rid = rid; 19 | this.tid = tid; 20 | late dynamic res; 21 | if (rid != null) { 22 | res = await VideoHttp.getRankVideoList(rid); 23 | } else { 24 | res = await VideoHttp.getRegionVideoList(tid!, 1, 50); 25 | } 26 | if (res['status']) { 27 | if (type == 'init') { 28 | videoList.value = res['data']; 29 | } else if (type == 'onRefresh') { 30 | videoList.clear(); 31 | videoList.addAll(res['data']); 32 | } else if (type == 'onLoad') { 33 | videoList.clear(); 34 | videoList.addAll(res['data']); 35 | } 36 | } 37 | isLoadingMore = false; 38 | return res; 39 | } 40 | 41 | // 下拉刷新 42 | Future onRefresh() async { 43 | queryRankFeed('onRefresh', rid, tid); 44 | } 45 | 46 | // 上拉加载 47 | Future onLoad() async { 48 | queryRankFeed('onLoad', rid, tid); 49 | } 50 | 51 | // 返回顶部并刷新 52 | void animateToTop() { 53 | scrollController.animToTop(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lib/pages/rank/zone/index.dart: -------------------------------------------------------------------------------- 1 | library rank.zone; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/rcmd/index.dart: -------------------------------------------------------------------------------- 1 | library recm_panel; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/search/index.dart: -------------------------------------------------------------------------------- 1 | library search; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/search/widgets/search_text.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class SearchText extends StatelessWidget { 4 | final String? searchText; 5 | final Function? onSelect; 6 | final int? searchTextIdx; 7 | final Function? onLongSelect; 8 | const SearchText({ 9 | super.key, 10 | this.searchText, 11 | this.onSelect, 12 | this.searchTextIdx, 13 | this.onLongSelect, 14 | }); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Material( 19 | color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.5), 20 | borderRadius: BorderRadius.circular(6), 21 | child: Padding( 22 | padding: EdgeInsets.zero, 23 | child: InkWell( 24 | onTap: () { 25 | onSelect!(searchText); 26 | }, 27 | onLongPress: () { 28 | onLongSelect!(searchText); 29 | }, 30 | borderRadius: BorderRadius.circular(6), 31 | child: Padding( 32 | padding: 33 | const EdgeInsets.only(top: 5, bottom: 5, left: 11, right: 11), 34 | child: Text( 35 | searchText!, 36 | style: TextStyle( 37 | color: Theme.of(context).colorScheme.onSurfaceVariant), 38 | ), 39 | ), 40 | ), 41 | ), 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/pages/search_panel/index.dart: -------------------------------------------------------------------------------- 1 | library searchpanel; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/search_result/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | 3 | class SearchResultController extends GetxController { 4 | String? keyword; 5 | int tabIndex = 0; 6 | 7 | @override 8 | void onInit() { 9 | super.onInit(); 10 | if (Get.parameters.keys.isNotEmpty) { 11 | keyword = Get.parameters['keyword']; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/pages/search_result/index.dart: -------------------------------------------------------------------------------- 1 | library searchresult; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/setting/index.dart: -------------------------------------------------------------------------------- 1 | library setting; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/subscription/index.dart: -------------------------------------------------------------------------------- 1 | library sub; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/subscription_detail/index.dart: -------------------------------------------------------------------------------- 1 | library sub_detail; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/video/index.dart: -------------------------------------------------------------------------------- 1 | library video_detail; 2 | 3 | export 'controller.dart'; 4 | export 'view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/video/introduction/bangumi/index.dart: -------------------------------------------------------------------------------- 1 | library bangumi_intro; 2 | 3 | export 'controller.dart'; 4 | export 'view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/video/introduction/detail/index.dart: -------------------------------------------------------------------------------- 1 | library video_intro_panel; 2 | 3 | export 'controller.dart'; 4 | export 'view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/video/related/controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; 3 | import 'package:get/get.dart'; 4 | import 'package:PiliPalaX/http/video.dart'; 5 | import '../../../../models/model_hot_video_item.dart'; 6 | 7 | class RelatedController extends GetxController { 8 | // 视频aid 9 | String bvid = Get.parameters['bvid'] ?? ""; 10 | // 推荐视频列表 11 | RxList relatedVideoList = [].obs; 12 | 13 | Future queryRelatedVideo() async { 14 | return VideoHttp.relatedVideoList(bvid: bvid).then((value) { 15 | if (value['status']) { 16 | relatedVideoList.value = value['data']; 17 | } else { 18 | SmartDialog.showToast(value['msg']); 19 | } 20 | return value; 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/pages/video/related/index.dart: -------------------------------------------------------------------------------- 1 | library releated_video_panel; 2 | 3 | export 'controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/video/reply/index.dart: -------------------------------------------------------------------------------- 1 | library video_reply_panel; 2 | 3 | export 'controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/video/reply_new/index.dart: -------------------------------------------------------------------------------- 1 | library video_reply_new; 2 | 3 | export 'view.dart'; -------------------------------------------------------------------------------- /lib/pages/video/reply_new/toolbar_icon_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ToolbarIconButton extends StatelessWidget { 4 | final VoidCallback onPressed; 5 | final Icon icon; 6 | final String toolbarType; 7 | final bool selected; 8 | final String tooltip; 9 | 10 | const ToolbarIconButton({ 11 | super.key, 12 | required this.onPressed, 13 | required this.icon, 14 | required this.toolbarType, 15 | required this.selected, 16 | required this.tooltip, 17 | }); 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | return SizedBox( 22 | width: 36, 23 | height: 36, 24 | child: IconButton( 25 | tooltip: tooltip, 26 | onPressed: onPressed, 27 | icon: icon, 28 | highlightColor: Theme.of(context).colorScheme.secondaryContainer, 29 | color: selected 30 | ? Theme.of(context).colorScheme.onSecondaryContainer 31 | : Theme.of(context).colorScheme.outline, 32 | style: ButtonStyle( 33 | padding: WidgetStateProperty.all(EdgeInsets.zero), 34 | backgroundColor: WidgetStateProperty.resolveWith((states) { 35 | return selected 36 | ? Theme.of(context).colorScheme.secondaryContainer 37 | : null; 38 | }), 39 | ), 40 | ), 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/pages/video/reply_reply/index.dart: -------------------------------------------------------------------------------- 1 | library video_reply_reply_panel; 2 | 3 | export 'controller.dart'; 4 | export 'view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/webview/index.dart: -------------------------------------------------------------------------------- 1 | library webview; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/whisper/index.dart: -------------------------------------------------------------------------------- 1 | library whisper; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/pages/whisper_detail/index.dart: -------------------------------------------------------------------------------- 1 | library whisper_detail; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | -------------------------------------------------------------------------------- /lib/plugin/pl_player/index.dart: -------------------------------------------------------------------------------- 1 | library pl_player; 2 | 3 | export './controller.dart'; 4 | export './view.dart'; 5 | export './models/data_source.dart'; 6 | export './models/play_status.dart'; 7 | export './models/data_status.dart'; 8 | export './widgets/common_btn.dart'; 9 | export './models/play_speed.dart'; 10 | export './models/fullscreen_mode.dart'; 11 | export './models/bottom_progress_behavior.dart'; 12 | export './widgets/app_bar_ani.dart'; 13 | export './utils/fullscreen.dart'; 14 | export './utils.dart'; 15 | -------------------------------------------------------------------------------- /lib/plugin/pl_player/models/bottom_control_type.dart: -------------------------------------------------------------------------------- 1 | enum BottomControlType { 2 | pre, 3 | playOrPause, 4 | next, 5 | // time, 6 | space, 7 | spaceButton, 8 | episode, 9 | fit, 10 | subtitle, 11 | speed, 12 | fullscreen, 13 | } 14 | -------------------------------------------------------------------------------- /lib/plugin/pl_player/models/bottom_progress_behavior.dart: -------------------------------------------------------------------------------- 1 | // ignore: camel_case_types 2 | enum BtmProgressBehavior { 3 | alwaysShow, 4 | alwaysHide, 5 | onlyShowFullScreen, 6 | onlyHideFullScreen, 7 | } 8 | 9 | extension BtmProgresBehaviorDesc on BtmProgressBehavior { 10 | String get description => ['始终展示', '始终隐藏', '仅全屏时展示', '仅全屏时隐藏'][index]; 11 | } 12 | 13 | extension BtmProgresBehaviorCode on BtmProgressBehavior { 14 | int get code => index; 15 | 16 | static BtmProgressBehavior? fromCode(int code) { 17 | if (code >= 0 && code < BtmProgressBehavior.values.length) { 18 | return BtmProgressBehavior.values[code]; 19 | } 20 | return null; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/plugin/pl_player/models/data_status.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | 3 | enum DataStatus { none, loading, loaded, error } 4 | 5 | class PlPlayerDataStatus { 6 | Rx status = Rx(DataStatus.none); 7 | 8 | bool get none => status.value == DataStatus.none; 9 | bool get loading => status.value == DataStatus.loading; 10 | bool get loaded => status.value == DataStatus.loaded; 11 | bool get error => status.value == DataStatus.error; 12 | } 13 | -------------------------------------------------------------------------------- /lib/plugin/pl_player/models/duration.dart: -------------------------------------------------------------------------------- 1 | extension DurationExtension on Duration { 2 | /// Returns clamp of [Duration] between [min] and [max]. 3 | Duration clamp(Duration min, Duration max) { 4 | if (this < min) return min; 5 | if (this > max) return max; 6 | return this; 7 | } 8 | 9 | /// Returns a [String] representation of [Duration]. 10 | String label({Duration? reference}) { 11 | reference ??= this; 12 | if (reference > const Duration(days: 1)) { 13 | final days = inDays.toString().padLeft(3, '0'); 14 | final hours = (inHours - (inDays * 24)).toString().padLeft(2, '0'); 15 | final minutes = (inMinutes - (inHours * 60)).toString().padLeft(2, '0'); 16 | final seconds = (inSeconds - (inMinutes * 60)).toString().padLeft(2, '0'); 17 | return '$days:$hours:$minutes:$seconds'; 18 | } else if (reference > const Duration(hours: 1)) { 19 | final hours = inHours.toString().padLeft(2, '0'); 20 | final minutes = (inMinutes - (inHours * 60)).toString().padLeft(2, '0'); 21 | final seconds = (inSeconds - (inMinutes * 60)).toString().padLeft(2, '0'); 22 | return '$hours:$minutes:$seconds'; 23 | } else { 24 | final minutes = inMinutes.toString().padLeft(2, '0'); 25 | final seconds = (inSeconds - (inMinutes * 60)).toString().padLeft(2, '0'); 26 | return '$minutes:$seconds'; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/plugin/pl_player/models/fullscreen_mode.dart: -------------------------------------------------------------------------------- 1 | // 全屏模式 2 | enum FullScreenMode { 3 | // 根据内容自适应 4 | auto, 5 | // 不改变当前方向 6 | none, 7 | // 始终竖屏 8 | vertical, 9 | // 始终横屏 10 | horizontal, 11 | // 屏幕长宽比<1.25时强制竖屏,否则按视频方向 12 | ratio, 13 | // 强制重力转屏(仅安卓) 14 | gravity, 15 | } 16 | 17 | extension FullScreenModeDesc on FullScreenMode { 18 | String get description => [ 19 | '按视频方向(默认)', 20 | '不改变当前方向(平板推荐)', 21 | '强制竖屏', 22 | '强制横屏', 23 | '屏幕长宽比<1.25时均竖屏,否则按视频方向', 24 | '忽略系统方向锁定,按重力转屏(仅安卓)' 25 | ][index]; 26 | } 27 | 28 | extension FullScreenModeCode on FullScreenMode { 29 | int get code => index; 30 | 31 | static FullScreenMode? fromCode(int code) { 32 | if (code >= 0 && code < FullScreenMode.values.length) { 33 | return FullScreenMode.values[code]; 34 | } 35 | return null; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/plugin/pl_player/models/play_repeat.dart: -------------------------------------------------------------------------------- 1 | enum PlayRepeat { 2 | pause, 3 | listOrder, 4 | singleCycle, 5 | listCycle, 6 | autoPlayRelated, 7 | } 8 | 9 | extension PlayRepeatExtension on PlayRepeat { 10 | static final List _descList = [ 11 | '播完暂停', 12 | '顺序播放', 13 | '单个循环', 14 | '列表循环', 15 | '自动连播', 16 | ]; 17 | String get description => _descList[index]; 18 | 19 | int get value => index + 1; //兼容历史配置 20 | } 21 | -------------------------------------------------------------------------------- /lib/plugin/pl_player/models/play_speed.dart: -------------------------------------------------------------------------------- 1 | enum PlaySpeed { 2 | one, 3 | two, 4 | } 5 | 6 | extension PlaySpeedExtension on PlaySpeed { 7 | static final List _descList = [ 8 | '1.0', 9 | '2.0', 10 | ]; 11 | String get description => _descList[index]; 12 | 13 | static final List _valueList = [ 14 | 1.0, 15 | 2.0, 16 | ]; 17 | double get value => _valueList[index]; 18 | double get defaultValue => _valueList[0]; 19 | } 20 | -------------------------------------------------------------------------------- /lib/plugin/pl_player/models/play_status.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | 3 | enum PlayerStatus { completed, playing, paused, disabled } 4 | 5 | class PlPlayerStatus { 6 | Rx status = Rx(PlayerStatus.paused); 7 | 8 | bool get playing { 9 | return status.value == PlayerStatus.playing; 10 | } 11 | 12 | bool get paused { 13 | return status.value == PlayerStatus.paused; 14 | } 15 | 16 | bool get completed { 17 | return status.value == PlayerStatus.completed; 18 | } 19 | 20 | bool get disabled { 21 | return status.value == PlayerStatus.disabled; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/plugin/pl_player/models/player_gesture_action.dart: -------------------------------------------------------------------------------- 1 | enum PlayerGestureAction { 2 | none, 3 | toggleFullScreen, 4 | pipInside, 5 | pipOutside, 6 | backToHome, 7 | prevPlay, 8 | nextPlay, 9 | } 10 | 11 | extension PlayerGestureActionDesc on PlayerGestureAction { 12 | String get description => 13 | ['无', '进入/退出全屏', '应用内小窗', '应用外小窗', '返回主页', '播放上一集', '播放下一集'][index]; 14 | } 15 | 16 | extension PlayerGestureActionCode on PlayerGestureAction { 17 | int get code => index; 18 | 19 | static PlayerGestureAction? fromCode(int code) { 20 | if (code >= 0 && code < PlayerGestureAction.values.length) { 21 | return PlayerGestureAction.values[code]; 22 | } 23 | return null; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/plugin/pl_player/models/player_middle_gesture.dart: -------------------------------------------------------------------------------- 1 | // 播放器中部手势 2 | enum PlayerMiddleGesture { 3 | nonFullScreenUp, 4 | nonFullScreenDown, 5 | fullScreenUp, 6 | fullScreenDown, 7 | } 8 | 9 | extension PlayerMiddleGestureDesc on PlayerMiddleGesture { 10 | String get description => ['非全屏时上滑', '非全屏时下滑', '全屏时上滑', '全屏时下滑'][index]; 11 | } 12 | 13 | extension PlayerMiddleGestureCode on PlayerMiddleGesture { 14 | int get code => index; 15 | 16 | static PlayerMiddleGesture? fromCode(int code) { 17 | if (code >= 0 && code < PlayerMiddleGesture.values.length) { 18 | return PlayerMiddleGesture.values[code]; 19 | } 20 | return null; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/plugin/pl_player/utils.dart: -------------------------------------------------------------------------------- 1 | String printDuration(Duration? duration) { 2 | if (duration == null) return "--:--"; 3 | 4 | /*String twoDigits(int n) { 5 | if (n >= 10||n < 0) return "$n"; 6 | return "0$n"; 7 | }*/ 8 | String twoDigits(int n) => n.toString().padLeft(2, "0"); 9 | 10 | String twoDigitMinutes = twoDigits(duration.inMinutes).replaceAll("-", ""); 11 | String twoDigitSeconds = 12 | twoDigits(duration.inSeconds.remainder(60)).replaceAll("-", ""); 13 | //customDebugPrint(duration.inSeconds.remainder(60)); 14 | return "$twoDigitMinutes:$twoDigitSeconds"; 15 | } 16 | 17 | String printDurationWithHours(Duration? duration) { 18 | if (duration == null) return "--:--:--"; 19 | 20 | String twoDigits(int n) { 21 | if (n >= 10) return "$n"; 22 | return "0$n"; 23 | } 24 | 25 | String twoDigitHours = twoDigits(duration.inHours); 26 | String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60)); 27 | String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60)); 28 | return "$twoDigitHours:$twoDigitMinutes:$twoDigitSeconds"; 29 | } 30 | -------------------------------------------------------------------------------- /lib/plugin/pl_player/widgets/common_btn.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ComBtn extends StatelessWidget { 4 | final Widget? icon; 5 | final Function? fuc; 6 | 7 | const ComBtn({ 8 | this.icon, 9 | this.fuc, 10 | super.key, 11 | }); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return SizedBox( 16 | width: 34, 17 | height: 34, 18 | child: InkWell( 19 | onTap: () { 20 | fuc!(); 21 | }, 22 | child: icon!, 23 | ), 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/scripts/build.sh: -------------------------------------------------------------------------------- 1 | flutter build apk --target-platform android-arm64 --split-per-abi -------------------------------------------------------------------------------- /lib/services/loggeer.dart: -------------------------------------------------------------------------------- 1 | // final _loggerFactory = 2 | 3 | import 'dart:io'; 4 | 5 | import 'package:logger/logger.dart'; 6 | import 'package:path_provider/path_provider.dart'; 7 | import 'package:path/path.dart' as p; 8 | 9 | final _loggerFactory = PiliLogger(); 10 | 11 | PiliLogger getLogger() { 12 | return _loggerFactory; 13 | } 14 | 15 | class PiliLogger extends Logger { 16 | PiliLogger() : super(); 17 | 18 | @override 19 | void log(Level level, dynamic message, 20 | {Object? error, StackTrace? stackTrace, DateTime? time}) async { 21 | if (level == Level.error || level == Level.fatal) { 22 | // 添加至文件末尾 23 | File logFile = await getLogsPath(); 24 | logFile.writeAsString( 25 | "**${DateTime.now()}** \n $message \n $stackTrace", 26 | mode: FileMode.writeOnlyAppend, 27 | ); 28 | } 29 | super.log(level, "$message", error: error, stackTrace: stackTrace); 30 | } 31 | } 32 | 33 | Future getLogsPath() async { 34 | String dir = (await getApplicationDocumentsDirectory()).path; 35 | final String filename = p.join(dir, ".pili_logs"); 36 | final File file = File(filename); 37 | if (!await file.exists()) { 38 | await file.create(recursive: true); 39 | } 40 | return file; 41 | } 42 | 43 | Future clearLogs() async { 44 | final File file = await getLogsPath(); 45 | try { 46 | await file.writeAsString(''); 47 | } catch (e) { 48 | print('Error clearing file: $e'); 49 | return false; 50 | } 51 | return true; 52 | } 53 | -------------------------------------------------------------------------------- /lib/services/service_locator.dart: -------------------------------------------------------------------------------- 1 | import 'audio_handler.dart'; 2 | import 'audio_session.dart'; 3 | import 'package:flutter_floating/floating/assist/floating_slide_type.dart'; 4 | import 'package:flutter_floating/floating/floating.dart'; 5 | import 'package:flutter_floating/floating/manager/floating_manager.dart'; 6 | 7 | late VideoPlayerServiceHandler videoPlayerServiceHandler; 8 | late AudioSessionHandler audioSessionHandler; 9 | Floating? floatingWindow; 10 | const globalId = 'global_floating_window'; 11 | String popRouteStackContinuously = ""; 12 | 13 | Future setupServiceLocator() async { 14 | final audio = await initAudioService(); 15 | videoPlayerServiceHandler = audio; 16 | audioSessionHandler = AudioSessionHandler(); 17 | } 18 | -------------------------------------------------------------------------------- /lib/utils/danmaku.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:canvas_danmaku/canvas_danmaku.dart'; 3 | 4 | class DmUtils { 5 | static Color decimalToColor(int decimalColor) { 6 | // 16777215 表示白色 7 | // int red = (decimalColor >> 16) & 0xFF; 8 | // int green = (decimalColor >> 8) & 0xFF; 9 | // int blue = decimalColor & 0xFF; 10 | // 11 | // return Color.fromARGB(255, red, green, blue); 12 | return Color(decimalColor); 13 | } 14 | 15 | static DanmakuItemType getPosition(int mode) { 16 | DanmakuItemType type = DanmakuItemType.scroll; 17 | if (mode >= 1 && mode <= 3) { 18 | type = DanmakuItemType.scroll; 19 | } else if (mode == 4) { 20 | type = DanmakuItemType.bottom; 21 | } else if (mode == 5) { 22 | type = DanmakuItemType.top; 23 | } 24 | return type; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/utils/data.dart: -------------------------------------------------------------------------------- 1 | import 'package:hive/hive.dart'; 2 | import 'package:PiliPalaX/http/user.dart'; 3 | 4 | import 'storage.dart'; 5 | 6 | class Data { 7 | static Future init() async { 8 | await historyStatus(); 9 | } 10 | 11 | static Future historyStatus() async { 12 | Box localCache = GStorage.localCache; 13 | Box userInfoCache = GStorage.userInfo; 14 | if (userInfoCache.get('userInfoCache') == null) { 15 | return; 16 | } 17 | var res = await UserHttp.historyStatus(); 18 | if (res['status']) { 19 | localCache.put(LocalCacheKey.historyPause, res['data']); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/utils/event_bus.dart: -------------------------------------------------------------------------------- 1 | // 订阅者回调签名 2 | typedef void EventCallback(arg); 3 | 4 | class EventBus { 5 | // 私有构造函数 6 | EventBus._internal(); 7 | 8 | // 保存单例 9 | static final EventBus _singleton = EventBus._internal(); 10 | 11 | // 工厂构造函数 12 | factory EventBus() => _singleton; 13 | 14 | // 保存事件订阅者队列,key:事件名(id),value: 对应事件的订阅者队列 15 | final _emap = >{}; 16 | 17 | // 添加订阅者 18 | void on(eventName, EventCallback f) { 19 | _emap[eventName] ??= []; 20 | _emap[eventName]!.add(f); 21 | } 22 | 23 | // 移除订阅者 24 | void off(eventName, [EventCallback? f]) { 25 | var list = _emap[eventName]; 26 | if (eventName == null || list == null) return; 27 | if (f == null) { 28 | _emap[eventName] = []; 29 | } else { 30 | list.remove(f); 31 | } 32 | } 33 | 34 | // 触发事件,事件触发后该事件所有订阅者会被调用 35 | void emit(eventName, [arg]) { 36 | var list = _emap[eventName]; 37 | if (list == null) return; 38 | List tempList = List.from(list); 39 | for (var callback in tempList) { 40 | callback(arg); 41 | } 42 | } 43 | 44 | // 获取订阅者数量 45 | int getSubscriberCount(eventName) { 46 | var list = _emap[eventName]; 47 | return list?.length ?? 0; 48 | } 49 | } 50 | 51 | class EventName { 52 | static const String loginEvent = 'loginEvent'; 53 | } 54 | -------------------------------------------------------------------------------- /lib/utils/extension.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | 4 | extension ImageExtension on num { 5 | int cacheSize(BuildContext context) { 6 | return (this * MediaQuery.of(context).devicePixelRatio).round(); 7 | } 8 | } 9 | 10 | extension ScrollControllerExt on ScrollController { 11 | void animToTop() { 12 | if (!hasClients) return; 13 | if (offset >= MediaQuery.of(Get.context!).size.height * 5) { 14 | jumpTo(0); 15 | } else { 16 | animateTo(0, 17 | duration: const Duration(milliseconds: 500), curve: Curves.easeInOut); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/utils/feed_back.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/services.dart'; 2 | import 'package:hive/hive.dart'; 3 | import 'storage.dart'; 4 | 5 | void feedBack() { 6 | Box setting = GStorage.setting; 7 | // 设置中是否开启 8 | final bool enable = 9 | setting.get(SettingBoxKey.feedBackEnable, defaultValue: false) as bool; 10 | if (enable) { 11 | HapticFeedback.lightImpact(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/utils/global_data.dart: -------------------------------------------------------------------------------- 1 | class GlobalData { 2 | int imgQuality = 10; 3 | 4 | // 私有构造函数 5 | GlobalData._(); 6 | 7 | // 单例实例 8 | static final GlobalData _instance = GlobalData._(); 9 | 10 | // 获取全局实例 11 | factory GlobalData() => _instance; 12 | } 13 | -------------------------------------------------------------------------------- /lib/utils/proxy.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:system_proxy/system_proxy.dart'; 3 | 4 | class CustomProxy { 5 | init() async { 6 | Map? proxy = await SystemProxy.getProxySettings(); 7 | if (proxy != null) { 8 | HttpOverrides.global = 9 | ProxiedHttpOverrides(proxy['host']!, proxy['port']!); 10 | } 11 | } 12 | } 13 | 14 | class ProxiedHttpOverrides extends HttpOverrides { 15 | final String _port; 16 | final String _host; 17 | 18 | ProxiedHttpOverrides(this._host, this._port); 19 | 20 | @override 21 | HttpClient createHttpClient(SecurityContext? context) { 22 | return super.createHttpClient(context) 23 | // set proxy 24 | ..findProxy = (uri) { 25 | return "PROXY $_host:$_port;"; 26 | }; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | -------------------------------------------------------------------------------- /linux/main.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | int main(int argc, char** argv) { 4 | g_autoptr(MyApplication) app = my_application_new(); 5 | return g_application_run(G_APPLICATION(app), argc, argv); 6 | } 7 | -------------------------------------------------------------------------------- /linux/my_application.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_MY_APPLICATION_H_ 2 | #define FLUTTER_MY_APPLICATION_H_ 3 | 4 | #include 5 | 6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, 7 | GtkApplication) 8 | 9 | /** 10 | * my_application_new: 11 | * 12 | * Creates a new Flutter-based application. 13 | * 14 | * Returns: a new #MyApplication. 15 | */ 16 | MyApplication* my_application_new(); 17 | 18 | #endif // FLUTTER_MY_APPLICATION_H_ 19 | -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.14' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | end 35 | 36 | post_install do |installer| 37 | installer.pods_project.targets.each do |target| 38 | flutter_additional_macos_build_settings(target) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/macos/Runner/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/macos/Runner/Assets.xcassets/AppIcon.appiconset/128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/macos/Runner/Assets.xcassets/AppIcon.appiconset/16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/macos/Runner/Assets.xcassets/AppIcon.appiconset/256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/macos/Runner/Assets.xcassets/AppIcon.appiconset/32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/macos/Runner/Assets.xcassets/AppIcon.appiconset/512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/macos/Runner/Assets.xcassets/AppIcon.appiconset/64.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | {"images":[{"size":"128x128","expected-size":"128","filename":"128.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"256x256","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"128x128","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"256x256","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"512x512","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"16","filename":"16.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"64","filename":"64.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"512x512","expected-size":"1024","filename":"1024.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"}]} -------------------------------------------------------------------------------- /macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = pilipala 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.pilipala 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2023 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | com.apple.security.network.client 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.network.client 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility in the flutter_test package. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:PiliPalaX/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(const MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pilipala", 3 | "short_name": "pilipala", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /web/splash/img/dark-1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/web/splash/img/dark-1x.png -------------------------------------------------------------------------------- /web/splash/img/dark-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/web/splash/img/dark-2x.png -------------------------------------------------------------------------------- /web/splash/img/dark-3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/web/splash/img/dark-3x.png -------------------------------------------------------------------------------- /web/splash/img/dark-4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/web/splash/img/dark-4x.png -------------------------------------------------------------------------------- /web/splash/img/light-1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/web/splash/img/light-1x.png -------------------------------------------------------------------------------- /web/splash/img/light-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/web/splash/img/light-2x.png -------------------------------------------------------------------------------- /web/splash/img/light-3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/web/splash/img/light-3x.png -------------------------------------------------------------------------------- /web/splash/img/light-4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/web/splash/img/light-4x.png -------------------------------------------------------------------------------- /windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_FLUTTER_WINDOW_H_ 2 | #define RUNNER_FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "win32_window.h" 10 | 11 | // A window that does nothing but host a Flutter view. 12 | class FlutterWindow : public Win32Window { 13 | public: 14 | // Creates a new FlutterWindow hosting a Flutter view running |project|. 15 | explicit FlutterWindow(const flutter::DartProject& project); 16 | virtual ~FlutterWindow(); 17 | 18 | protected: 19 | // Win32Window: 20 | bool OnCreate() override; 21 | void OnDestroy() override; 22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 23 | LPARAM const lparam) noexcept override; 24 | 25 | private: 26 | // The project to run. 27 | flutter::DartProject project_; 28 | 29 | // The Flutter instance hosted by this window. 30 | std::unique_ptr flutter_controller_; 31 | }; 32 | 33 | #endif // RUNNER_FLUTTER_WINDOW_H_ 34 | -------------------------------------------------------------------------------- /windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "utils.h" 7 | 8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 9 | _In_ wchar_t *command_line, _In_ int show_command) { 10 | // Attach to console when present (e.g., 'flutter run') or create a 11 | // new console when running with a debugger. 12 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 13 | CreateAndAttachConsole(); 14 | } 15 | 16 | // Initialize COM, so that it is available for use in the library and/or 17 | // plugins. 18 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 19 | 20 | flutter::DartProject project(L"data"); 21 | 22 | std::vector command_line_arguments = 23 | GetCommandLineArguments(); 24 | 25 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); 26 | 27 | FlutterWindow window(project); 28 | Win32Window::Point origin(10, 10); 29 | Win32Window::Size size(1280, 720); 30 | if (!window.Create(L"pilipala", origin, size)) { 31 | return EXIT_FAILURE; 32 | } 33 | window.SetQuitOnClose(true); 34 | 35 | ::MSG msg; 36 | while (::GetMessage(&msg, nullptr, 0, 0)) { 37 | ::TranslateMessage(&msg); 38 | ::DispatchMessage(&msg); 39 | } 40 | 41 | ::CoUninitialize(); 42 | return EXIT_SUCCESS; 43 | } 44 | -------------------------------------------------------------------------------- /windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orz12/PiliPalaX/2da94140c2b49402dac2597aa6553bfc65b8663a/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | --------------------------------------------------------------------------------