Repository: CarGuo/gsy_github_app_flutter Branch: master Commit: 5917c1936240 Files: 369 Total size: 1.2 MB Directory structure: gitextract_kfzn5wba/ ├── .fvmrc ├── .github/ │ ├── FUNDING.yml │ └── workflows/ │ └── ci.yml ├── .gitignore ├── .metadata ├── .vscode/ │ └── settings.json ├── AGENTS.md ├── LICENSE ├── README.md ├── README_EN.md ├── RECORD.md ├── UISCENE_PLUGIN_RISK.md ├── VERSION.md ├── analysis_options.yaml ├── android/ │ ├── .gitignore │ ├── app/ │ │ ├── build.gradle │ │ ├── exported.gradle │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── kotlin/ │ │ │ └── com/ │ │ │ └── shuyu/ │ │ │ └── gsygithub/ │ │ │ └── gsygithubappflutter/ │ │ │ ├── MainActivity.kt │ │ │ └── UpdateAlbumPlugin.kt │ │ └── res/ │ │ ├── drawable/ │ │ │ ├── launch_background.xml │ │ │ └── normal_background.xml │ │ └── values/ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle/ │ │ └── wrapper/ │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradle.properties │ ├── gradlew │ ├── gradlew.bat │ ├── gsygithubapp-debug.jks │ └── settings.gradle ├── devtools_options.yaml ├── docs/ │ ├── 00-overview/ │ │ └── project-map.md │ ├── 01-architecture/ │ │ ├── app-layering.md │ │ └── state-management-matrix.md │ ├── 02-features/ │ │ ├── debug.md │ │ ├── dynamic.md │ │ ├── home.md │ │ ├── issue.md │ │ ├── login.md │ │ ├── notify.md │ │ ├── push.md │ │ ├── release.md │ │ ├── repos.md │ │ ├── search.md │ │ ├── trend.md │ │ └── user.md │ ├── 03-runbooks/ │ │ └── local-setup.md │ ├── 04-quality/ │ │ ├── smoke-matrix.md │ │ └── test-strategy.md │ ├── 05-ai/ │ │ ├── agent-guide.md │ │ ├── feature-playbooks/ │ │ │ ├── debug-change.md │ │ │ ├── dynamic-change.md │ │ │ ├── home-change.md │ │ │ ├── issue-change.md │ │ │ ├── notify-change.md │ │ │ ├── push-change.md │ │ │ ├── release-change.md │ │ │ ├── repos-change.md │ │ │ ├── search-change.md │ │ │ ├── trend-change.md │ │ │ └── user-change.md │ │ ├── prompts/ │ │ │ ├── author-handoff.md │ │ │ └── reviewer-system.md │ │ ├── review-harness.md │ │ └── task-playbooks/ │ │ ├── add-api.md │ │ ├── add-page.md │ │ ├── fix-bug.md │ │ └── refactor-state.md │ ├── 06-decisions/ │ │ ├── ADR-0001-状态管理收敛策略.md │ │ ├── ADR-0002-新增功能默认状态方案.md │ │ └── README.md │ ├── CONTRIBUTING_AI.md │ └── README.md ├── fastlane/ │ └── metadata/ │ └── android/ │ └── en-US/ │ ├── full_description.txt │ └── short_description.txt ├── ios/ │ ├── .gitignore │ ├── Flutter/ │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── ephemeral/ │ │ ├── flutter_lldb_helper.py │ │ └── flutter_lldbinit │ ├── Podfile │ ├── Runner/ │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets/ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ └── LaunchImage.imageset/ │ │ │ └── Contents.json │ │ ├── Base.lproj/ │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── Runner-Bridging-Header.h │ │ └── SceneDelegate.swift │ ├── Runner.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── Runner.xcscheme │ └── Runner.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ └── IDEWorkspaceChecks.plist ├── l10n.yaml ├── lib/ │ ├── app.dart │ ├── common/ │ │ ├── config/ │ │ │ └── config.dart │ │ ├── event/ │ │ │ ├── event_bus.dart │ │ │ ├── http_error_event.dart │ │ │ └── index.dart │ │ ├── local/ │ │ │ └── local_storage.dart │ │ ├── localization/ │ │ │ ├── extension.dart │ │ │ └── l10n/ │ │ │ ├── app_en.arb │ │ │ ├── app_ja.arb │ │ │ ├── app_ko.arb │ │ │ ├── app_localizations.dart │ │ │ ├── app_localizations_en.dart │ │ │ ├── app_localizations_ja.dart │ │ │ ├── app_localizations_ko.dart │ │ │ ├── app_localizations_zh.dart │ │ │ └── app_zh.arb │ │ ├── logger.dart │ │ ├── net/ │ │ │ ├── AGENTS.md │ │ │ ├── address.dart │ │ │ ├── api.dart │ │ │ ├── code.dart │ │ │ ├── graphql/ │ │ │ │ ├── client.dart │ │ │ │ ├── repositories.dart │ │ │ │ └── users.dart │ │ │ ├── interceptors/ │ │ │ │ ├── error_interceptor.dart │ │ │ │ ├── header_interceptor.dart │ │ │ │ ├── log_interceptor.dart │ │ │ │ ├── response_interceptor.dart │ │ │ │ └── token_interceptor.dart │ │ │ ├── result_data.dart │ │ │ ├── transformer.dart │ │ │ ├── transformer.g.dart │ │ │ └── trending/ │ │ │ └── github_trending.dart │ │ ├── repositories/ │ │ │ ├── data_result.dart │ │ │ ├── event_repository.dart │ │ │ ├── issue_repository.dart │ │ │ ├── repos_repository.dart │ │ │ └── user_repository.dart │ │ ├── router/ │ │ │ └── anima_route.dart │ │ ├── style/ │ │ │ └── gsy_style.dart │ │ ├── toast.dart │ │ └── utils/ │ │ ├── code_utils.dart │ │ ├── common_utils.dart │ │ ├── event_utils.dart │ │ ├── html_utils.dart │ │ └── navigator_utils.dart │ ├── db/ │ │ ├── provider/ │ │ │ ├── event/ │ │ │ │ ├── received_event_db_provider.dart │ │ │ │ └── user_event_db_provider.dart │ │ │ ├── issue/ │ │ │ │ ├── issue_comment_db_provider.dart │ │ │ │ └── issue_detail_db_provider.dart │ │ │ ├── repos/ │ │ │ │ ├── read_history_db_provider.dart │ │ │ │ ├── repository_branch_db_provider.dart │ │ │ │ ├── repository_commitInfo_detail_db_provider.dart │ │ │ │ ├── repository_commits_db_provider.dart │ │ │ │ ├── repository_detail_db_provider.dart │ │ │ │ ├── repository_detail_readme_db_provider.dart │ │ │ │ ├── repository_event_db_provider.dart │ │ │ │ ├── repository_fork_db_provider.dart │ │ │ │ ├── repository_issue_db_provider.dart │ │ │ │ ├── repository_pulse_db_provider.dart │ │ │ │ ├── repository_star_db_provider.dart │ │ │ │ ├── repository_watcher_db_provider.dart │ │ │ │ └── trend_repository_db_provider.dart │ │ │ └── user/ │ │ │ ├── org_member_db_provider.dart │ │ │ ├── user_followed_db_provider.dart │ │ │ ├── user_follower_db_provider.dart │ │ │ ├── user_orgs_db_provider.dart │ │ │ ├── user_repos_db_provider.dart │ │ │ ├── user_stared_db_provider.dart │ │ │ └── userinfo_db_provider.dart │ │ ├── sql_manager.dart │ │ └── sql_provider.dart │ ├── env/ │ │ ├── AGENTS.md │ │ ├── config_wrapper.dart │ │ ├── dev.dart │ │ ├── dev.g.dart │ │ ├── env_config.dart │ │ ├── env_config.g.dart │ │ ├── env_json_dev.json │ │ ├── env_json_prod.json │ │ ├── prod.dart │ │ └── prod.g.dart │ ├── main.dart │ ├── main_prod.dart │ ├── model/ │ │ ├── branch.dart │ │ ├── branch.g.dart │ │ ├── commitFile.dart │ │ ├── commitFile.g.dart │ │ ├── commit_comment.dart │ │ ├── commit_comment.g.dart │ │ ├── commit_git_info.dart │ │ ├── commit_git_info.g.dart │ │ ├── commit_git_user.dart │ │ ├── commit_git_user.g.dart │ │ ├── commit_stats.dart │ │ ├── commit_stats.g.dart │ │ ├── commits_comparison.dart │ │ ├── commits_comparison.g.dart │ │ ├── common_list_datatype.dart │ │ ├── download_source.dart │ │ ├── download_source.g.dart │ │ ├── event.dart │ │ ├── event.g.dart │ │ ├── event_payload.dart │ │ ├── event_payload.g.dart │ │ ├── file_model.dart │ │ ├── file_model.g.dart │ │ ├── issue.dart │ │ ├── issue.g.dart │ │ ├── issue_event.dart │ │ ├── issue_event.g.dart │ │ ├── license.dart │ │ ├── license.g.dart │ │ ├── notification.dart │ │ ├── notification.g.dart │ │ ├── notification_subject.dart │ │ ├── notification_subject.g.dart │ │ ├── push_commit.dart │ │ ├── push_commit.g.dart │ │ ├── push_event_commit.dart │ │ ├── push_event_commit.g.dart │ │ ├── release.dart │ │ ├── release.g.dart │ │ ├── release_asset.dart │ │ ├── release_asset.g.dart │ │ ├── repo_commit.dart │ │ ├── repo_commit.g.dart │ │ ├── repository.dart │ │ ├── repository.g.dart │ │ ├── repository_permissions.dart │ │ ├── repository_permissions.g.dart │ │ ├── repository_ql.dart │ │ ├── search_user_ql.dart │ │ ├── template.dart │ │ ├── template.g.dart │ │ ├── trending_repo_model.dart │ │ ├── trending_repo_model.g.dart │ │ ├── user.dart │ │ ├── user.g.dart │ │ ├── user_org.dart │ │ └── user_org.g.dart │ ├── page/ │ │ ├── AGENTS.md │ │ ├── code_detail_page_web.dart │ │ ├── common_list_page.dart │ │ ├── debug/ │ │ │ ├── debug_data_page.dart │ │ │ └── debug_label.dart │ │ ├── dynamic/ │ │ │ ├── dynamic_bloc.dart │ │ │ └── dynamic_page.dart │ │ ├── error_page.dart │ │ ├── gsy_webview.dart │ │ ├── home/ │ │ │ ├── home_page.dart │ │ │ └── widget/ │ │ │ └── home_drawer.dart │ │ ├── honor_list_page.dart │ │ ├── issue/ │ │ │ ├── issue_detail_page.dart │ │ │ ├── issue_edit_dIalog.dart │ │ │ └── widget/ │ │ │ ├── issue_header_item.dart │ │ │ └── issue_item.dart │ │ ├── login/ │ │ │ ├── login_page.dart │ │ │ └── login_webview.dart │ │ ├── my_page.dart │ │ ├── notify/ │ │ │ └── notify_page.dart │ │ ├── photoview_page.dart │ │ ├── push/ │ │ │ ├── push_detail_page.dart │ │ │ └── widget/ │ │ │ ├── push_coed_item.dart │ │ │ └── push_header.dart │ │ ├── release/ │ │ │ ├── release_page.dart │ │ │ └── widget/ │ │ │ └── release_item.dart │ │ ├── repos/ │ │ │ ├── provider/ │ │ │ │ ├── repos_detail_provider.dart │ │ │ │ └── repos_network_provider.dart │ │ │ ├── repository_detail_issue_list_page.dart │ │ │ ├── repository_detail_page.dart │ │ │ ├── repository_detail_readme_page.dart │ │ │ ├── repository_file_list_page.dart │ │ │ ├── repostory_detail_info_page.dart │ │ │ └── widget/ │ │ │ ├── repos_header_item.dart │ │ │ └── repos_item.dart │ │ ├── search/ │ │ │ ├── search_bloc.dart │ │ │ ├── search_page.dart │ │ │ └── widget/ │ │ │ ├── gsy_search_drawer.dart │ │ │ └── gsy_search_input_widget.dart │ │ ├── trend/ │ │ │ ├── trend_page.dart │ │ │ ├── trend_provider.dart │ │ │ ├── trend_provider.g.dart │ │ │ ├── trend_user_page.dart │ │ │ ├── trend_user_provider.dart │ │ │ └── trend_user_provider.g.dart │ │ ├── user/ │ │ │ ├── base_person_provider.dart │ │ │ ├── base_person_provider.g.dart │ │ │ ├── base_person_state.dart │ │ │ ├── person_page.dart │ │ │ └── widget/ │ │ │ ├── user_header.dart │ │ │ └── user_item.dart │ │ ├── user_profile_page.dart │ │ └── welcome_page.dart │ ├── provider/ │ │ ├── app_state_provider.dart │ │ └── app_state_provider.g.dart │ ├── redux/ │ │ ├── gsy_state.dart │ │ ├── login_redux.dart │ │ ├── middleware/ │ │ │ ├── combine_epics.dart │ │ │ ├── epic.dart │ │ │ ├── epic_middleware.dart │ │ │ └── epic_store.dart │ │ └── user_redux.dart │ ├── test/ │ │ ├── demo_app.dart │ │ ├── demo_appbar.dart │ │ ├── demo_bloc_page.dart │ │ ├── demo_db.dart │ │ ├── demo_item.dart │ │ ├── demo_mixins.dart │ │ ├── demo_page.dart │ │ ├── demo_tab_page.dart │ │ ├── demo_text_field_page.dart │ │ ├── demo_user_store.dart │ │ └── demo_widget.dart │ └── widget/ │ ├── anima/ │ │ └── curves_bezier.dart │ ├── animated_background.dart │ ├── diff_scale_text.dart │ ├── flutter_json_widget.dart │ ├── gsy_bottom_action_bar.dart │ ├── gsy_card_item.dart │ ├── gsy_common_option_widget.dart │ ├── gsy_event_item.dart │ ├── gsy_flex_button.dart │ ├── gsy_icon_text.dart │ ├── gsy_input_widget.dart │ ├── gsy_select_item_widget.dart │ ├── gsy_tabbar_widget.dart │ ├── gsy_tabs.dart │ ├── gsy_title_bar.dart │ ├── gsy_user_icon_widget.dart │ ├── markdown/ │ │ ├── gsy_markdown_widget.dart │ │ └── syntax_high_lighter.dart │ ├── menu/ │ │ ├── flutter_radial_menu.dart │ │ └── src/ │ │ ├── arc_progress_indicator.dart │ │ ├── radial_menu.dart │ │ ├── radial_menu_button.dart │ │ ├── radial_menu_center_button.dart │ │ └── radial_menu_item.dart │ ├── mole_widget.dart │ ├── never_overscroll_indicator.dart │ ├── only_share_widget.dart │ ├── particle/ │ │ ├── particle_model.dart │ │ ├── particle_painter.dart │ │ └── particle_widget.dart │ ├── pull/ │ │ ├── custom_bouncing_scroll_physics.dart │ │ ├── gsy_flare_mutli_pull_controller.dart │ │ ├── gsy_flare_pull_controller.dart │ │ ├── gsy_pull_load_widget.dart │ │ ├── gsy_pull_new_load_widget.dart │ │ ├── gsy_refresh_sliver.dart │ │ └── nested/ │ │ ├── gsy_nested_pull_load_widget.dart │ │ ├── gsy_sliver_header_delegate.dart │ │ └── nested_refresh.dart │ └── state/ │ └── gsy_list_state.dart ├── pubspec.yaml ├── static/ │ ├── file/ │ │ ├── Space-Demo.flr │ │ ├── flare_flutter_logo_.flr │ │ ├── launch.riv │ │ ├── loading_world_now.flr │ │ ├── rejection.json │ │ ├── rejection2.json │ │ ├── search.json │ │ └── user.json │ └── font/ │ ├── demo.css │ ├── demo_fontclass.html │ ├── demo_symbol.html │ ├── demo_unicode.html │ ├── iconfont.css │ └── iconfont.js └── tool/ └── ai/ └── build_review_bundle.ps1 ================================================ FILE CONTENTS ================================================ ================================================ FILE: .fvmrc ================================================ { "flutter": "3.38.4" } ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms custom: http://img.cdn.guoshuyu.cn/thanks.jpg ================================================ FILE: .github/workflows/ci.yml ================================================ name: CI on: push: branches: - master tags: - '*' pull_request: paths-ignore: - '**/*.md' - '**/*.txt' - '**/*.png' - '**/*.jpg' jobs: build: name: Build runs-on: ubuntu-latest steps: - name: Free Disk Space uses: jlumbroso/free-disk-space@main with: tool-cache: false android: false dotnet: true haskell: true large-packages: true docker-images: true swap-storage: true - uses: actions/checkout@v2 - uses: actions/setup-java@v2 with: distribution: 'zulu' java-version: 21 - uses: subosito/flutter-action@v1 with: flutter-version: '3.38.4' - name: Create config file run: | echo 'class NetConfig { static const CLIENT_ID = "${{ secrets.CLIENT_ID }}"; static const CLIENT_SECRET = "${{ secrets.CLIENT_SECRET }}";}' > lib/common/config/ignoreConfig.dart - run: flutter pub get - run: flutter build apk --release --target-platform=android-arm64 --no-shrink apk: name: Generate APK if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: - name: Free Disk Space uses: jlumbroso/free-disk-space@main with: tool-cache: false android: false dotnet: true haskell: true large-packages: true docker-images: true swap-storage: true - name: Checkout uses: actions/checkout@v2 - name: Setup JDK uses: actions/setup-java@v2 with: distribution: 'zulu' java-version: 21 - uses: subosito/flutter-action@v1 with: flutter-version: '3.38.4' - name: Create config file run: | echo 'class NetConfig { static const CLIENT_ID = "${{ secrets.CLIENT_ID }}"; static const CLIENT_SECRET = "${{ secrets.CLIENT_SECRET }}";}' > lib/common/config/ignoreConfig.dart - run: flutter pub get - run: flutter build apk --release --target-platform=android-arm64 --no-shrink - name: Upload APK uses: actions/upload-artifact@v4 with: name: apk path: build/app/outputs/apk/release/app-release.apk release: name: Release APK needs: apk if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: - name: Free Disk Space uses: jlumbroso/free-disk-space@main with: tool-cache: false android: false dotnet: true haskell: true large-packages: true docker-images: true swap-storage: true - name: Download APK from build uses: actions/download-artifact@v4 with: name: apk - name: Display structure of downloaded files run: ls -R - name: Create Release id: create_release uses: actions/create-release@v1.1.4 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ github.ref }} release_name: ${{ github.ref }} - name: Upload Release APK id: upload_release_asset uses: actions/upload-release-asset@v1.0.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: ./app-release.apk asset_name: app-release.apk asset_content_type: application/zip ================================================ FILE: .gitignore ================================================ .DS_Store .dart_tool/ .packages .pub/ build/ .flutter-plugins .flutter-plugins-dependencies .gradle/ ignoreConfig.dart flutter_export_environment.sh # Miscellaneous *.class *.log *.pyc *.swp .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ **/ios/Flutter/.last_build_id .pub-cache/ /build/ # Web related lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols # Obfuscation related app.*.map.json # Exceptions to above rules. !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages # FVM Version Cache .fvm/ ================================================ FILE: .metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: 18cd7a3601bcffb36fdf2f679f763b5e827c2e8e channel: unknown project_type: app ================================================ FILE: .vscode/settings.json ================================================ { "java.configuration.updateBuildConfiguration": "disabled" } ================================================ FILE: AGENTS.md ================================================ # GSY GitHub App Flutter 协作说明 这是一个 Flutter GitHub 客户端,同时也是带有教学展示性质的示例工程。 不要假设整个仓库是单一架构风格。多种状态管理方案并存是当前设计现实,不是偶然脏代码。 ## 进入仓库后先读 在进行非微小改动前,先读这些文件: 1. `README.md` 2. `docs/README.md` 3. `docs/00-overview/project-map.md` 4. `docs/01-architecture/app-layering.md` 5. `docs/01-architecture/state-management-matrix.md` ## 工作规则 - 改动尽量限制在当前功能域,不要顺手做跨模块重构。 - 非任务明确要求时,不要迁移状态管理框架。 - 优先遵循目标模块现有模式,而不是引入新的全局规范。 - 未经明确允许,不得为了满足需求擅自替换模块既有框架或状态实现,即使替换后看起来更简单。 - `*.g.dart`、多语言生成文件、env 生成文件都视为生成产物;优先重新生成,不要手改。 - 不要提交密钥。`lib/common/config/ignoreConfig.dart` 属于本地或 CI 环境材料。 ## 高风险目录 - `lib/app.dart`:应用根装配、导航、全局报错、Redux 和 Riverpod 混合接线 - `lib/common/net/`:共享网络栈、拦截器、GraphQL/REST 入口 - `lib/common/repositories/`:功能数据访问边界 - `lib/env/`:构建期环境配置和生成文件 - `lib/common/localization/`:ARB 与多语言生成输出 ## 建议修改策略 - 纯 UI 任务:优先只改页面或局部 widget,不碰全局状态 - API 任务:同时检查 `common/net` 与对应 `common/repositories` - 状态任务:沿用该模块当前已有状态方案,除非任务明确要求迁移 - 配置/构建任务:同步更新 `docs/03-runbooks/` 中的操作说明 ## Review 规则 - 中等以上改动默认使用独立 reviewer 上下文 - 每次非微小代码改动后,默认拉起新的 reviewer subagent 或新的干净上下文审查刚刚的修改 - author 在通过一轮新的 reviewer subagent 审查前,不应直接宣告代码任务完成 - reviewer 不应复用 author 的完整上下文历史 - 先看 `docs/05-ai/review-harness.md` - reviewer 提示模板见 `docs/05-ai/prompts/reviewer-system.md` - `tool/ai/build_review_bundle.ps1` 只是可选辅助,不是主流程 ## 本地最小验证 按改动范围选择最小验证集合: - `flutter pub get` - `dart run build_runner build --delete-conflicting-outputs` - `flutter gen-l10n` - `flutter analyze` - `flutter build apk --release --target-platform=android-arm64 --no-shrink` 说明: - 改模型、env、注解生成代码时跑 `build_runner` - 改 ARB 或本地化输入时跑 `flutter gen-l10n` - 改 Android 构建、依赖或运行时关键路径时跑 APK 构建 ## 当前已知约束 - 仓库目前没有提交进来的 `test/` 测试目录 - CI 使用 GitHub Actions,当前偏重构建成功 - 项目同时使用 Redux、Riverpod、Provider、Signals - OAuth 登录相关流程依赖本地 `ignoreConfig.dart` ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================  [](https://github.com/CarGuo/gsy_github_app_flutter/actions) [](https://github.com/CarGuo/GSYGithubAppFlutter/stargazers) [](https://github.com/CarGuo/GSYGithubAppFlutter/network) [](https://github.com/CarGuo/GSYGithubAppFlutter/issues) [](https://github.com/CarGuo/GSYGithubAppFlutter/blob/master/LICENSE) [](https://gitcode.com/ZuoYueLiang/gsy_github_app_flutter) ### [English Readme](https://github.com/CarGuo/GSYGithubAppFlutter/blob/master/README_EN.md) ## 一款跨平台的开源Github客户端App,提供更丰富的功能,更好体验,旨在更好的日常管理和维护个人Github,提供更好更方便的驾车体验~~Σ( ̄。 ̄ノ)ノ。项目涉及各种常用控件、网络、数据库、设计模式、主题切换、多语言、状态管理(Redux、Riverpod、Provider)等。在开发学习过程中,提供丰富的同款对比: * ### 同款Weex版 ( https://github.com/CarGuo/GSYGithubAppWeex ) * ### 同款ReactNative版 ( https://github.com/CarGuo/GSYGithubApp ) * ### 同款Android Kotlin View版本( https://github.com/CarGuo/GSYGithubAppKotlin ) * ### 同款Android Compose版本( https://github.com/CarGuo/GSYGithubAppCompose ) * ### 简单 Flutter 独立学习项目 ( https://github.com/CarGuo/gsy_flutter_demo ) ## AI 协作与贡献入口 如果你希望用 AI 或更工程化的方式参与这个仓库,建议不要只看本 README,先看下面这些文档入口: - 总导航:`docs/CONTRIBUTING_AI.md` - 文档索引:`docs/README.md` - 项目地图:`docs/00-overview/project-map.md` - 分层边界:`docs/01-architecture/app-layering.md` - 状态管理边界:`docs/01-architecture/state-management-matrix.md` - 手工回归矩阵:`docs/04-quality/smoke-matrix.md` 按任务类型进入: - 修 Bug:`docs/05-ai/task-playbooks/fix-bug.md` - 新增页面:`docs/05-ai/task-playbooks/add-page.md` - 新增接口:`docs/05-ai/task-playbooks/add-api.md` - 状态整理:`docs/05-ai/task-playbooks/refactor-state.md` 按功能域进入: - 仓库详情:`docs/05-ai/feature-playbooks/repos-change.md` - 趋势页:`docs/05-ai/feature-playbooks/trend-change.md` - 通知页:`docs/05-ai/feature-playbooks/notify-change.md` - Issue:`docs/05-ai/feature-playbooks/issue-change.md` - 搜索:`docs/05-ai/feature-playbooks/search-change.md` - 用户页:`docs/05-ai/feature-playbooks/user-change.md` - 首页容器:`docs/05-ai/feature-playbooks/home-change.md` - 动态页:`docs/05-ai/feature-playbooks/dynamic-change.md` - Release:`docs/05-ai/feature-playbooks/release-change.md` - Push 提交详情:`docs/05-ai/feature-playbooks/push-change.md` - 调试页:`docs/05-ai/feature-playbooks/debug-change.md` 长期规则: - 状态管理收敛策略:`docs/06-decisions/ADR-0001-状态管理收敛策略.md` - 新增功能默认状态方案:`docs/06-decisions/ADR-0002-新增功能默认状态方案.md` Review harness: - author / reviewer 分离:`docs/05-ai/review-harness.md` - reviewer prompt:`docs/05-ai/prompts/reviewer-system.md` - review bundle 脚本(可选辅助):`tool/ai/build_review_bundle.ps1` ## 相关文章 | 公众号 | 掘金 | 知乎 | CSDN | 简书 |---------|---------|--------- |---------|---------| | GSYTech | [点我](https://juejin.cn/user/582aca2ba22b9d006b59ae68/posts) | [点我](https://www.zhihu.com/people/carguo) | [点我](https://blog.csdn.net/ZuoYueLiang) | [点我](https://www.jianshu.com/u/6e613846e1ea) - ### [Flutter系列文章专栏](https://juejin.cn/column/6960546078202527774) ---- - ### [Flutter 独立简单学习演示项目](https://github.com/CarGuo/gsy_flutter_demo) - ### [Flutter 完整开发实战详解 Gitbook 预览下载](https://github.com/CarGuo/gsy_flutter_book) - ### [所有运行问题请点击这里](https://github.com/CarGuo/gsy_github_app_flutter/issues/13) * ### GSY老书:[《Flutter开发实战详解》](https://item.jd.com/12883054.html)上架啦:[京东](https://item.jd.com/12883054.html) / [当当](http://product.dangdang.com/28558519.html) / 电子版[京东读书](https://e.jd.com/30624414.html)和[Kindle](https://www.amazon.cn/dp/B08BHQ4TKK/ref=sr_1_5?__mk_zh_CN=亚马逊网站&keywords=flutter&qid=1593498531&s=digital-text&sr=1-5) - ### [如果克隆太慢或者图片看不到,可尝试从码云地址下载](https://gitee.com/CarGuo/GSYGithubAppFlutter) ----- ## 须知 > **因为是偏学习展示项目,所以项目里会有各式各样的模式、库、UI等,请不要介意** > > 0、 全局状态管理目前有多种模式,包括 Provider、Redux、Riverpod 等 > > 1、 TrendPage : 目前采用纯 riverpod 状态管理,演示 > > 2、 Provider:目前在 RepositoryDetailPage 出使用 > > 3、 Redux:目前展示了全局登陆和用户信息等上面使用。 > > 4、 riverpod:目前用于管理全局灰度,多语言。 > > 5、 Repos 等请求展示了 graphQL > > 6、 Redux:目前展示了全局登陆和用户信息等上面使用。 > > 7、 Signals:目前用于 NotifyPage、RepositoryDetailFileListPage 页面内状态管理 > > **列表显示有多个,其中:** > > 1、**gsy_pull_load_widget.dart.dart** > `common_list_page.dart 等使用,搭配 gsy_list_state.dart 使用` > > 2、**gsy_pull_new_load_widget.dart.dart** > `dynamic_page.dart 等使用,搭配 gsy_bloc_list_state.dart 使用` > `有 iOS 和 Android 两种风格下拉风格支持` > > 3、**gsy_nested_pull_load_widget.dart** > `trend_page.dart 等使用,配置sliver 效果` ## 编译运行流程 1、配置好Flutter开发环境(目前Flutter SDK 版本 **3.38**),可参阅 [【搭建环境】](https://flutterchina.club)。 2、clone代码,执行`Packages get`安装第三方包。(因为某些不可抗力原因,国内可能需要设置代理: [代理环境变量](https://flutterchina.club/setup-windows/)) >### 3、重点:你需要自己在lib/common/config/目录下 创建一个`ignoreConfig.dart`文件,然后输入你申请的Github client_id 和 client_secret。 class NetConfig { static const CLIENT_ID = "xxxx"; static const CLIENT_SECRET = "xxxxxxxxxxx"; } [ 注册 Github APP 传送门](https://github.com/settings/applications/new),当然,前提是你现有一个github账号(~ ̄▽ ̄)~ 。 ### 4、如果使用安全登录(授权登录),那么在上述注册 Github App 的 Authorization callback URL 一栏必须填入 `gsygithubapp://authed`
### 框架
>当前 Flutter SDK 版本 3.38
```
用户交互 → UI层(Widget/Page) → 状态层(Redux/Provider/Riverpod) → 服务层(Repositories)
→ 网络层(Net) → GitHub API → 数据模型(Model) → 本地存储(DB) → UI更新
```
```
┌─────────────────────────────────────────────────────────────────┐
│ GSY GitHub App │
├─────────────┬───────────────┬────────────────┬─────────────────┤
│ UI Layer │ State Layer │ Service Layer │ Data Layer │
├─────────────┼───────────────┼────────────────┼─────────────────┤
│ │ │ │ │
│ ┌─────────┐│ ┌─────────┐ │ ┌─────────┐ │ ┌─────────┐ │
│ │ Pages ││ │ Redux │ │ │Repositories│ │ │ Models │ │
│ └─────────┘│ └─────────┘ │ └─────────┘ │ └─────────┘ │
│ │ │ │ │
│ ┌─────────┐│ ┌─────────┐ │ ┌─────────┐ │ ┌─────────┐ │
│ │ Widgets ││ │ Provider│ │ │Network API│ │ │Database │ │
│ └─────────┘│ └─────────┘ │ └─────────┘ │ └─────────┘ │
│ │ │ │ │
│ ┌─────────┐│ ┌─────────┐ │ │ │
│ │Common UI││ │Riverpod │ │ │ │
│ └─────────┘│ └─────────┘ │ │ │
│ │ │ │ │
│ │ ┌─────────┐ │ │ │
│ │ │ Signals │ │ │ │
│ │ └─────────┘ │ │ │
│ │ │ │ │
└─────────────┴───────────────┴────────────────┴─────────────────┘
```
```
lib/
├── main.dart # 应用入口点
├── main_prod.dart # 生产环境入口点
├── app.dart # 应用配置与路由
├── common/ # 公共功能模块
│ ├── config/ # 应用配置
│ ├── event/ # 事件总线
│ ├── local/ # 本地化
│ ├── localization/ # 多语言支持
│ ├── net/ # 网络请求
│ ├── repositories/ # 数据仓库
│ ├── router/ # 路由配置
│ ├── style/ # 样式配置
│ └── utils/ # 工具类
├── db/ # 数据库相关
│ ├── provider/ # 数据库提供者
│ ├── sql_manager.dart # SQL管理器
│ └── sql_provider.dart # SQL提供者
├── env/ # 环境配置
├── model/ # 数据模型
├── page/ # 页面
│ ├── debug/ # 调试页面
│ ├── dynamic/ # 动态页面
│ ├── home/ # 主页
│ ├── issue/ # Issue相关页面
│ ├── login/ # 登录页面
│ ├── push/ # 推送相关页面
│ ├── release/ # 发布相关页面
│ ├── repos/ # 仓库相关页面
│ ├── search/ # 搜索页面
│ ├── trend/ # 趋势页面
│ └── user/ # 用户相关页面
├── provider/ # Provider状态管理
├── redux/ # Redux状态管理
│ ├── middleware/ # Redux中间件
│ ├── gsy_state.dart # Redux状态定义
│ ├── login_redux.dart # 登录状态管理
│ └── user_redux.dart # 用户状态管理
├── test/ # 测试相关
└── widget/ # 自定义组件
├── anima/ # 动画组件
├── markdown/ # Markdown渲染组件
├── menu/ # 菜单组件
├── particle/ # 粒子效果组件
├── pull/ # 下拉刷新组件
└── state/ # 状态相关组件
```
riverpod 页面内状态管理:
```
┌───────────────────────────────────────────────────────────────────────────┐
│ Page Architecture Overview │
└───────────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────────────┐
│ Global State │
│ ┌───────────────────┐ ┌────────────────────┐ ┌────────────────────┐ │
│ │ appThemeProvider │ │ appLocalProvider │ │ appGrepProvider │ │
│ │ (Theme Data) │ │ (Localization) │ │ (Grayscale Mode) │ │
│ └───────────────────┘ └────────────────────┘ └────────────────────┘ │
└───────────────────────────────────────────────────────────────────────────┘
│
┌────────────────┴────────────────┐
▼ ▼
┌─────────────────────────────────┐ ┌─────────────────────────────────────┐
│ TrendPage (Riverpod) │ │ NotifyPage (Signals) │
├─────────────────────────────────┤ ├─────────────────────────────────────┤
│ │ │ │
│┌─────────────────────────────┐ │ │┌───────────────────────────────────┐│
││ Riverpod Providers │ │ ││ Signals State ││
││┌───────────────────────────┐│ │ ││┌─────────────────────────────────┐││
│││ trendFirstProvider ││ │ │││ notifySignal (List) │││
│││ trendSecondProvider ││ │ │││ notifyIndexSignal (int) │││
││└───────────────────────────┘│ │ │││ signalPage (int) │││
│└─────────────────────────────┘ │ ││└─────────────────────────────────┘││
│ │ │└───────────────────────────────────┘│
│┌─────────────────────────────┐ │ │┌───────────────────────────────────┐│
││ Local State (StatefulWidget)│ │ ││ SignalsMixin Processing ││
││ - UI Controls │ │ ││ - createEffect() for reactions ││
││ - Filter Parameters │ │ ││ - Manages data loading ││
│└─────────────────────────────┘ │ ││ - Updates UI based on signals ││
│ │ │└───────────────────────────────────┘│
└─────────────────────────────────┘ └─────────────────────────────────────┘
│ │
└────────────────┬────────────────┘
▼
┌───────────────────────────────────────────────────────────────────────────┐
│ Data Layer │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ ReposRepository / UserRepository │ │
│ │ ┌────────────────────────┐ ┌─────────────────────────────────┐ │ │
│ │ │ Network Request │───┬──▶│ Database Providers │ │ │
│ │ │ - API calls │ │ │ - Data caching │ │ │
│ │ └────────────────────────┘ │ └─────────────────────────────────┘ │ │
│ │ │ │ │
│ │ │ ┌─────────────────────────────────┐ │ │
│ │ └──▶│ Data Models │ │ │
│ │ │ - Structure definitions │ │ │
│ │ └─────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────────────┐
│ UI Components │
│ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐ │
│ │ View Models │ │ List Items │ │ Interactive UI │ │
│ │ - Data Formatting │ │ - Item Rendering │ │ - User Actions │ │
│ └────────────────────┘ └────────────────────┘ └────────────────────┘ │
└───────────────────────────────────────────────────────────────────────────┘
```
provider 页面内状态管理:
```
+-----------------------------------------------------+
| App User Interface |
+-----------------------------------------------------+
|
v
+-----------------------------------------------------+
| RepositoryDetailPage (StatefulWidget) |
| with SingleTickerProviderStateMixin |
+-----------------------------------------------------+
|
v
+-----------------------------------------------------+
| MultiProvider |
+-----------------------------------------------------+
| |
v v
+------------------+ +-----------------------+
| ReposNetWork |<----------| ReposDetailProvider |
| Provider | | |
+---------+--------+ +-----------------------+
| |
| |
v v
+-----------------------------------------------------+
| Repository Data Services |
| (ReposRepository, IssueRepository) |
+-----------------------------------------------------+
|
v
+-----------------------------------------------------+
| Four Tab Pages (Consumers) |
+-----------------------------------------------------+
| | | |
v v v v
+----------+ +----------+ +----------+ +----------+
| Info | | Readme | | Issues | | Files |
| Page | | Page | | Page | | Page |
+----------+ +----------+ +----------+ +----------+
| | | |
| | | |
v v v v
+-----------------------------------------------------+
| GlobalKeys for Tab Access |
| (infoListKey, readmeKey, issueListKey, fileListKey) |
+-----------------------------------------------------+
```




> 更多可见:https://codewiki.google/github.com/carguo/gsy_github_app_flutter
## Star History Chart
[](https://star-history.com/#CarGuo/gsy_github_app_flutter&Date)


### LICENSE
```
CarGuo/GSYGithubAppFlutter is licensed under the
Apache License 2.0
A permissive license whose main conditions require preservation of copyright and license notices.
Contributors provide an express grant of patent rights.
Licensed works, modifications, and larger works may be distributed under different terms and without source code.
```
================================================
FILE: README_EN.md
================================================

[](https://github.com/CarGuo/gsy_github_app_flutter/actions)
[](https://github.com/CarGuo/GSYGithubAppFlutter/stargazers)
[](https://github.com/CarGuo/GSYGithubAppFlutter/network)
[](https://github.com/CarGuo/GSYGithubAppFlutter/issues)
[](https://github.com/CarGuo/GSYGithubAppFlutter/blob/master/LICENSE)
[](https://gitcode.com/ZuoYueLiang/gsy_github_app_flutter)
### [Chinese Readme](https://github.com/CarGuo/GSYGithubAppFlutter/blob/master/README.md)
## A cross-platform open source Github client App, offering richer features and better experience. Designed for better daily management and maintenance of your personal Github account, providing a more convenient driving experience~~Σ( ̄。 ̄ノ)ノ. The project involves various common widgets, networking, databases, design patterns, theme switching, multi-language support, state management (Redux, Riverpod, Provider), and more. During the development and learning process, it provides rich comparisons with equivalent implementations:
* ### Same Weex version ( https://github.com/CarGuo/GSYGithubAppWeex )
* ### Same ReactNative version ( https://github.com/CarGuo/GSYGithubApp )
* ### Same Android Kotlin View version ( https://github.com/CarGuo/GSYGithubAppKotlin )
* ### Same Android Compose version ( https://github.com/CarGuo/GSYGithubAppCompose )
* ### Simple Flutter standalone learning project ( https://github.com/CarGuo/gsy_flutter_demo )
## Related Articles
- ## [Flutter Series Articles Column](https://juejin.cn/column/6960546078202527774)
----
- ## [Flutter Simple Learning Demo Project](https://github.com/CarGuo/gsy_flutter_demo)
- ## [Flutter Complete Development Practical Detailed Gitbook Preview Download](https://github.com/CarGuo/gsy_flutter_book)
- ## [For all running issues please click here](https://github.com/CarGuo/gsy_github_app_flutter/issues/13)
* ### GSY's old book: [《Flutter Development in Action》](https://item.jd.com/12883054.html) is available: [JD.com](https://item.jd.com/12883054.html) / [Dangdang](http://product.dangdang.com/28558519.html) / E-book [JD Reading](https://e.jd.com/30624414.html) and [Kindle](https://www.amazon.cn/dp/B08BHQ4TKK/ref=sr_1_5?__mk_zh_CN=亚马逊网站&keywords=flutter&qid=1593498531&s=digital-text&sr=1-5)
- ### [If cloning is too slow or if images don't display, you can try downloading from the Gitee address](https://gitee.com/CarGuo/GSYGithubAppFlutter)
-----
## Important Notes
> **Since this is primarily a learning and demonstration project, it includes various patterns, libraries, UIs, etc. Please don't mind the diversity**
>
> 0. Global state management currently has multiple modes, including Provider, Redux, Riverpod, etc.
>
> 1. TrendPage: Currently uses pure riverpod state management for demonstration
>
> 2. Provider: Currently used in RepositoryDetailPage
>
> 3. Redux: Currently demonstrated for global login and user information.
>
> 4. riverpod: Currently used to manage global grayscale and multi-language.
>
> 5. Repos and other requests demonstrate graphQL
>
> 6. Redux: Currently demonstrated for global login and user information.
>
> 7. Signals: Currently used for in-page state management in NotifyPage, RepositoryDetailFileListPage
>
> **There are multiple list displays, including:**
>
> 1. **gsy_pull_load_widget.dart.dart**
> `Used in common_list_page.dart, etc., paired with gsy_list_state.dart`
>
> 2. **gsy_pull_new_load_widget.dart.dart**
> `Used in dynamic_page.dart, etc., paired with gsy_bloc_list_state.dart`
> `Supports both iOS and Android pull-to-refresh styles`
>
> 3. **gsy_nested_pull_load_widget.dart**
> `Used in trend_page.dart, etc., configured with sliver effect`
## Compilation and Running Process
1. Set up the Flutter development environment (current Flutter SDK version **3.38**), see [Setting up the environment](https://flutterchina.club).
2. Clone the code, run `Packages get` to install third-party packages. (Due to certain reasons beyond control, you may need to set up a proxy in China: [Proxy environment variables](https://flutterchina.club/setup-windows/))
>### 3. Important: You need to create an `ignoreConfig.dart` file in the lib/common/config/ directory yourself, and then enter your registered Github client_id and client_secret.
class NetConfig {
static const CLIENT_ID = "xxxx";
static const CLIENT_SECRET = "xxxxxxxxxxx";
}
[ Register Github APP link](https://github.com/settings/applications/new), of course, the prerequisite is that you already have a github account (~ ̄▽ ̄)~.
### 4. If using secure login (authorization login), then in the above Github App registration, the Authorization callback URL field must be filled with `gsygithubapp://authed`
### Framework
>Current Flutter SDK version 3.38
```
User Interaction → UI Layer(Widget/Page) → State Layer(Redux/Provider/Riverpod) → Service Layer(Repositories)
→ Network Layer(Net) → GitHub API → Data Model(Model) → Local Storage(DB) → UI Update
```
```
┌─────────────────────────────────────────────────────────────────┐
│ GSY GitHub App │
├─────────────┬───────────────┬────────────────┬─────────────────┤
│ UI Layer │ State Layer │ Service Layer │ Data Layer │
├─────────────┼───────────────┼────────────────┼─────────────────┤
│ │ │ │ │
│ ┌─────────┐│ ┌─────────┐ │ ┌─────────┐ │ ┌─────────┐ │
│ │ Pages ││ │ Redux │ │ │Repositories│ │ │ Models │ │
│ └─────────┘│ └─────────┘ │ └─────────┘ │ └─────────┘ │
│ │ │ │ │
│ ┌─────────┐│ ┌─────────┐ │ ┌─────────┐ │ ┌─────────┐ │
│ │ Widgets ││ │ Provider│ │ │Network API│ │ │Database │ │
│ └─────────┘│ └─────────┘ │ └─────────┘ │ └─────────┘ │
│ │ │ │ │
│ ┌─────────┐│ ┌─────────┐ │ │ │
│ │Common UI││ │Riverpod │ │ │ │
│ └─────────┘│ └─────────┘ │ │ │
│ │ │ │ │
│ │ ┌─────────┐ │ │ │
│ │ │ Signals │ │ │ │
│ │ └─────────┘ │ │ │
│ │ │ │ │
└─────────────┴───────────────┴────────────────┴─────────────────┘
```
```
lib/
├── main.dart # Application entry point
├── main_prod.dart # Production environment entry point
├── app.dart # Application configuration and routing
├── common/ # Common functionality modules
│ ├── config/ # Application configuration
│ ├── event/ # Event bus
│ ├── local/ # Localization
│ ├── localization/ # Multi-language support
│ ├── net/ # Network requests
│ ├── repositories/ # Data repositories
│ ├── router/ # Routing configuration
│ ├── style/ # Style configuration
│ └── utils/ # Utility classes
├── db/ # Database related
│ ├── provider/ # Database providers
│ ├── sql_manager.dart # SQL manager
│ └── sql_provider.dart # SQL provider
├── env/ # Environment configuration
├── model/ # Data models
├── page/ # Pages
│ ├── debug/ # Debug pages
│ ├── dynamic/ # Dynamic pages
│ ├── home/ # Home page
│ ├── issue/ # Issue related pages
│ ├── login/ # Login page
│ ├── push/ # Push related pages
│ ├── release/ # Release related pages
│ ├── repos/ # Repository related pages
│ ├── search/ # Search page
│ ├── trend/ # Trend page
│ └── user/ # User related pages
├── provider/ # Provider state management
├── redux/ # Redux state management
│ ├── middleware/ # Redux middleware
│ ├── gsy_state.dart # Redux state definition
│ ├── login_redux.dart # Login state management
│ └── user_redux.dart # User state management
├── test/ # Test related
└── widget/ # Custom widgets
├── anima/ # Animation widgets
├── markdown/ # Markdown rendering widgets
├── menu/ # Menu widgets
├── particle/ # Particle effect widgets
├── pull/ # Pull-to-refresh widgets
└── state/ # State related widgets
```
Riverpod page state management:
```
┌───────────────────────────────────────────────────────────────────────────┐
│ Page Architecture Overview │
└───────────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────────────┐
│ Global State │
│ ┌───────────────────┐ ┌────────────────────┐ ┌────────────────────┐ │
│ │ appThemeProvider │ │ appLocalProvider │ │ appGrepProvider │ │
│ │ (Theme Data) │ │ (Localization) │ │ (Grayscale Mode) │ │
│ └───────────────────┘ └────────────────────┘ └────────────────────┘ │
└───────────────────────────────────────────────────────────────────────────┘
│
┌────────────────┴────────────────┐
▼ ▼
┌─────────────────────────────────┐ ┌─────────────────────────────────────┐
│ TrendPage (Riverpod) │ │ NotifyPage (Signals) │
├─────────────────────────────────┤ ├─────────────────────────────────────┤
│ │ │ │
│┌─────────────────────────────┐ │ │┌───────────────────────────────────┐│
││ Riverpod Providers │ │ ││ Signals State ││
││┌───────────────────────────┐│ │ ││┌─────────────────────────────────┐││
│││ trendFirstProvider ││ │ │││ notifySignal (List) │││
│││ trendSecondProvider ││ │ │││ notifyIndexSignal (int) │││
││└───────────────────────────┘│ │ │││ signalPage (int) │││
│└─────────────────────────────┘ │ ││└─────────────────────────────────┘││
│ │ │└───────────────────────────────────┘│
│┌─────────────────────────────┐ │ │┌───────────────────────────────────┐│
││ Local State (StatefulWidget)│ │ ││ SignalsMixin Processing ││
││ - UI Controls │ │ ││ - createEffect() for reactions ││
││ - Filter Parameters │ │ ││ - Manages data loading ││
│└─────────────────────────────┘ │ ││ - Updates UI based on signals ││
│ │ │└───────────────────────────────────┘│
└─────────────────────────────────┘ └─────────────────────────────────────┘
│ │
└────────────────┬────────────────┘
▼
┌───────────────────────────────────────────────────────────────────────────┐
│ Data Layer │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ ReposRepository / UserRepository │ │
│ │ ┌────────────────────────┐ ┌─────────────────────────────────┐ │ │
│ │ │ Network Request │───┬──▶│ Database Providers │ │ │
│ │ │ - API calls │ │ │ - Data caching │ │ │
│ │ └────────────────────────┘ │ └─────────────────────────────────┘ │ │
│ │ │ │ │
│ │ │ ┌─────────────────────────────────┐ │ │
│ │ └──▶│ Data Models │ │ │
│ │ │ - Structure definitions │ │ │
│ │ └─────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────────────┐
│ UI Components │
│ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐ │
│ │ View Models │ │ List Items │ │ Interactive UI │ │
│ │ - Data Formatting │ │ - Item Rendering │ │ - User Actions │ │
│ └────────────────────┘ └────────────────────┘ └────────────────────┘ │
└───────────────────────────────────────────────────────────────────────────┘
```
Provider page state management:
```
+-----------------------------------------------------+
| App User Interface |
+-----------------------------------------------------+
|
v
+-----------------------------------------------------+
| RepositoryDetailPage (StatefulWidget) |
| with SingleTickerProviderStateMixin |
+-----------------------------------------------------+
|
v
+-----------------------------------------------------+
| MultiProvider |
+-----------------------------------------------------+
| |
v v
+------------------+ +-----------------------+
| ReposNetWork |<----------| ReposDetailProvider |
| Provider | | |
+---------+--------+ +-----------------------+
| |
| |
v v
+-----------------------------------------------------+
| Repository Data Services |
| (ReposRepository, IssueRepository) |
+-----------------------------------------------------+
|
v
+-----------------------------------------------------+
| Four Tab Pages (Consumers) |
+-----------------------------------------------------+
| | | |
v v v v
+----------+ +----------+ +----------+ +----------+
| Info | | Readme | | Issues | | Files |
| Page | | Page | | Page | | Page |
+----------+ +----------+ +----------+ +----------+
| | | |
| | | |
v v v v
+-----------------------------------------------------+
| GlobalKeys for Tab Access |
| (infoListKey, readmeKey, issueListKey, fileListKey) |
+-----------------------------------------------------+
```




## Star History Chart
[](https://star-history.com/#CarGuo/gsy_github_app_flutter&Date)
### LICENSE
```
CarGuo/GSYGithubAppFlutter is licensed under the
Apache License 2.0
A permissive license whose main conditions require preservation of copyright and license notices.
Contributors provide an express grant of patent rights.
Licensed works, modifications, and larger works may be distributed under different terms and without source code.
```
================================================
FILE: RECORD.md
================================================
flutter build apk --target-platform android-arm64 -t lib/main_prod.dart --no-sound-null-safety
flutter packages pub run build_runner build --delete-conflicting-outputs
dart migrate --skip-import-check
flutter run --no-sound-null-safety
https://flutter.cn/docs/development/tools/devtools/cli http://localhost:9100
sudo gem install -n /usr/local/bin cocoapods -v 1.9.3
./gradlew :app:dependencies
AS 全局匹配中文搜索 ^((?!(\*|//)).)+[\u4e00-\u9fa5]
查看 framework 支持
1.进入到framework目录下
cd /Users/.../xFramework.framework
2.输入命令
lipo -info xFramework
-tag:gralloc4
# 如何查看dill文件
我们可以通过dart sdk中的vm package提供的dump_kernel.dart打印出dill的内部结构。
```
dart bin/dump_kernel.dart /Users/kylewong/Codes/AOP/aspectd/example/aop/build/app.dill /Users/kylewong/Codes/AOP/aspectd/example/aop/build/app.dill.txt
注意bin/dump_kernel.dart需要改成自己dart sdk中的具体路径。
```
///配置多渠道
flutter run --dart-define=CHANNEL=GSY --dart-define=LANGUAGE=Dart
const CHANNEL = String.fromEnvironment('CHANNEL');
const LANGUAGE = String.fromEnvironment('LANGUAGE');
query getUserDetail($name:String!){
user(login: $name) {
login,
avatarUrl,
company,
location,
bio,
email,
bioHTML,
websiteUrl,
viewerIsFollowing,
createdAt,
repositories(first: 100) {
totalCount,
nodes {
stargazers {
totalCount
}
}
}
followers {
totalCount
}
following {
totalCount
}
starredRepositories {
totalCount
}
isViewer,
#pinnedItems {
#
#}
organizations(first: 100) {
nodes {
login,
avatarUrl,
name
}
}
}
}
query GetStars($name: String!, $owner: String!, $after: String) {
repository(name: $name, owner: $owner) {
createdAt
stargazers(first: 100, after: $after) {
edges {
node {
id
login
name
avatarUrl
__typename
}
starredAt
__typename
}
pageInfo {
startCursor
endCursor
hasNextPage
__typename↵
}
totalCount
__typename
}
__typename
}
}
xxd /Users/xxxxxxx/workspace/flutter-wrok/flutter_app_test/.dart_tool/flutter_build/bf7ed8e7e7b3e64f28f0af8a89a29ca9/app.dill
dart dump_kernel.dart /Users/xxxxxxx/workspace/flutter-wrok/flutter_app_test/.dart_tool/flutter_build/bf7ed8e7e7b3e64f28f0af8a89a29ca9/app.dill /Users/xxxxxxx/workspace/flutter-wrok/flutter_app_test/.dart_tool/flutter_build/bf7ed8e7e7b3e64f28f0af8a89a29ca9/app.dill.txt
flutter pub deps 打印依赖
m1 mac pod install fail , gem install ffi -- --enable-libffi-alloc
iconv -f gbk -t utf8 1.txt > 1_utf.txt
AS 检索匹配中文
^((?!(\*|//)).)+[\u4e00-\u9fa5]
serve --ssl-key *.key --ssl-cert *.crt
获取崩溃日志
/// 清空
adb logcat -d *:W > crash.log
/// 输出
win 平台可以
adb logcat -d *:E | Select-String "com.shuyu.gsygithub.gsygithubappflutter" > crash.log
mac 可以
adb logcat -d *:E | grep "com.shuyu.gsygithub.gsygithubappflutter" > crash.log
获取更进准
flutter build web --no-web-resources-cdn
adb shell setprop log.tag.gralloc4 SILENT
"No uri found in code block"
clear your working set as it has become corrupt
================================================
FILE: UISCENE_PLUGIN_RISK.md
================================================
# UIScene Plugin Risk Checklist
- Project: `gsy_github_app_flutter`
- Generated on: 2026-02-13
- Scope: iOS plugins listed in `.flutter-plugins-dependencies`
- Method: static source scan for Scene lifecycle compatibility signals (`FlutterSceneLifeCycleDelegate`, `addSceneDelegate`, usage of `UIApplication.keyWindow` / `windows`, and AppDelegate lifecycle hooks).
## High Risk
### 1. `url_launcher_ios 6.3.6`
- Risk level: High
- Why:
- Uses deprecated window lookup via `UIApplication.shared.keyWindow`, which is scene-unaware.
- Evidence:
- `/Users/guoshuyu/.pub-cache/hosted/pub.dev/url_launcher_ios-6.3.6/ios/url_launcher_ios/Sources/url_launcher_ios/URLLauncherPlugin.swift:22`
- Impact:
- In multi-scene/iPad multi-window mode, in-app Safari presentation may target the wrong scene or fail to present.
### 2. `flutter_inappwebview_ios 1.1.2`
- Risk level: High
- Why:
- Multiple code paths still use `keyWindow` / `UIApplication.shared.windows`, which can be incorrect under multi-scene.
- Evidence:
- `/Users/guoshuyu/.pub-cache/hosted/pub.dev/flutter_inappwebview_ios-1.1.2/ios/Classes/HeadlessInAppWebView/HeadlessInAppWebView.swift:40`
- `/Users/guoshuyu/.pub-cache/hosted/pub.dev/flutter_inappwebview_ios-1.1.2/ios/Classes/UIApplication/VisibleViewController.swift:13`
- `/Users/guoshuyu/.pub-cache/hosted/pub.dev/flutter_inappwebview_ios-1.1.2/ios/Classes/WebAuthenticationSession/WebAuthenticationSession.swift:93`
- Impact:
- Headless WebView attach point, visible view-controller resolution, and web-auth presentation anchor may bind to the wrong window/scene.
## Medium Risk
### 1. `fluttertoast 8.2.10`
- Risk level: Medium
- Why:
- Chooses UI window via `UIApplication.sharedApplication.windows` and key-window iteration.
- Evidence:
- `/Users/guoshuyu/.pub-cache/hosted/pub.dev/fluttertoast-8.2.10/ios/Classes/FluttertoastPlugin.m:130`
- Impact:
- Toast may appear on a non-active scene window or behave inconsistently in multi-window mode.
## Low Risk
### 1. `share_plus 12.0.1`
- Risk level: Low
- Why:
- Uses `connectedScenes` and `UIWindowScene.windows` for root view-controller selection on iOS 13+.
- Evidence:
- `/Users/guoshuyu/.pub-cache/hosted/pub.dev/share_plus-12.0.1/ios/share_plus/Sources/share_plus/FPPSharePlusPlugin.m:12`
- Note:
- Keeps a fallback to `keyWindow` for iOS 12 and below (acceptable for non-scene OS versions).
### 2. Other installed iOS plugins in this repo
- `connectivity_plus 6.0.5`
- `device_info_plus 10.1.2`
- `package_info_plus 8.0.2`
- `path_provider_foundation 2.5.1`
- `permission_handler_apple 9.4.7`
- `rive_common 0.4.11`
- `shared_preferences_foundation 2.5.6`
- `sqflite 2.3.3+1`
- `webview_flutter_wkwebview 3.23.5`
Risk level: Low (for UIScene lifecycle migration)
- Why:
- No direct AppDelegate lifecycle hook usage (`addApplicationDelegate` / `openURL` callbacks / `continueUserActivity`) detected in plugin runtime source paths.
## Recommended Actions
1. Upgrade first:
- `url_launcher_ios`
- `flutter_inappwebview_ios`
- `fluttertoast`
2. Run targeted iPad multi-window validation:
- `url_launcher` in-app Safari presentation
- InAppWebView / headless webview attach
- Web auth session presentation anchor
- Toast display target window
- Share sheet presentation
3. If upgrade is blocked:
- Apply local patch to resolve active `UIWindowScene` and active window/VC instead of `keyWindow`/global `windows`.
================================================
FILE: VERSION.md
================================================
### 请直接看 github release
### 1.1.9
* 修正弹出键盘的时候被挤压问题
* 修复切换主题导致长按输入框弹出异常
* 修复其他小问题。
### 1.1.8
* 修复反馈输入框遮挡问题。
* 更新部分插件,更新了 sdk 到 1.1.9
### 1.1.7
* 更新flutter SDK 到 1.1.3 版本,修复TargetSDK 28以上在9.0键盘无法弹出问题。
### 1.1.6
* flutter升级正式版1.0
### 1.1.5
* Android 代码详情使用 AndroidView 实现WebView
* 升级flutter Sdk
* 升级第三方包
### 1.1.3
* 修复详情tab切换问题。
### 1.1.2
* 增加滑动返回。
* 修复主页抽屉小屏幕无法滚动。
* 增加部分代码高亮。
* 修复搜索排序按键问题。
* 更新flutter SDK
### 1.1.1
* 更新flutter SDK 0.5.8。
* 修复一些仓库下的readme问题。
### 1.1.0
* 切换用户切换数据库。
* 多语言。
### 1.0.9
* 切换主题支持
* 问题修复
### 1.0.8
* readme图片解析优化
* readme图片增加点击查看
* 组织账号不显示活跃记录Item
* 增加用户组织显示
### 1.0.7
* 增加图片预览
* 修复未读的通知打开提示其他异常
* 增加fork仓库跳转到原仓库
* 增加仓库点击展示 issue 状态信息
* 增加个人状态信息可跳转
* 增加仓库Topic显示
* 通知中心增加侧滑点击已读
### 1.0.6
* trend修改为redux
* 增加本地阅读历史
* drawer 状态栏样式处理
* 增加个人动态提交表。
### 1.0.5
* 增加本地数据库
* 修复分享问题。
* 修改用户页面样式
* 增加用户加入github时间显示
### 1.0.4
* 修复启动页变形问题。
* 调整个人页面字体动态大小。
* 增加趋势语言,搜索语言dart选项。
* 增加前后台切换刷新动态。
* 增加触摸隐藏键盘。
* 增加点击检测版本。
* 增加 issue 使用markdown解析
* 增加 issue 输入框的快速输入按键。
* 增加 issue 关闭操作信息。
* 返回文件列表的返回键处理逻辑。
* 修复详情中存在的model转化问题。
### 1.0.1 (已发布)
* 修复loading弹出框黄线问题。
* 调整部分ui。
* 增加Release列表。
* 增加版检测。
* Issue详情页显示问题。
* 返回按键退出问题。
### 1.0.0
* 第一版完成
================================================
FILE: analysis_options.yaml
================================================
include: package:flutter_lints/flutter.yaml
analyzer:
errors:
mixin_inherits_from_not_object: ignore
plugins:
- custom_lint
linter:
rules:
non_constant_identifier_names: false
file_names: false
constant_identifier_names: false
library_private_types_in_public_api: false
library_prefixes: false
================================================
FILE: android/.gitignore
================================================
*.iml
*.class
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
GeneratedPluginRegistrant.java
.cxx/
================================================
FILE: android/app/build.gradle
================================================
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
apply from: "exported.gradle"
android {
namespace "com.shuyu.gsygithub.gsygithubappflutter"
compileSdkVersion 36
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lint {
disable += 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.shuyu.gsygithub.gsygithubappflutter"
minSdkVersion flutter.minSdkVersion
targetSdkVersion 35
versionCode 69
versionName "7.9.3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
signingConfigs {
debug {
storeFile file("../gsygithubapp-debug.jks")
storePassword "123456"
keyAlias "debug"
keyPassword "123456"
}
release {
storeFile file("../gsygithubapp-debug.jks")
storePassword "123456"
keyAlias "debug"
keyPassword "123456"
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
signingConfig signingConfigs.release
}
}
lint {
abortOnError = false
}
dependenciesInfo {
// Disables dependency metadata when building APKs.
includeInApk = false
// Disables dependency metadata when building Android App Bundles.
includeInBundle = false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '17'
}
configurations.all {
resolutionStrategy {
///为了 https://github.com/pichillilorenzo/flutter_inappwebview/issues/2150
///force 'androidx.webkit:webkit:1.8.0'
///为了 Failed to transform appcompat-resources-1.7.0.aar
///这玩意导致的 Failed to transform appcompat-resources-1.7.0.aar Cannot invoke "String.length()" because "The purpose of the project is to facilitate personal daily maintenance and access to Github, better immerse in the mutual base between coders, Github is your home.
================================================ FILE: fastlane/metadata/android/en-US/short_description.txt ================================================ Third-party Github App ================================================ FILE: ios/.gitignore ================================================ .idea/ .vagrant/ .sconsign.dblite .svn/ .DS_Store *.swp profile DerivedData/ build/ GeneratedPluginRegistrant.h GeneratedPluginRegistrant.m .generated/ *.pbxuser *.mode1v3 *.mode2v3 *.perspectivev3 !default.pbxuser !default.mode1v3 !default.mode2v3 !default.perspectivev3 xcuserdata *.moved-aside *.pyc *sync/ Icon? .tags* /Flutter/app.flx /Flutter/app.zip /Flutter/flutter_assets/ /Flutter/App.framework /Flutter/Flutter.framework /Flutter/Generated.xcconfig /Flutter/Flutter.podspec /ServiceDefinitions.json Pods/ .symlinks/ ================================================ FILE: ios/Flutter/AppFrameworkInfo.plist ================================================