├── .gitignore ├── .metadata ├── .vscode └── launch.json ├── LICENSE ├── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── all_univers │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-hdpi │ │ │ └── ic_launcher_foreground.png │ │ │ ├── drawable-mdpi │ │ │ └── ic_launcher_foreground.png │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── drawable-xhdpi │ │ │ └── ic_launcher_foreground.png │ │ │ ├── drawable-xxhdpi │ │ │ └── ic_launcher_foreground.png │ │ │ ├── drawable-xxxhdpi │ │ │ └── ic_launcher_foreground.png │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ └── ic_launcher.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── 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 │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-50x50@1x.png │ │ ├── Icon-App-50x50@2x.png │ │ ├── Icon-App-57x57@1x.png │ │ ├── Icon-App-57x57@2x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-72x72@1x.png │ │ ├── Icon-App-72x72@2x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ └── Icon-App-83.5x83.5@2x.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h ├── lib ├── assets │ ├── fonts │ │ ├── barlow-medium.ttf │ │ └── caveat-medium.ttf │ ├── images │ │ ├── common │ │ │ ├── jiazaizhong.png │ │ │ ├── logo.png │ │ │ ├── logo2.png │ │ │ └── logo2.webp │ │ ├── cover │ │ │ ├── 1L.webp │ │ │ ├── 1N.webp │ │ │ ├── hG.webp │ │ │ ├── hL.webp │ │ │ ├── hY.webp │ │ │ ├── hZ.webp │ │ │ ├── hh.webp │ │ │ ├── lL.webp │ │ │ ├── lM.webp │ │ │ ├── wK.webp │ │ │ ├── wN.webp │ │ │ ├── wc.webp │ │ │ ├── wf.webp │ │ │ ├── wh.webp │ │ │ ├── wi.webp │ │ │ └── wu.webp │ │ ├── home │ │ │ └── xn.webp │ │ ├── player │ │ │ ├── player.webp │ │ │ └── suspend.webp │ │ └── tabbar │ │ │ ├── cover1.webp │ │ │ ├── cover2.webp │ │ │ ├── egg.webp │ │ │ ├── toolbar1.webp │ │ │ ├── toolbar1_active.webp │ │ │ ├── toolbar2.webp │ │ │ ├── toolbar2_active.webp │ │ │ ├── toolbar3.webp │ │ │ └── toolbar3_active.webp │ └── lottie │ │ ├── big_heart.json │ │ ├── giftcard.json │ │ ├── like_animation.lottie │ │ ├── like_guide.json │ │ ├── lottie_comment_like.json │ │ ├── lottie_discover_header_animation.json │ │ ├── lottie_episode_star.json │ │ ├── lottie_global_loading.json │ │ ├── lottie_inbox_filter_star_guide.json │ │ ├── lottie_inbox_filter_star_guide_full.json │ │ ├── lottie_inbox_maybe_loss_tip.json │ │ ├── lottie_list_pull_refresh.json │ │ ├── lottie_listen_stats_header_bg.json │ │ ├── lottie_listen_stats_spacecraft.json │ │ ├── lottie_pay_podcast_purchase_success.json │ │ ├── lottie_play_bar_loading.json │ │ ├── lottie_player_page_forward.json │ │ ├── lottie_player_page_like.json │ │ ├── lottie_player_page_like_button.json │ │ ├── lottie_player_page_loading.json │ │ ├── lottie_player_page_play_pause.json │ │ ├── lottie_player_page_rewind.json │ │ ├── lottie_player_page_setting.json │ │ ├── lottie_pod_recom_subscribe.json │ │ ├── lottie_podcast_push_switch.json │ │ ├── lottie_single_episode_loading.json │ │ ├── lottie_widget_guide.json │ │ ├── more_likes.json │ │ ├── move_to_top.json │ │ ├── playlist_syncing.json │ │ ├── single_episode_new_star.json │ │ ├── slide_add_to_playlist_last.json │ │ ├── slide_add_to_playlist_top.json │ │ ├── slide_guide.json │ │ ├── slide_remove.json │ │ ├── slide_to_star.json │ │ ├── slide_to_top.json │ │ └── slide_to_unstar.json ├── common │ ├── colors │ │ └── colors.dart │ ├── langs │ │ ├── en_US.dart │ │ ├── translation_service.dart │ │ └── zh_Hans.dart │ ├── size_config.dart │ └── values │ │ ├── cache.dart │ │ ├── enum.dart │ │ ├── storage.dart │ │ └── values.dart ├── components │ ├── cahenetwork_image.dart │ ├── components.dart │ ├── custom_appbar.dart │ ├── custom_like.dart │ ├── custom_loading.dart │ ├── custom_more.dart │ ├── custom_scaffold.dart │ ├── custom_scroll_physics.dart │ ├── custom_share.dart │ ├── custom_sub.dart │ ├── custom_title.dart │ ├── no_splash_factory.dart │ └── play_btn.dart ├── config.dart ├── env.dart ├── global.dart ├── main.dart ├── model │ ├── api_response.dart │ ├── play.dart │ ├── podcast.dart │ ├── podcast_detail.dart │ └── user.dart ├── pages │ ├── Index │ │ ├── Index_controller.dart │ │ ├── Index_view.dart │ │ └── index_binding.dart │ ├── details │ │ ├── details_binding.dart │ │ ├── details_controller.dart │ │ ├── details_state.dart │ │ ├── details_view.dart │ │ └── widgets │ │ │ ├── after_appbar.dart │ │ │ ├── before_appbar.dart │ │ │ └── recommend_item.dart │ ├── home │ │ ├── home_binding.dart │ │ ├── home_controller.dart │ │ ├── home_state.dart │ │ ├── home_view.dart │ │ └── widgets │ │ │ ├── edit_selection.dart │ │ │ ├── edit_selection_item.dart │ │ │ ├── fraternity.dart │ │ │ ├── hot.dart │ │ │ ├── more_btn.dart │ │ │ ├── podcast_item.dart │ │ │ ├── recommend.dart │ │ │ ├── search_bar.dart │ │ │ ├── ta_like.dart │ │ │ └── treasure_hunt.dart │ ├── login │ │ ├── login_binding.dart │ │ ├── login_controller.dart │ │ ├── login_state.dart │ │ └── login_view.dart │ ├── notfound │ │ └── notfound_view.dart │ ├── personal │ │ ├── personal_binding.dart │ │ ├── personal_controller.dart │ │ ├── personal_state.dart │ │ └── personal_view.dart │ ├── play │ │ ├── bottom_play_bar_view.dart │ │ ├── play_binding.dart │ │ ├── play_controller.dart │ │ ├── play_list_view.dart │ │ ├── play_state.dart │ │ ├── play_view.dart │ │ └── widgets │ │ │ ├── play_list_btn.dart │ │ │ └── play_progress.dart │ ├── proxy │ │ └── proxy_view.dart │ ├── splash │ │ ├── spalsh_view.dart │ │ ├── splash_controller.dart │ │ ├── splash_state.dart │ │ └── widgets │ │ │ └── animation_img_box.dart │ ├── subscription │ │ ├── subscription_binding.dart │ │ ├── subscription_controller.dart │ │ ├── subscription_state.dart │ │ ├── subscription_view.dart │ │ └── widgets │ │ │ └── sub_list.dart │ ├── tabbar │ │ ├── tabbar_binding.dart │ │ ├── tabbar_controller.dart │ │ ├── tabbar_state.dart │ │ └── tabbar_view.dart │ ├── test │ │ └── test_screen.dart │ └── webview │ │ └── browser.dart ├── router │ ├── app_pages.dart │ └── app_routes.dart ├── services │ ├── audio_handler.dart │ ├── home.dart │ ├── service_locator.dart │ ├── services.dart │ └── user.dart └── utils │ ├── authentication.dart │ ├── common.dart │ ├── local_storage.dart │ ├── request.dart │ ├── screen_device.dart │ └── utils.dart ├── linux ├── .gitignore ├── CMakeLists.txt ├── flutter │ ├── CMakeLists.txt │ ├── generated_plugin_registrant.cc │ ├── generated_plugin_registrant.h │ └── generated_plugins.cmake ├── main.cc ├── my_application.cc └── my_application.h ├── macos ├── .gitignore ├── Flutter │ ├── Flutter-Debug.xcconfig │ ├── Flutter-Release.xcconfig │ └── GeneratedPluginRegistrant.swift ├── 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 │ │ ├── Contents.json │ │ ├── app_icon_1024.png │ │ ├── app_icon_128.png │ │ ├── app_icon_16.png │ │ ├── app_icon_256.png │ │ ├── app_icon_32.png │ │ ├── app_icon_512.png │ │ └── app_icon_64.png │ ├── Base.lproj │ └── MainMenu.xib │ ├── Configs │ ├── AppInfo.xcconfig │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── Warnings.xcconfig │ ├── DebugProfile.entitlements │ ├── Info.plist │ ├── MainFlutterWindow.swift │ └── Release.entitlements ├── memo.md ├── pubspec.lock ├── pubspec.yaml ├── screenshots ├── sc.png ├── sc1.png ├── sc10.png ├── sc11.png ├── sc2.png ├── sc3.png ├── sc4.png ├── sc5.png ├── sc6.png ├── sc7.png ├── sc8.png └── sc9.png ├── 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 └── windows ├── .gitignore ├── CMakeLists.txt ├── flutter ├── CMakeLists.txt ├── generated_plugin_registrant.cc ├── generated_plugin_registrant.h └── generated_plugins.cmake └── 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 /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Symbolication related 36 | app.*.symbols 37 | 38 | # Obfuscation related 39 | app.*.map.json 40 | 41 | # Android Studio will place build artifacts here 42 | /android/app/debug 43 | /android/app/profile 44 | /android/app/release 45 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled. 5 | 6 | version: 7 | revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 17 | base_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 18 | - platform: android 19 | create_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 20 | base_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 21 | - platform: ios 22 | create_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 23 | base_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 24 | - platform: linux 25 | create_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 26 | base_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 27 | - platform: macos 28 | create_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 29 | base_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 30 | - platform: web 31 | create_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 32 | base_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 33 | - platform: windows 34 | create_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 35 | base_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4 36 | 37 | # User provided section 38 | 39 | # List of Local paths (relative to this file) that should be 40 | # ignored by the migrate tool. 41 | # 42 | # Files that are not part of the templates will be ignored by default. 43 | unmanaged_files: 44 | - 'lib/main.dart' 45 | - 'ios/Runner.xcodeproj/project.pbxproj' 46 | -------------------------------------------------------------------------------- /.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": "all-universe-flutter", 9 | "request": "launch", 10 | "type": "dart" 11 | }, 12 | { 13 | "name": "all-universe-flutter (profile mode)", 14 | "request": "launch", 15 | "type": "dart", 16 | "flutterMode": "profile" 17 | }, 18 | { 19 | "name": "all-universe-flutter (release mode)", 20 | "request": "launch", 21 | "type": "dart", 22 | "flutterMode": "release" 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🪐大宇宙 Flutter 我在尝试优化并写个文章。。。。。 2 | 3 | 🚩 Flutter 模仿[小宇宙App](https://www.plutopod.com/) 练习项目,调用真实云端mock接口 [mock 地址](https://www.apifox.cn/apidoc/shared-343f119d-0318-425f-ba64-d2a291136766/api-66526781) 4 | 5 | 🚩 本项目并非从头构建cli的项目,注重的业务的实现。(下面的学习之路,或许对您有所帮助) 6 | 7 | 🚩 注意 mock 随便写的,这不是本项目练习的重点(所以图片或者音频资源可能失效,自己更改mock脚本即可)。 8 |
9 | 10 | ## 🌱目标 11 |
12 | 13 | - ✅登录页 14 | - ✅首页 15 | - ✅播放页面 (可播放) 16 | - ✅详情页面 17 | - ✅订阅页面 18 | - ✅个人页面(头像可拖动) 19 | - ❌开屏页面 20 | - ❌其他页(都是无脑滚键盘了,和上面页面差距不大,看请况吧😂😂😂) 21 | - ❌10个Star⭐(2/10) 22 |
23 | 24 | ## 🌳完成页面 25 | 26 |
27 | 28 |
29 | 30 |

31 | Gallery Image 32 | Gallery Image 33 | Gallery Image 34 | Gallery Image 35 | Gallery Image 36 | Gallery Image 37 | Gallery Image 38 | Gallery Image 39 | Gallery Image 40 | Gallery Image 41 | Gallery Image 42 | Gallery Image 43 |

44 | 45 | ## 🌻学习参考 46 |
47 | 48 | - [Flutter 官网](https://flutter.cn) 英语好的,看官方最好。 49 | - [老孟 Flutter](http://www.laomengit.com/) 英语不好,可以看这个 主要快速查询方便。 50 | - [Flutter实战·第二版](https://book.flutterchina.club/chapter6/tabview.html#_6-9-1-tabbarview) 英语不好,可以看这个 主要快速查询方便。 51 | - [👍👍👍FlutterUnit](https://github.com/toly1994328/FlutterUnit) flutter组件效果预览App 主页有下载地址,非常推荐初学者安装,没事打开滑一滑。 52 | - [bili_you](https://github.com/lucinhu/bili_you) 仿bilbil项目 53 | 54 | - [王叔不秃Flutter教程](https://www.bilibili.com/video/BV1dt4y117J9/?spm_id_from=333.788&vd_source=009060b038d734b4de0f2c3ccf982d98) 需要有点基础看,应该是b站最好的flutter教学。 55 | - [Flutter GetX使用---简洁的魅力!](https://juejin.cn/post/6924104248275763208) 56 | - [Flutter之GetX依赖注入Bindings使用详解](https://juejin.cn/post/7062516045130498084) 57 | - [后台播放音频](https://github.com/ryanheise/just_audio/blob/minor/just_audio_background/example/lib/main.dart) 58 | ### 工具 ### 59 | - [脚手架 注意阅读Readme](https://github.com/xieyezi/flutter-getx-template) 60 | - [vscode 插件](https://marketplace.visualstudio.com/items?itemName=xieyezi.monia-getx-template) 脚手架作者写的,用于快速创建页面 61 | - [json数据格式化Map网站](https://app.quicktype.io/) 62 | ### 推荐作者 ### 63 | - [张风捷特烈](https://juejin.cn/user/149189281194766) 64 | - [恋猫de小郭](https://juejin.cn/user/817692379985752) 65 | - ~~[优弧](https://juejin.cn/user/852876722177533)不需要~~ 66 | - [北海道浪子](https://juejin.cn/user/729731450022440) 67 | - [小呆呆666](https://juejin.cn/user/2840793776393847) 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /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/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 33 30 | ndkVersion flutter.ndkVersion 31 | 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_8 34 | targetCompatibility JavaVersion.VERSION_1_8 35 | } 36 | 37 | kotlinOptions { 38 | jvmTarget = '1.8' 39 | } 40 | 41 | sourceSets { 42 | main.java.srcDirs += 'src/main/kotlin' 43 | } 44 | 45 | defaultConfig { 46 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 47 | applicationId "com.example.all_univers" 48 | // You can update the following values to match your application needs. 49 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. 50 | minSdkVersion 21 51 | targetSdkVersion flutter.targetSdkVersion 52 | versionCode flutterVersionCode.toInteger() 53 | versionName flutterVersionName 54 | } 55 | 56 | buildTypes { 57 | release { 58 | // TODO: Add your own signing config for the release build. 59 | // Signing with the debug keys for now, so `flutter run --release` works. 60 | signingConfig signingConfigs.debug 61 | } 62 | } 63 | } 64 | 65 | flutter { 66 | source '../..' 67 | } 68 | 69 | dependencies { 70 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 71 | } 72 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | 22 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 40 | 45 | 46 | 47 | 48 | 49 | 50 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/all_univers/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.all_univers 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /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 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.6.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.1.2' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip 6 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /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/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '11.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.generated_projects.each do |project| 39 | project.targets.each do |target| 40 | target.build_configurations.each do |config| 41 | config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' 42 | target.build_configurations.each do |config| 43 | config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ 44 | '$(inherited)', 45 | 'AUDIO_SESSION_MICROPHONE=0' 46 | ] 47 | end 48 | end 49 | end 50 | end 51 | installer.pods_project.targets.each do |target| 52 | flutter_additional_ios_build_settings(target) 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - audio_service (0.0.1): 3 | - Flutter 4 | - audio_session (0.0.1): 5 | - Flutter 6 | - Flutter (1.0.0) 7 | - FMDB (2.7.5): 8 | - FMDB/standard (= 2.7.5) 9 | - FMDB/standard (2.7.5) 10 | - image_gallery_saver (1.5.0): 11 | - Flutter 12 | - image_picker (0.0.1): 13 | - Flutter 14 | - just_audio (0.0.1): 15 | - Flutter 16 | - path_provider_foundation (0.0.1): 17 | - Flutter 18 | - FlutterMacOS 19 | - "permission_handler (5.1.0+2)": 20 | - Flutter 21 | - shared_preferences_foundation (0.0.1): 22 | - Flutter 23 | - FlutterMacOS 24 | - sqflite (0.0.2): 25 | - Flutter 26 | - FMDB (>= 2.7.5) 27 | - vibration (1.7.5): 28 | - Flutter 29 | - webview_flutter_wkwebview (0.0.1): 30 | - Flutter 31 | 32 | DEPENDENCIES: 33 | - audio_service (from `.symlinks/plugins/audio_service/ios`) 34 | - audio_session (from `.symlinks/plugins/audio_session/ios`) 35 | - Flutter (from `Flutter`) 36 | - image_gallery_saver (from `.symlinks/plugins/image_gallery_saver/ios`) 37 | - image_picker (from `.symlinks/plugins/image_picker/ios`) 38 | - just_audio (from `.symlinks/plugins/just_audio/ios`) 39 | - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) 40 | - permission_handler (from `.symlinks/plugins/permission_handler/ios`) 41 | - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`) 42 | - sqflite (from `.symlinks/plugins/sqflite/ios`) 43 | - vibration (from `.symlinks/plugins/vibration/ios`) 44 | - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) 45 | 46 | SPEC REPOS: 47 | trunk: 48 | - FMDB 49 | 50 | EXTERNAL SOURCES: 51 | audio_service: 52 | :path: ".symlinks/plugins/audio_service/ios" 53 | audio_session: 54 | :path: ".symlinks/plugins/audio_session/ios" 55 | Flutter: 56 | :path: Flutter 57 | image_gallery_saver: 58 | :path: ".symlinks/plugins/image_gallery_saver/ios" 59 | image_picker: 60 | :path: ".symlinks/plugins/image_picker/ios" 61 | just_audio: 62 | :path: ".symlinks/plugins/just_audio/ios" 63 | path_provider_foundation: 64 | :path: ".symlinks/plugins/path_provider_foundation/ios" 65 | permission_handler: 66 | :path: ".symlinks/plugins/permission_handler/ios" 67 | shared_preferences_foundation: 68 | :path: ".symlinks/plugins/shared_preferences_foundation/ios" 69 | sqflite: 70 | :path: ".symlinks/plugins/sqflite/ios" 71 | vibration: 72 | :path: ".symlinks/plugins/vibration/ios" 73 | webview_flutter_wkwebview: 74 | :path: ".symlinks/plugins/webview_flutter_wkwebview/ios" 75 | 76 | SPEC CHECKSUMS: 77 | audio_service: f509d65da41b9521a61f1c404dd58651f265a567 78 | audio_session: 4f3e461722055d21515cf3261b64c973c062f345 79 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 80 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a 81 | image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2 82 | image_picker: 50e7c7ff960e5f58faa4d1f4af84a771c671bc4a 83 | just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa 84 | path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 85 | permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0 86 | shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472 87 | sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 88 | vibration: 7d883d141656a1c1a6d8d238616b2042a51a1241 89 | webview_flutter_wkwebview: 2e2d318f21a5e036e2c3f26171342e95908bd60a 90 | 91 | PODFILE CHECKSUM: 7e0f44c2569118dfe5bb4c205ce834f8885af941 92 | 93 | COCOAPODS: 1.11.3 94 | -------------------------------------------------------------------------------- /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.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /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 UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@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/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | 大宇宙 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | 大宇宙 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | CADisableMinimumFrameDurationOnPhone 47 | 48 | UIApplicationSupportsIndirectInputEvents 49 | 50 | UIBackgroundModes 51 | 52 | audio 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /lib/assets/fonts/barlow-medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/fonts/barlow-medium.ttf -------------------------------------------------------------------------------- /lib/assets/fonts/caveat-medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/fonts/caveat-medium.ttf -------------------------------------------------------------------------------- /lib/assets/images/common/jiazaizhong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/common/jiazaizhong.png -------------------------------------------------------------------------------- /lib/assets/images/common/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/common/logo.png -------------------------------------------------------------------------------- /lib/assets/images/common/logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/common/logo2.png -------------------------------------------------------------------------------- /lib/assets/images/common/logo2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/common/logo2.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/1L.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/1L.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/1N.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/1N.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/hG.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/hG.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/hL.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/hL.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/hY.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/hY.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/hZ.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/hZ.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/hh.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/hh.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/lL.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/lL.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/lM.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/lM.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/wK.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/wK.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/wN.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/wN.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/wc.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/wc.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/wf.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/wf.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/wh.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/wh.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/wi.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/wi.webp -------------------------------------------------------------------------------- /lib/assets/images/cover/wu.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/cover/wu.webp -------------------------------------------------------------------------------- /lib/assets/images/home/xn.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/home/xn.webp -------------------------------------------------------------------------------- /lib/assets/images/player/player.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/player/player.webp -------------------------------------------------------------------------------- /lib/assets/images/player/suspend.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/player/suspend.webp -------------------------------------------------------------------------------- /lib/assets/images/tabbar/cover1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/tabbar/cover1.webp -------------------------------------------------------------------------------- /lib/assets/images/tabbar/cover2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/tabbar/cover2.webp -------------------------------------------------------------------------------- /lib/assets/images/tabbar/egg.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/tabbar/egg.webp -------------------------------------------------------------------------------- /lib/assets/images/tabbar/toolbar1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/tabbar/toolbar1.webp -------------------------------------------------------------------------------- /lib/assets/images/tabbar/toolbar1_active.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/tabbar/toolbar1_active.webp -------------------------------------------------------------------------------- /lib/assets/images/tabbar/toolbar2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/tabbar/toolbar2.webp -------------------------------------------------------------------------------- /lib/assets/images/tabbar/toolbar2_active.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/tabbar/toolbar2_active.webp -------------------------------------------------------------------------------- /lib/assets/images/tabbar/toolbar3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/tabbar/toolbar3.webp -------------------------------------------------------------------------------- /lib/assets/images/tabbar/toolbar3_active.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/images/tabbar/toolbar3_active.webp -------------------------------------------------------------------------------- /lib/assets/lottie/like_animation.lottie: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/lib/assets/lottie/like_animation.lottie -------------------------------------------------------------------------------- /lib/assets/lottie/lottie_play_bar_loading.json: -------------------------------------------------------------------------------- 1 | {"v":"5.6.4","fr":60,"ip":0,"op":155,"w":40,"h":40,"nm":"ic_playbar_loading","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"ic_playbar_loading Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.41],"y":[1]},"o":{"x":[0.59],"y":[0]},"t":0,"s":[0]},{"t":105,"s":[352]}],"ix":10},"p":{"a":0,"k":[20,20,0],"ix":2},"a":{"a":0,"k":[20,20,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-9.941,0],[0,-9.941],[9.941,0],[0,9.941]],"o":[[9.941,0],[0,9.941],[-9.941,0],[0,-9.941]],"v":[[0,-18],[18,0],[0,18],[-18,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.145098045468,0.705882370472,0.882352948189,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.5,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[20,20],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.487],"y":[0.878]},"o":{"x":[0.982],"y":[0]},"t":17,"s":[0]},{"t":105,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.402],"y":[1]},"o":{"x":[0.751],"y":[0]},"t":0,"s":[0]},{"t":83,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":155,"st":0,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /lib/assets/lottie/lottie_player_page_like_button.json: -------------------------------------------------------------------------------- 1 | {"v":"5.6.4","fr":60,"ip":0,"op":40,"w":46,"h":46,"nm":"upvote_button","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":2,"ty":4,"nm":"thumbsUp","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.328],"y":[0]},"t":0,"s":[40]},{"i":{"x":[0],"y":[1]},"o":{"x":[1],"y":[0]},"t":4,"s":[65]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[1],"y":[0]},"t":16,"s":[65]},{"t":26,"s":[40]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.404],"y":[1]},"o":{"x":[0.169],"y":[0.83]},"t":0,"s":[0]},{"i":{"x":[0.368],"y":[1]},"o":{"x":[0.308],"y":[0]},"t":13,"s":[-21]},{"t":40,"s":[0]}],"ix":10},"p":{"a":0,"k":[22.681,22.607,0],"ix":2},"a":{"a":0,"k":[22.681,22.607,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.238,0.238,0],"y":[1,1,1]},"o":{"x":[0.046,0.046,0.328],"y":[0.405,0.405,0]},"t":0,"s":[110,110,100]},{"i":{"x":[0.387,0.387,0.5],"y":[1,1,1]},"o":{"x":[0.357,0.357,1],"y":[0,0,0]},"t":13,"s":[124,124,100]},{"t":40,"s":[110,110,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.25,"y":1},"o":{"x":0.665,"y":0},"t":0,"s":[{"i":[[0.62,-1.062],[0,0],[0,0],[0,0],[-0.183,0.94],[0,0],[1.886,0],[0,0],[0,2.393],[1.484,0.142]],"o":[[-0.769,2.514],[0,0],[0,0],[0.958,0],[0,0],[0.359,-1.852],[0,0],[0,0],[-0.218,-1.701],[-1.383,-0.132]],"v":[[-6.251,-8.749],[-8.083,-2.448],[-8.083,10.952],[4.018,10.952],[5.982,9.333],[7.724,0.351],[4.78,-3.221],[-0.583,-3.221],[-0.583,-7.941],[-3.199,-10.82]],"c":true}]},{"i":{"x":0.25,"y":1},"o":{"x":0.665,"y":0},"t":13,"s":[{"i":[[-0.067,-1.364],[0,0],[0,0],[0,0],[-0.183,0.94],[0,0],[1.886,0],[0,0],[0.579,1.836],[1.857,-0.702]],"o":[[0.096,1.95],[0,0],[0,0],[0.958,0],[0,0],[0.359,-1.852],[0,0],[0,0],[-0.674,-2.261],[-1.921,0.726]],"v":[[-7.456,-6.066],[-8.083,-2.448],[-8.083,10.952],[4.018,10.952],[5.982,9.333],[7.724,0.351],[4.78,-3.221],[-1.218,-3.787],[-1.898,-8.269],[-7.041,-11.382]],"c":true}]},{"t":32,"s":[{"i":[[0.62,-1.062],[0,0],[0,0],[0,0],[-0.183,0.94],[0,0],[1.886,0],[0,0],[0,2.393],[1.484,0.142]],"o":[[-0.769,2.514],[0,0],[0,0],[0.958,0],[0,0],[0.359,-1.852],[0,0],[0,0],[-0.218,-1.701],[-1.383,-0.132]],"v":[[-6.251,-8.749],[-8.083,-2.448],[-8.083,10.952],[4.018,10.952],[5.982,9.333],[7.724,0.351],[4.78,-3.221],[-0.583,-3.221],[-0.583,-7.941],[-3.199,-10.82]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-0.512,0.05],[0,0],[0,0],[0,0],[0,0.552]],"o":[[0,-0.515],[0,0],[0,0],[0,0],[-0.552,0],[0,0]],"v":[[-13.583,-0.586],[-12.68,-1.581],[-8.083,-2.03],[-8.083,10.952],[-12.583,10.952],[-13.583,9.952]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 2","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[25.582,22.548],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /lib/assets/lottie/lottie_single_episode_loading.json: -------------------------------------------------------------------------------- 1 | {"v":"5.6.4","fr":60,"ip":0,"op":112,"w":34,"h":34,"nm":"single_episode_loading","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"single_episode_loading Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[17,17,0],"ix":2},"a":{"a":0,"k":[17,17,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-8.284,0],[0,-8.284],[8.284,0],[0,8.284]],"o":[[8.284,0],[0,8.284],[-8.284,0],[0,-8.284]],"v":[[0,-15],[15,0],[0,15],[-15,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.145098039216,0.705882352941,0.882352941176,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.5,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[17,17],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.67],"y":[1]},"o":{"x":[0.59],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.41],"y":[1]},"o":{"x":[0.33],"y":[0]},"t":39.771,"s":[0]},{"t":75,"s":[50]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.67],"y":[1]},"o":{"x":[0.59],"y":[0]},"t":0,"s":[0]},{"t":39.771484375,"s":[50]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.41],"y":[1]},"o":{"x":[0.59],"y":[0]},"t":0,"s":[0]},{"t":75,"s":[526]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":103,"st":0,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /lib/common/colors/colors.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class AppColors { 4 | /// 主色调 5 | static const Color primaryColor = Color.fromRGBO(36, 180, 224, 1); 6 | 7 | /// 主背景 8 | static const Color primaryBackground = Color(0xFFF4F6FA); 9 | 10 | /// 主文本 11 | static const Color primaryText = Color.fromRGBO(66, 65, 67, 1); 12 | 13 | /// 主文本灰色 14 | static const Color primaryGreyText = Color.fromRGBO(196, 196, 197, 1); 15 | 16 | /// 主文本绿色 17 | static const Color primaryGreenText = Color.fromRGBO(125, 182, 70, 1); 18 | 19 | /// 主背景灰色 20 | static const Color primaryGreyBackground = Color.fromRGBO(246, 246, 246, 1); 21 | } 22 | -------------------------------------------------------------------------------- /lib/common/langs/en_US.dart: -------------------------------------------------------------------------------- 1 | const Map en_US = { 2 | 'title': 'This is Title!', 3 | 'login': 'logged in as @name with email @email', 4 | }; 5 | -------------------------------------------------------------------------------- /lib/common/langs/translation_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | import 'en_US.dart'; 4 | import 'zh_Hans.dart'; 5 | 6 | /* 7 | https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LanguageandLocaleIDs/LanguageandLocaleIDs.html 8 | https://www.ibabbleon.com/iOS-Language-Codes-ISO-639.html 9 | */ 10 | 11 | class TranslationService extends Translations { 12 | static Locale? get locale => Get.deviceLocale; 13 | static final fallbackLocale = Locale('zh', 'Hans'); 14 | @override 15 | Map> get keys => { 16 | 'en_US': en_US, 17 | 'zh_Hans': zh_Hans, 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /lib/common/langs/zh_Hans.dart: -------------------------------------------------------------------------------- 1 | const Map zh_Hans = { 2 | 'title': '这是标题', 3 | 'login': '登录用户 @name,邮箱账号 @email', 4 | }; 5 | -------------------------------------------------------------------------------- /lib/common/size_config.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class SizeConfig { 4 | static late MediaQueryData _mediaQueryData; 5 | static late double screenWidth; 6 | static late double screenHeight; 7 | static double? defaultSize; 8 | static Orientation? orientation; 9 | 10 | void init(BuildContext context) { 11 | _mediaQueryData = MediaQuery.of(context); 12 | screenWidth = _mediaQueryData.size.width; 13 | screenHeight = _mediaQueryData.size.height; 14 | orientation = _mediaQueryData.orientation; 15 | } 16 | } 17 | 18 | // Get the proportionate height as per screen size 19 | double getProportionateScreenHeight(double inputHeight) { 20 | double screenHeight = SizeConfig.screenHeight; 21 | // 812 is the layout height that designer use 22 | return (inputHeight / 926.0) * screenHeight; 23 | } 24 | 25 | // Get the proportionate height as per screen size 26 | double getProportionateScreenWidth(double inputWidth) { 27 | double screenWidth = SizeConfig.screenWidth; 28 | // 375 is the layout width that designer use 29 | return (inputWidth / 428.0) * screenWidth; 30 | } 31 | -------------------------------------------------------------------------------- /lib/common/values/cache.dart: -------------------------------------------------------------------------------- 1 | // 是否启用缓存 2 | const CACHE_ENABLE = false; 3 | 4 | // 缓存的最长时间,单位(秒) 5 | const CACHE_MAXAGE = 1000; 6 | 7 | // 最大缓存数 8 | const CACHE_MAXCOUNT = 100; 9 | -------------------------------------------------------------------------------- /lib/common/values/enum.dart: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lib/common/values/storage.dart: -------------------------------------------------------------------------------- 1 | /// 用户信息 2 | const String STORAGE_USER_PROFILE_KEY = 'user_profile'; 3 | 4 | /// 设备是否第一次打开 5 | const String STORAGE_DEVICE_ALREADY_OPEN_KEY = 'device_already_open'; 6 | 7 | /// 极光设备RegistrationID 8 | const String REGISTRATION_ID = 'reegistration_id'; 9 | -------------------------------------------------------------------------------- /lib/common/values/values.dart: -------------------------------------------------------------------------------- 1 | library values; 2 | 3 | export 'cache.dart'; 4 | export 'storage.dart'; 5 | -------------------------------------------------------------------------------- /lib/components/cahenetwork_image.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class MyCachedNetworkImage extends StatelessWidget { 5 | final String imageurl; 6 | const MyCachedNetworkImage({Key? key, required this.imageurl}) 7 | : super(key: key); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return CachedNetworkImage( 12 | width: double.infinity, 13 | height: double.infinity, 14 | imageUrl: imageurl, 15 | placeholder: (_, __) => 16 | Image.asset('lib/assets/images/common/jiazaizhong.png'), 17 | fit: BoxFit.cover, 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/components/components.dart: -------------------------------------------------------------------------------- 1 | library components; 2 | 3 | export 'custom_appbar.dart'; 4 | export 'custom_scaffold.dart'; 5 | -------------------------------------------------------------------------------- /lib/components/custom_appbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:all_universe_flutter/common/colors/colors.dart'; 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 4 | 5 | /// appbar 返回按钮类型 6 | enum AppBarBackType { Back, Close, None } 7 | 8 | const double kNavigationBarHeight = 44.0; 9 | 10 | // 自定义 AppBar 11 | class MyAppBar extends AppBar implements PreferredSizeWidget { 12 | MyAppBar({ 13 | Key? key, 14 | Widget? title, 15 | AppBarBackType? leadingType, 16 | WillPopCallback? onWillPop, 17 | Widget? leading, 18 | Brightness? brightness, 19 | Color? backgroundColor, 20 | List? actions, 21 | bool centerTitle = true, 22 | double? elevation, 23 | Color? backArrowColor = AppColors.primaryColor, 24 | }) : super( 25 | key: key, 26 | title: title, 27 | centerTitle: centerTitle, 28 | backgroundColor: backgroundColor ?? AppColors.primaryBackground, 29 | leading: leading ?? 30 | (leadingType == AppBarBackType.None 31 | ? Container() 32 | : AppBarBack( 33 | leadingType ?? AppBarBackType.Back, 34 | onWillPop: onWillPop, 35 | color: backArrowColor, 36 | )), 37 | actions: actions, 38 | elevation: elevation ?? 0.5, 39 | ); 40 | @override 41 | get preferredSize => Size.fromHeight(44); 42 | } 43 | 44 | // 自定义返回按钮 45 | class AppBarBack extends StatelessWidget { 46 | final AppBarBackType _backType; 47 | final Color? color; 48 | final WillPopCallback? onWillPop; 49 | 50 | AppBarBack(this._backType, {this.onWillPop, this.color}); 51 | 52 | @override 53 | Widget build(BuildContext context) { 54 | return GestureDetector( 55 | onTap: () async { 56 | final willBack = onWillPop == null ? true : await onWillPop!(); 57 | if (!willBack) return; 58 | Navigator.pop(context); 59 | }, 60 | child: _backType == AppBarBackType.Close 61 | ? Container( 62 | child: Icon(Icons.close, color: color, size: 24.0.r), 63 | ) 64 | : Container( 65 | padding: EdgeInsets.only(right: 0.r), 66 | child: Icon(Icons.arrow_back, size: 24.0.r, color: color), 67 | ), 68 | ); 69 | } 70 | } 71 | 72 | class MyTitle extends StatelessWidget { 73 | final String _title; 74 | final Color? color; 75 | 76 | MyTitle(this._title, {this.color}); 77 | 78 | @override 79 | Widget build(BuildContext context) { 80 | return Text(_title, 81 | style: TextStyle( 82 | color: color ?? Color(0xFF222222), 83 | fontSize: 18, 84 | fontWeight: FontWeight.w500)); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /lib/components/custom_like.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/common/colors/colors.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 4 | 5 | class CustomLikeBtn extends StatelessWidget { 6 | final Color color; 7 | const CustomLikeBtn({super.key, this.color = AppColors.primaryColor}); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Icon( 12 | Icons.star_outline_rounded, 13 | size: 28.w, 14 | color: color, 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/components/custom_loading.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | 3 | class CustomLoading extends StatelessWidget { 4 | const CustomLoading({super.key}); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return Center( 9 | child: CupertinoActivityIndicator(), 10 | ); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/components/custom_more.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/common/colors/colors.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 4 | 5 | class CustomMoreBtn extends StatelessWidget { 6 | final Color color; 7 | const CustomMoreBtn({super.key, this.color = AppColors.primaryColor}); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Icon( 12 | Icons.more_horiz, 13 | color: color, 14 | size: 26.w, 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/components/custom_scaffold.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'custom_appbar.dart'; 3 | 4 | class BaseScaffold extends Scaffold { 5 | BaseScaffold({ 6 | String? title, 7 | PreferredSizeWidget? appBar, 8 | required Widget body, 9 | List? actions, 10 | AppBarBackType? leadType, 11 | WillPopCallback? onWillPop, 12 | Brightness brightness = Brightness.light, 13 | Widget? floatingActionButton, 14 | Color appBarBackgroundColor = Colors.white, 15 | Color? titleColor, 16 | bool centerTitle = true, 17 | Widget? bottomNavigationBar, 18 | FloatingActionButtonLocation? floatingActionButtonLocation, 19 | }) : super( 20 | appBar: appBar, 21 | backgroundColor: Colors.white, 22 | body: body, 23 | bottomNavigationBar: bottomNavigationBar, 24 | floatingActionButton: floatingActionButton, 25 | floatingActionButtonLocation: floatingActionButtonLocation, 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /lib/components/custom_scroll_physics.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class CustomScrollPhysics extends ScrollPhysics { 4 | final double itemDimension; 5 | 6 | CustomScrollPhysics({ 7 | required this.itemDimension, 8 | }); 9 | 10 | double _getPage(ScrollMetrics position) { 11 | return position.pixels / itemDimension; 12 | } 13 | 14 | double _getPixels(double page) { 15 | return page * itemDimension; 16 | } 17 | 18 | double _getTargetPixels( 19 | ScrollMetrics position, Tolerance tolerance, double velocity) { 20 | double page = _getPage(position); 21 | if (velocity < -tolerance.velocity) { 22 | page -= 0.5; 23 | } else if (velocity > tolerance.velocity) { 24 | page += 0.5; 25 | } 26 | return _getPixels(page.roundToDouble()); 27 | } 28 | 29 | @override 30 | Simulation? createBallisticSimulation( 31 | ScrollMetrics position, double velocity) { 32 | // If we're out of range and not headed back in range, defer to the parent 33 | // ballistics, which should put us back in range at a page boundary. 34 | if ((velocity <= 0.0 && position.pixels <= position.minScrollExtent) || 35 | (velocity >= 0.0 && position.pixels >= position.maxScrollExtent)) 36 | return super.createBallisticSimulation(position, velocity); 37 | final Tolerance tolerance = this.tolerance; 38 | final double target = _getTargetPixels(position, tolerance, velocity); 39 | if (target != position.pixels) 40 | return ScrollSpringSimulation(spring, position.pixels, target, velocity, 41 | tolerance: tolerance); 42 | return null; 43 | } 44 | 45 | @override 46 | bool get allowImplicitScrolling => false; 47 | } 48 | -------------------------------------------------------------------------------- /lib/components/custom_share.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/common/colors/colors.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 4 | 5 | class CustomShareBtn extends StatelessWidget { 6 | final Color color; 7 | const CustomShareBtn({super.key, this.color = AppColors.primaryColor}); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Icon( 12 | Icons.share, 13 | size: 25.w, 14 | color: color, 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/components/custom_sub.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/common/colors/colors.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 4 | 5 | class CustomSubBtn extends StatelessWidget { 6 | final Color color; 7 | const CustomSubBtn({super.key, this.color = AppColors.primaryColor}); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Center( 12 | child: Container( 13 | alignment: Alignment.center, 14 | padding: EdgeInsets.only(left: 7.w, right: 7.w), 15 | height: 28.h, 16 | decoration: BoxDecoration( 17 | color: color, 18 | borderRadius: BorderRadius.all(Radius.circular(3.r)), 19 | ), 20 | child: Row( 21 | children: [ 22 | Icon( 23 | Icons.add, 24 | color: Colors.white, 25 | size: 16.w, 26 | ), 27 | SizedBox(width: 6.w), 28 | Text( 29 | '订阅', 30 | style: TextStyle( 31 | color: Colors.white, 32 | fontSize: 15.sp, 33 | ), 34 | ), 35 | ], 36 | ), 37 | ), 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/components/custom_title.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/common/colors/colors.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 4 | 5 | // 顶部标题 6 | class TopTitle extends StatelessWidget { 7 | final String title; 8 | final Widget widget; 9 | TopTitle(this.title, this.widget); 10 | @override 11 | Widget build(BuildContext context) { 12 | return Row( 13 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 14 | children: [ 15 | Text( 16 | title, 17 | style: TextStyle( 18 | fontSize: 25.sp, 19 | fontWeight: FontWeight.w400, 20 | ), 21 | ), 22 | widget 23 | ], 24 | ); 25 | } 26 | } 27 | 28 | //单个大标题 29 | class DiyTitle extends StatelessWidget { 30 | final String? title1; 31 | final String? title2; 32 | final EdgeInsets margin; 33 | 34 | const DiyTitle({ 35 | this.title1, 36 | this.title2, 37 | this.margin = const EdgeInsets.only(top: 0), 38 | }); 39 | 40 | @override 41 | Widget build(BuildContext context) { 42 | return Container( 43 | margin: margin, 44 | child: Row( 45 | children: [ 46 | if (title1 != null && title1!.isNotEmpty) 47 | Opacity( 48 | opacity: 0.4, 49 | child: Text( 50 | '$title1 ', 51 | style: TextStyle( 52 | fontSize: 20.sp, 53 | color: AppColors.primaryColor, 54 | fontWeight: FontWeight.w900, 55 | ), 56 | ), 57 | ), 58 | Text( 59 | '$title2', 60 | style: TextStyle( 61 | fontSize: 20.sp, 62 | color: AppColors.primaryColor, 63 | fontWeight: FontWeight.w900, 64 | ), 65 | ), 66 | ], 67 | ), 68 | ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /lib/components/no_splash_factory.dart: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lib/config.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/env.dart'; 2 | 3 | // 开发环境 4 | const SERVER_HOST_DEV = 'https://mock.apifox.cn/m1/1931946-0-default/api'; 5 | 6 | // 生产环境 7 | // 生产环境地址禁止随意修改!!! 8 | const SERVER_HOST_PROD = ''; 9 | 10 | const SERVER_API_URL = ENV_IS_DEV ? SERVER_HOST_DEV : SERVER_HOST_PROD; 11 | 12 | const ENV_IS_DEV = ENV == "DEV"; 13 | 14 | const PUSH_PREFIX = ENV_IS_DEV ? "test_" : "prod_"; 15 | -------------------------------------------------------------------------------- /lib/env.dart: -------------------------------------------------------------------------------- 1 | const ENV = 'DEV'; 2 | -------------------------------------------------------------------------------- /lib/global.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:all_universe_flutter/model/user.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/services.dart'; 5 | import 'package:all_universe_flutter/common/values/values.dart'; 6 | import 'package:all_universe_flutter/utils/utils.dart'; 7 | import 'package:just_audio_background/just_audio_background.dart'; 8 | 9 | /// 全局配置 10 | class Global { 11 | /// 用户配置 12 | static UserInfo? profile = null; 13 | 14 | /// 是否第一次打开 15 | static bool isFirstOpen = false; 16 | 17 | /// 是否离线登录 18 | static bool isOfflineLogin = false; 19 | 20 | /// 是否 release 21 | static bool get isRelease => bool.fromEnvironment("dart.vm.product"); 22 | 23 | /// init 24 | static Future init() async { 25 | // 运行初始 26 | WidgetsFlutterBinding.ensureInitialized(); 27 | 28 | // Ruquest 模块初始化 29 | Request(); 30 | // 本地存储初始化 31 | await LoacalStorage.init(); 32 | 33 | // 后台播放器初始化 34 | await JustAudioBackground.init( 35 | androidNotificationChannelId: 'com.ryanheise.bg_demo.channel.audio', 36 | androidNotificationChannelName: 'Audio playback', 37 | androidNotificationOngoing: true, 38 | ); 39 | 40 | // 极光推送初始化 41 | // await PushManager.setup(); 42 | 43 | // 语音播报初始化 44 | // await TtsManager.setup(); 45 | 46 | // 高德地图初始化 47 | // await AmapService.instance.init( 48 | // iosKey: 'xxxx', 49 | // androidKey: 'xxxx', 50 | // ); 51 | 52 | // 读取设备第一次打开 53 | isFirstOpen = !LoacalStorage().getBool(STORAGE_DEVICE_ALREADY_OPEN_KEY); 54 | if (isFirstOpen) { 55 | LoacalStorage().setBool(STORAGE_DEVICE_ALREADY_OPEN_KEY, true); 56 | } 57 | 58 | // 读取离线用户信息 59 | var _profileJSON = LoacalStorage().getJSON(STORAGE_USER_PROFILE_KEY); 60 | if (_profileJSON != null) { 61 | profile = UserInfo.fromJson(_profileJSON); 62 | isOfflineLogin = true; 63 | } 64 | 65 | // android 状态栏为透明的沉浸 66 | if (Platform.isAndroid) { 67 | SystemUiOverlayStyle systemUiOverlayStyle = 68 | SystemUiOverlayStyle(statusBarColor: Colors.transparent); 69 | SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle); 70 | } 71 | } 72 | 73 | // 持久化 用户信息 74 | static Future saveProfile(UserInfo userResponse) { 75 | profile = userResponse; 76 | return LoacalStorage() 77 | .setJSON(STORAGE_USER_PROFILE_KEY, userResponse.toJson()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_easyloading/flutter_easyloading.dart'; 3 | import 'package:all_universe_flutter/common/langs/translation_service.dart'; 4 | import 'package:all_universe_flutter/global.dart'; 5 | import 'package:all_universe_flutter/pages/Index/Index_view.dart'; 6 | import 'package:all_universe_flutter/pages/Index/index_binding.dart'; 7 | import 'package:all_universe_flutter/router/app_pages.dart'; 8 | import 'package:get/get.dart'; 9 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 10 | 11 | void main() async { 12 | await Global.init(); 13 | runApp(MyApp()); 14 | } 15 | 16 | class MyApp extends StatelessWidget { 17 | @override 18 | Widget build(BuildContext context) { 19 | return ScreenUtilInit( 20 | designSize: const Size(375, 812), 21 | minTextAdapt: true, 22 | splitScreenMode: true, 23 | builder: (BuildContext context, child) { 24 | return GetMaterialApp( 25 | title: '大宇宙', 26 | home: IndexPage(), 27 | initialBinding: IndexBinding(), 28 | debugShowCheckedModeBanner: false, 29 | enableLog: true, 30 | initialRoute: AppPages.INITIAL, 31 | getPages: AppPages.routes, 32 | unknownRoute: AppPages.unknownRoute, 33 | builder: EasyLoading.init(), 34 | locale: TranslationService.locale, 35 | fallbackLocale: TranslationService.fallbackLocale, 36 | ); 37 | }, 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/model/api_response.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | /// 请求返回格式 4 | ResultData resultDataFromJson(String str) => 5 | ResultData.fromJson(json.decode(str)); 6 | 7 | String resultDataToJson(ResultData data) => json.encode(data.toJson()); 8 | 9 | class ResultData { 10 | ResultData({ 11 | required this.code, 12 | this.data, 13 | this.msg, 14 | }); 15 | 16 | int code; 17 | String? msg; 18 | T? data; 19 | 20 | factory ResultData.fromJson(Map json) => ResultData( 21 | code: json["code"], 22 | msg: json["msg"], 23 | data: json["data"], 24 | ); 25 | 26 | Map toJson() => { 27 | "code": code, 28 | "msg": msg, 29 | "data": data, 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /lib/model/play.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | User userFromJson(String str) => User.fromJson(json.decode(str)); 4 | 5 | String userToJson(User data) => json.encode(data.toJson()); 6 | 7 | class User { 8 | User({ 9 | required this.img, 10 | required this.name, 11 | }); 12 | 13 | final String img; 14 | final String name; 15 | 16 | factory User.fromJson(Map json) => User( 17 | img: json["img"], 18 | name: json["name"], 19 | ); 20 | 21 | Map toJson() => { 22 | "img": img, 23 | "name": name, 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /lib/model/podcast.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | PodcastModel podcastModelFromJson(String str) => 4 | PodcastModel.fromJson(json.decode(str)); 5 | 6 | String podcastModelToJson(PodcastModel data) => json.encode(data.toJson()); 7 | 8 | class PodcastModel { 9 | PodcastModel({ 10 | required this.name, 11 | required this.cover, 12 | required this.title, 13 | required this.userList, 14 | required this.desc, 15 | required this.userName, 16 | required this.time, 17 | required this.sTitle, 18 | required this.id, 19 | required this.color, 20 | required this.url, 21 | required this.cover2, 22 | }); 23 | 24 | String name; 25 | String cover; 26 | String title; 27 | List userList; 28 | String desc; 29 | String userName; 30 | String sTitle; 31 | String color; 32 | int time; 33 | int id; 34 | String url; 35 | String cover2; 36 | 37 | factory PodcastModel.fromJson(Map json) => PodcastModel( 38 | name: json["name"], 39 | cover: json["cover"], 40 | title: json["title"], 41 | userList: List.from( 42 | json["userList"].map((x) => UserList.fromJson(x))), 43 | desc: json["desc"], 44 | userName: json["userName"], 45 | time: json["time"], 46 | sTitle: json["sTitle"], 47 | id: json["id"], 48 | color: json["color"], 49 | url: json["url"], 50 | cover2: json["cover2"], 51 | ); 52 | 53 | Map toJson() => { 54 | "name": name, 55 | "cover": cover, 56 | "title": title, 57 | "userList": List.from(userList.map((x) => x.toJson())), 58 | "desc": desc, 59 | "userName": userName, 60 | "time": time, 61 | "sTitle": sTitle, 62 | "id": id, 63 | "color": color, 64 | "url": url, 65 | "cover2": cover2, 66 | }; 67 | } 68 | 69 | class UserList { 70 | UserList({ 71 | required this.name, 72 | required this.img, 73 | }); 74 | 75 | String name; 76 | String img; 77 | 78 | factory UserList.fromJson(Map json) => UserList( 79 | name: json["name"], 80 | img: json["img"], 81 | ); 82 | 83 | Map toJson() => { 84 | "name": name, 85 | "img": img, 86 | }; 87 | } 88 | -------------------------------------------------------------------------------- /lib/model/podcast_detail.dart: -------------------------------------------------------------------------------- 1 | // To parse this JSON data, do 2 | // 3 | // final podcastDetail = podcastDetailFromJson(jsonString); 4 | 5 | import 'dart:convert'; 6 | 7 | PodcastDetail podcastDetailFromJson(String str) => 8 | PodcastDetail.fromJson(json.decode(str)); 9 | 10 | String podcastDetailToJson(PodcastDetail data) => json.encode(data.toJson()); 11 | 12 | class PodcastDetail { 13 | PodcastDetail({ 14 | required this.name, 15 | required this.color, 16 | required this.cover, 17 | required this.cover2, 18 | required this.title, 19 | required this.userName, 20 | required this.desc, 21 | required this.time, 22 | required this.content, 23 | required this.url, 24 | required this.id, 25 | }); 26 | 27 | String name; 28 | String color; 29 | String cover; 30 | String title; 31 | String userName; 32 | String desc; 33 | int time; 34 | int id; 35 | String content; 36 | String cover2; 37 | String url; 38 | 39 | factory PodcastDetail.fromJson(Map json) => PodcastDetail( 40 | name: json["name"], 41 | color: json["color"], 42 | cover: json["cover"], 43 | title: json["title"], 44 | userName: json["userName"], 45 | desc: json["desc"], 46 | time: json["time"], 47 | content: json["content"], 48 | cover2: json["cover2"], 49 | url: json["url"], 50 | id: json["id"], 51 | ); 52 | 53 | Map toJson() => { 54 | "name": name, 55 | "color": color, 56 | "cover": cover, 57 | "title": title, 58 | "userName": userName, 59 | "desc": desc, 60 | "time": time, 61 | "content": content, 62 | "cover2": cover2, 63 | "url": url, 64 | "id": id, 65 | }; 66 | } 67 | -------------------------------------------------------------------------------- /lib/model/user.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | UserInfo UserInfoFromJson(String str) => UserInfo.fromJson(json.decode(str)); 4 | 5 | String UserInfoToJson(UserInfo data) => json.encode(data.toJson()); 6 | 7 | class UserInfo { 8 | UserInfo({ 9 | this.img, 10 | this.name, 11 | this.token, 12 | }); 13 | 14 | final String? img; 15 | final String? name; 16 | final String? token; 17 | 18 | factory UserInfo.fromJson(Map json) => UserInfo( 19 | img: json["img"], 20 | name: json["name"], 21 | token: json["token"], 22 | ); 23 | 24 | Map toJson() => { 25 | "img": img, 26 | "name": name, 27 | "token": token, 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /lib/pages/Index/Index_controller.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:all_universe_flutter/global.dart'; 4 | import 'package:all_universe_flutter/router/app_pages.dart'; 5 | import 'package:get/get.dart'; 6 | 7 | class IndexController extends GetxController { 8 | @override 9 | void onInit() { 10 | super.onInit(); 11 | } 12 | 13 | @override 14 | void onReady() { 15 | startCountdownTimer(); 16 | } 17 | 18 | @override 19 | void onClose() {} 20 | 21 | // 展示欢迎页,倒计时1.5秒之后进入应用 22 | Future startCountdownTimer() async { 23 | await Future.delayed(Duration(milliseconds: 1000), () { 24 | if (Global.profile != null) { 25 | Get.toNamed(AppRoutes.Tabbar); 26 | } else { 27 | Get.offAllNamed(AppRoutes.Splash); 28 | } 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/pages/Index/Index_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/common/colors/colors.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:all_universe_flutter/pages/Index/Index_controller.dart'; 4 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 5 | import 'package:get/get.dart'; 6 | 7 | class IndexPage extends StatelessWidget { 8 | IndexPage({Key? key}) : super(key: key); 9 | final controller = Get.put(IndexController()); 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | child: Column( 14 | crossAxisAlignment: CrossAxisAlignment.center, 15 | children: [ 16 | Spacer(), 17 | Image( 18 | image: AssetImage('lib/assets/images/common/logo.png'), 19 | width: 200.w, 20 | ), 21 | SizedBox(height: 10.h), 22 | Text( 23 | '😂大宇宙😂', 24 | style: TextStyle( 25 | color: AppColors.primaryText, 26 | fontSize: 20.sp, 27 | ), 28 | ), 29 | Spacer(), 30 | ], 31 | ), 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/pages/Index/index_binding.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/pages/Index/Index_controller.dart'; 2 | import 'package:get/get.dart'; 3 | 4 | class IndexBinding extends Bindings { 5 | @override 6 | void dependencies() { 7 | Get.lazyPut(() => IndexController()); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/pages/details/details_binding.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/pages/details/details_controller.dart'; 2 | import 'package:get/get.dart'; 3 | 4 | class DetailsBinding extends Bindings { 5 | @override 6 | void dependencies() { 7 | print("homebing"); 8 | Get.lazyPut(() => DetailsController()); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/pages/details/details_controller.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:all_universe_flutter/model/podcast_detail.dart'; 4 | import 'package:all_universe_flutter/pages/details/details_state.dart'; 5 | import 'package:all_universe_flutter/services/services.dart'; 6 | import 'package:get/get.dart'; 7 | 8 | class DetailsController extends GetxController { 9 | final DetailState state = DetailState(); 10 | 11 | @override 12 | void onInit() async { 13 | ///监听滚动位置 14 | state.scrollController.addListener(() { 15 | if (state.scrollController.offset > 60) { 16 | state.isShowAppbar = true; 17 | } else { 18 | state.isShowAppbar = false; 19 | } 20 | update(); 21 | }); 22 | dynamic params = Get.arguments; 23 | state.details = await getDetails({'id': params['data'].id}); 24 | state.list = await getRandomPodcastList({'pageSize': '5'}); 25 | state.isLoading = false; 26 | update(); 27 | super.onInit(); 28 | } 29 | 30 | @override 31 | void onReady() {} 32 | 33 | @override 34 | void onClose() {} 35 | } 36 | -------------------------------------------------------------------------------- /lib/pages/details/details_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/model/podcast.dart'; 2 | import 'package:all_universe_flutter/model/podcast_detail.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | class DetailState { 6 | bool isShowAppbar = false; 7 | bool isLoading = true; 8 | PodcastDetail? details; 9 | List list = []; 10 | ScrollController scrollController = ScrollController(); 11 | DetailState() {} 12 | } 13 | -------------------------------------------------------------------------------- /lib/pages/details/widgets/after_appbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/components/components.dart'; 2 | import 'package:all_universe_flutter/components/custom_share.dart'; 3 | import 'package:all_universe_flutter/components/custom_sub.dart'; 4 | import 'package:all_universe_flutter/utils/utils.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 7 | 8 | /// 滚动之后的导航 9 | PreferredSizeWidget AfterAppbar(details) { 10 | return MyAppBar( 11 | centerTitle: false, 12 | backgroundColor: Colors.white, 13 | backArrowColor: hexToColor(details.color), 14 | elevation: 0, 15 | title: Row( 16 | children: [ 17 | Container( 18 | width: 30.w, 19 | height: 30.w, 20 | decoration: BoxDecoration( 21 | image: DecorationImage( 22 | image: NetworkImage(details.cover), 23 | fit: BoxFit.cover, 24 | ), 25 | borderRadius: BorderRadius.all(Radius.circular(3.r)), 26 | ), 27 | ), 28 | SizedBox(width: 10.w), 29 | Expanded( 30 | child: Text( 31 | details.title, 32 | overflow: TextOverflow.ellipsis, 33 | maxLines: 1, 34 | style: TextStyle( 35 | color: Colors.black, 36 | fontSize: 14.sp, 37 | fontWeight: FontWeight.w400, 38 | ), 39 | ), 40 | ) 41 | ], 42 | ), 43 | actions: [ 44 | CustomSubBtn(color: hexToColor(details.color)), 45 | SizedBox(width: 15.w), 46 | CustomShareBtn(color: hexToColor(details.color)), 47 | SizedBox(width: 10.w), 48 | ], 49 | ); 50 | } 51 | -------------------------------------------------------------------------------- /lib/pages/details/widgets/before_appbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/components/components.dart'; 2 | import 'package:all_universe_flutter/components/custom_more.dart'; 3 | import 'package:all_universe_flutter/components/custom_share.dart'; 4 | import 'package:all_universe_flutter/components/custom_sub.dart'; 5 | import 'package:all_universe_flutter/utils/utils.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 8 | 9 | /// 滚动之前的导航 10 | PreferredSizeWidget BeforeAppbar(details) { 11 | return MyAppBar( 12 | centerTitle: false, 13 | backgroundColor: Colors.white, 14 | elevation: 0, 15 | backArrowColor: hexToColor(details.color), 16 | actions: [ 17 | CustomSubBtn(color: hexToColor(details.color)), 18 | SizedBox(width: 15.w), 19 | CustomShareBtn(color: hexToColor(details.color)), 20 | SizedBox(width: 10.w), 21 | CustomMoreBtn(color: hexToColor(details.color)), 22 | SizedBox(width: 20.w), 23 | ], 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /lib/pages/details/widgets/recommend_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/common/colors/colors.dart'; 2 | import 'package:all_universe_flutter/components/cahenetwork_image.dart'; 3 | import 'package:all_universe_flutter/model/podcast.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 6 | 7 | class RecommendItem extends StatelessWidget { 8 | final PodcastModel data; 9 | const RecommendItem({super.key, required this.data}); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | final TextStyle textStyle = TextStyle( 14 | fontSize: 11.sp, 15 | color: AppColors.primaryGreyText, 16 | ); 17 | return Container( 18 | margin: EdgeInsets.only(right: 40.w), 19 | child: Row( 20 | children: [ 21 | ClipRRect( 22 | borderRadius: BorderRadius.all(Radius.circular(5.r)), 23 | child: Container( 24 | width: 60.h, 25 | height: 60.h, 26 | child: MyCachedNetworkImage( 27 | imageurl: data.cover, 28 | ), 29 | ), 30 | ), 31 | SizedBox(width: 10.w), 32 | Expanded( 33 | child: Column( 34 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 35 | crossAxisAlignment: CrossAxisAlignment.start, 36 | children: [ 37 | Text( 38 | data.desc, 39 | overflow: TextOverflow.ellipsis, 40 | maxLines: 2, 41 | style: TextStyle( 42 | fontSize: 14.sp, 43 | ), 44 | ), 45 | Row( 46 | children: [ 47 | Text( 48 | data.name, 49 | style: textStyle, 50 | ), 51 | Spacer(), 52 | Icon( 53 | Icons.thumb_up, 54 | size: 15.w, 55 | color: AppColors.primaryGreyText, 56 | ), 57 | SizedBox(width: 5.w), 58 | Text( 59 | '34', 60 | style: textStyle, 61 | ), 62 | SizedBox(width: 10.w), 63 | Icon( 64 | Icons.message, 65 | size: 15.w, 66 | color: AppColors.primaryGreyText, 67 | ), 68 | SizedBox(width: 5.w), 69 | Text( 70 | '134', 71 | style: textStyle, 72 | ), 73 | ], 74 | ) 75 | ], 76 | ), 77 | ) 78 | ], 79 | ), 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lib/pages/home/home_binding.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/pages/home/home_controller.dart'; 2 | import 'package:get/get.dart'; 3 | 4 | class HomeBinding extends Bindings { 5 | @override 6 | void dependencies() { 7 | Get.lazyPut(() => HomeController()); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/pages/home/home_controller.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:all_universe_flutter/model/podcast.dart'; 4 | import 'package:all_universe_flutter/pages/home/home_state.dart'; 5 | import 'package:get/get.dart'; 6 | import 'package:all_universe_flutter/services/services.dart'; 7 | 8 | class HomeController extends GetxController { 9 | late final HomeState state; 10 | 11 | @override 12 | void onInit() async { 13 | state = HomeState(); 14 | await Future.delayed(Duration(seconds: 3)); 15 | state.scrollController.addListener(() { 16 | if (state.scrollController.offset > 100) { 17 | state.isShowAppbarText = true; 18 | } else { 19 | state.isShowAppbarText = false; 20 | } 21 | update(); 22 | }); 23 | await initData(); 24 | state.loading = false; 25 | update(); 26 | super.onInit(); 27 | } 28 | 29 | @override 30 | void onReady() { 31 | super.onReady(); 32 | } 33 | 34 | setHotSwiperIndex(int index) { 35 | state.hotSwiperIndex = index; 36 | update(); 37 | } 38 | 39 | @override 40 | void onClose() { 41 | print('close'); 42 | } 43 | 44 | List getRandomArrayElements(List arr, int count) { 45 | var shuffled = arr.sublist(0); 46 | var i = arr.length; 47 | int min = i - count; 48 | dynamic temp; 49 | dynamic index; 50 | while (i-- > min) { 51 | index = 52 | ((i + 1) * Random().nextDouble()).floor(); //这里的+1 是因为上面i--的操作 所以要加回来 53 | temp = shuffled[index]; //即值交换 54 | shuffled[index] = shuffled[i]; 55 | shuffled[i] = temp; 56 | } 57 | return shuffled.sublist(min); 58 | } 59 | 60 | onRefresh() async { 61 | await initData(); 62 | update(); 63 | } 64 | 65 | Future initData() async { 66 | var allList = await getRandomPodcastList({'page': 1, 'pageSize': 100}); 67 | state.editSelectionList = getRandomArrayElements(allList, 3); 68 | state.hotList = getRandomArrayElements(allList, 9); 69 | state.recommendList1 = getRandomArrayElements(allList, 3); 70 | state.recommendList2 = getRandomArrayElements(allList, 9); 71 | state.treasureHuntList = getRandomArrayElements(allList, 3); 72 | state.taLikeList = getRandomArrayElements(allList, 3); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /lib/pages/home/home_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/model/podcast.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class HomeState { 5 | /// 编辑精选 6 | List editSelectionList = []; 7 | 8 | /// 榜单 9 | List hotList = []; 10 | 11 | /// 推荐爱听 12 | List recommendList1 = []; 13 | 14 | /// 推荐2 15 | List recommendList2 = []; 16 | 17 | /// 寻宝 18 | List treasureHuntList = []; 19 | 20 | /// ta们喜欢 21 | List taLikeList = []; 22 | 23 | /// 榜单类型下标 24 | int hotSwiperIndex = 0; 25 | 26 | bool loading = true; 27 | 28 | /// 是否展示appbar文字 29 | bool isShowAppbarText = false; 30 | 31 | /// 热榜 Pageview 32 | PageController pageController = PageController(viewportFraction: 0.9); 33 | 34 | List titleList = [ 35 | '最热榜 ', 36 | '锋芒榜 ', 37 | '新星榜 ', 38 | ]; 39 | 40 | ScrollController scrollController = ScrollController(); 41 | HomeState() { 42 | // print('----'); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/pages/home/widgets/edit_selection.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | /// 编辑精选 4 | import 'package:all_universe_flutter/model/podcast.dart'; 5 | import 'package:all_universe_flutter/pages/home/widgets/edit_selection_item.dart'; 6 | import 'package:all_universe_flutter/pages/home/widgets/more_btn.dart'; 7 | import 'package:all_universe_flutter/components/custom_title.dart'; 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 10 | import 'package:all_universe_flutter/common/colors/colors.dart'; 11 | import 'package:get/get.dart'; 12 | 13 | class EditSelection extends StatelessWidget { 14 | final List editSelectionList; 15 | EditSelection({Key? key, required this.editSelectionList}) : super(key: key); 16 | @override 17 | Widget build(BuildContext context) { 18 | return Column( 19 | children: [ 20 | DiyTitle( 21 | title1: '编辑', 22 | title2: '精选', 23 | margin: EdgeInsets.symmetric(vertical: 20.h), 24 | ), 25 | ListView.builder( 26 | itemCount: editSelectionList.length, 27 | shrinkWrap: true, 28 | padding: EdgeInsets.zero, 29 | physics: NeverScrollableScrollPhysics(), 30 | itemBuilder: (context, index) { 31 | return EditSelectionItem( 32 | data: editSelectionList[index], 33 | ontap: (data) { 34 | Get.toNamed('/details', arguments: {'data': data}); 35 | }, 36 | ); 37 | }, 38 | ), 39 | MoreBtn( 40 | icon: Icon( 41 | Icons.calendar_month_outlined, 42 | color: AppColors.primaryGreyText, 43 | size: 26.sp, 44 | ), 45 | text: '查看往日精选', 46 | ), 47 | ], 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/pages/home/widgets/fraternity.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/common/colors/colors.dart'; 2 | import 'package:all_universe_flutter/model/podcast.dart'; 3 | import 'package:all_universe_flutter/pages/home/widgets/podcast_item.dart'; 4 | import 'package:all_universe_flutter/components/custom_title.dart'; 5 | import 'package:all_universe_flutter/utils/common.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 8 | 9 | class Fraternity extends StatelessWidget { 10 | final List list; 11 | Fraternity({super.key, required this.list}); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | List> swiperList = getSplitList(list, 3); 16 | return Container( 17 | margin: EdgeInsets.only(top: 40.h), 18 | child: Column( 19 | crossAxisAlignment: CrossAxisAlignment.start, 20 | mainAxisAlignment: MainAxisAlignment.start, 21 | children: [ 22 | DiyTitle( 23 | title2: '前端互助会', 24 | margin: EdgeInsets.only(top: 0, left: 20.w), 25 | ), 26 | Container( 27 | margin: EdgeInsets.only(top: 5.h, bottom: 15.h, left: 20.w), 28 | child: Text( 29 | '只盼那瓶内脓水,不是你我日后模样', 30 | style: TextStyle( 31 | fontSize: 16.sp, 32 | color: AppColors.primaryColor, 33 | ), 34 | ), 35 | ), 36 | Container( 37 | height: 330.h, 38 | child: PageView.builder( 39 | controller: PageController(viewportFraction: 0.9), 40 | itemCount: swiperList.length, 41 | itemBuilder: (BuildContext context, int index) { 42 | return Container( 43 | padding: EdgeInsets.only(right: 10.w), 44 | child: Column( 45 | children: swiperList[index].map((e) { 46 | return Column( 47 | children: [ 48 | PodcastItem(data: e), 49 | SizedBox(height: 20.h), 50 | ], 51 | ); 52 | }).toList(), 53 | ), 54 | ); 55 | }, 56 | ), 57 | ), 58 | ], 59 | ), 60 | ); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/pages/home/widgets/more_btn.dart: -------------------------------------------------------------------------------- 1 | // 精选更多按钮 2 | import 'dart:developer'; 3 | 4 | import 'package:all_universe_flutter/common/colors/colors.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 7 | 8 | class MoreBtn extends StatelessWidget { 9 | final String text; 10 | final Icon? icon; 11 | 12 | const MoreBtn({Key? key, required this.text, this.icon}) : super(key: key); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return Center( 17 | child: InkWell( 18 | onTap: () => {log('more')}, 19 | child: Container( 20 | width: 140.w, 21 | height: 35.h, 22 | child: Row( 23 | mainAxisAlignment: MainAxisAlignment.center, 24 | children: [ 25 | if (icon != null) icon!, 26 | if (icon != null) SizedBox(), 27 | SizedBox(width: 4.w), 28 | Text( 29 | text, 30 | style: TextStyle( 31 | color: AppColors.primaryGreyText, 32 | fontSize: 14.sp, 33 | ), 34 | ), 35 | ], 36 | ), 37 | decoration: BoxDecoration( 38 | color: AppColors.primaryGreyBackground, 39 | borderRadius: BorderRadius.circular(2.r), 40 | ), 41 | ), 42 | ), 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/pages/home/widgets/podcast_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/common/colors/colors.dart'; 2 | import 'package:all_universe_flutter/components/cahenetwork_image.dart'; 3 | import 'package:all_universe_flutter/components/play_btn.dart'; 4 | import 'package:all_universe_flutter/model/podcast.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 7 | import 'package:get/get.dart'; 8 | 9 | /// 单个播客组件 10 | class PodcastItem extends StatelessWidget { 11 | final PodcastModel data; 12 | final String? type; 13 | 14 | const PodcastItem({super.key, required this.data, this.type = 'sTitle'}); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return GestureDetector( 19 | onTap: () => Get.toNamed('/details', arguments: {'data': data}), 20 | child: Container( 21 | height: 90.r, 22 | color: Colors.transparent, 23 | child: Row( 24 | children: [ 25 | Container( 26 | width: 90.r, 27 | child: MyCachedNetworkImage(imageurl: data.cover), 28 | ), 29 | SizedBox(width: 10.w), 30 | Expanded( 31 | child: Column( 32 | crossAxisAlignment: CrossAxisAlignment.start, 33 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 34 | children: [ 35 | Text( 36 | data.name, 37 | style: TextStyle( 38 | fontSize: 14.sp, 39 | color: AppColors.primaryGreyText, 40 | ), 41 | ), 42 | Text( 43 | data.desc, 44 | maxLines: 2, 45 | overflow: TextOverflow.ellipsis, 46 | style: TextStyle( 47 | fontSize: 14.sp, 48 | color: AppColors.primaryText, 49 | fontWeight: FontWeight.w400, 50 | ), 51 | ), 52 | Text( 53 | "“ ${type == 'sTitle' ? '${data.name}' : '${data.sTitle} 分钟'} ", 54 | maxLines: 1, 55 | overflow: TextOverflow.ellipsis, 56 | style: TextStyle( 57 | fontSize: 14.sp, 58 | color: AppColors.primaryGreyText, 59 | ), 60 | ), 61 | ], 62 | ), 63 | ), 64 | SizedBox(width: 10.w), 65 | PlayBtn(data: data), 66 | ], 67 | ), 68 | ), 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /lib/pages/home/widgets/recommend.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/model/podcast.dart'; 2 | import 'package:all_universe_flutter/pages/home/widgets/podcast_item.dart'; 3 | import 'package:all_universe_flutter/components/custom_title.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 6 | 7 | class Recommend extends StatelessWidget { 8 | final List list; 9 | const Recommend({super.key, required this.list}); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Container( 14 | child: Column( 15 | crossAxisAlignment: CrossAxisAlignment.start, 16 | children: [ 17 | DiyTitle( 18 | title1: '忽左忽右', 19 | title2: '的观众也爱听', 20 | margin: EdgeInsets.only(top: 40.h, bottom: 15.h), 21 | ), 22 | ListView.builder( 23 | itemCount: list.length, 24 | shrinkWrap: true, 25 | padding: EdgeInsets.zero, 26 | physics: NeverScrollableScrollPhysics(), 27 | itemBuilder: (context, index) { 28 | return Column( 29 | children: [ 30 | PodcastItem(data: list[index], type: 'time'), 31 | list.length - 1 == index 32 | ? SizedBox() 33 | : SizedBox(height: 20.h), 34 | ], 35 | ); 36 | }, 37 | ), 38 | ], 39 | ), 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/pages/home/widgets/search_bar.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/common/colors/colors.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 4 | 5 | class SearchBar extends StatelessWidget { 6 | const SearchBar(); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Container( 11 | height: 50.h, 12 | margin: EdgeInsets.only(top: 10.h), 13 | decoration: BoxDecoration( 14 | color: AppColors.primaryGreyBackground, 15 | borderRadius: BorderRadius.all(Radius.circular(6.r)), 16 | ), 17 | child: Padding( 18 | padding: EdgeInsets.symmetric(horizontal: 20.h), 19 | child: Row( 20 | children: [ 21 | Icon( 22 | Icons.search, 23 | color: AppColors.primaryGreyText, 24 | size: 26.sp, 25 | ), 26 | Expanded( 27 | child: Text( 28 | '掘金开发者大会', 29 | textAlign: TextAlign.center, 30 | style: TextStyle( 31 | fontSize: 16.sp, 32 | color: AppColors.primaryGreyText, 33 | ), 34 | ), 35 | ), 36 | Icon( 37 | Icons.qr_code_scanner_rounded, 38 | color: AppColors.primaryGreyText, 39 | size: 26.sp, 40 | ) 41 | ], 42 | ), 43 | ), 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/pages/login/login_binding.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/pages/login/login_controller.dart'; 2 | import 'package:get/get.dart'; 3 | 4 | class LoginBinding extends Bindings { 5 | @override 6 | void dependencies() { 7 | Get.lazyPut(() => LoginController()); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/pages/login/login_controller.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:developer'; 3 | 4 | import 'package:all_universe_flutter/global.dart'; 5 | import 'package:all_universe_flutter/model/user.dart'; 6 | import 'package:all_universe_flutter/pages/login/login_state.dart'; 7 | import 'package:all_universe_flutter/router/app_pages.dart'; 8 | import 'package:all_universe_flutter/services/services.dart'; 9 | import 'package:flutter_easyloading/flutter_easyloading.dart'; 10 | import 'package:get/get.dart'; 11 | 12 | class LoginController extends GetxController { 13 | final LoginState state = LoginState(); 14 | @override 15 | void onInit() { 16 | super.onInit(); 17 | } 18 | 19 | @override 20 | void onReady() { 21 | state.phoneController.addListener(() { 22 | state.codeEnable = chinaPhoneNumber(state.phoneController.text); 23 | setLoginBtnStatus(); 24 | update(); 25 | }); 26 | state.codeController.addListener(() { 27 | setLoginBtnStatus(); 28 | update(); 29 | }); 30 | } 31 | 32 | @override 33 | void onClose() { 34 | log('close'); 35 | } 36 | 37 | bool chinaPhoneNumber(String input) { 38 | if (!input.isEmpty) { 39 | return true; 40 | } else { 41 | return false; 42 | } 43 | } 44 | 45 | setLoginBtnStatus() { 46 | if (state.phoneController.text.length >= 3) { 47 | state.loginBtnEable = true; 48 | } else { 49 | state.loginBtnEable = false; 50 | } 51 | } 52 | 53 | /// 取消倒计时的计时器。 54 | void _cancelTimer() { 55 | state.timer?.cancel(); 56 | } 57 | 58 | /// 启动倒计时的计时器。 59 | void startTimer() { 60 | // 计时器(`Timer`)组件的定期(`periodic`)构造函数,创建一个新的重复计时器。 61 | state.timer = Timer.periodic(Duration(seconds: 1), (timer) { 62 | print('${state.seconds}'); 63 | if (state.seconds == 0) { 64 | _cancelTimer(); 65 | state.seconds = 20; 66 | state.verifyStr = '重新发送'; 67 | state.codeEnable = true; 68 | update(); 69 | return; 70 | } 71 | state.seconds--; 72 | state.verifyStr = '已发送${state.seconds}' + 's'; 73 | state.codeEnable = false; 74 | update(); 75 | }); 76 | } 77 | 78 | chageCodeStatus() { 79 | if (state.codeEnable) { 80 | startTimer(); 81 | } 82 | } 83 | 84 | /// 登陆 85 | void login() async { 86 | try { 87 | final data = { 88 | "phone": state.phoneController.text, 89 | "passWord": state.codeController.text, 90 | }; 91 | EasyLoading.show(status: 'loading...'); 92 | final UserInfo userInfo = await UserAPI.login(params: data); 93 | Global.saveProfile(userInfo); 94 | state.timer?.cancel(); 95 | EasyLoading.dismiss(); 96 | Get.offAllNamed(AppRoutes.Tabbar); 97 | } catch (e) { 98 | log('$e'); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /lib/pages/login/login_state.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class LoginState { 6 | TextEditingController phoneController = TextEditingController(text: 'admin'); 7 | TextEditingController codeController = TextEditingController(text: '123'); 8 | 9 | bool codeEnable = true; 10 | bool loginBtnEable = true; 11 | String verifyStr = '获取验证码'; 12 | 13 | Timer? timer; 14 | int seconds = 20; 15 | 16 | LoginState() {} 17 | } 18 | -------------------------------------------------------------------------------- /lib/pages/notfound/notfound_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:all_universe_flutter/router/app_pages.dart'; 3 | import 'package:get/get.dart'; 4 | 5 | class NotfoundPage extends StatelessWidget { 6 | const NotfoundPage({Key? key}) : super(key: key); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Scaffold( 11 | appBar: AppBar( 12 | title: Text("路由没有找到"), 13 | ), 14 | body: ListTile( 15 | title: Text("返回首页"), 16 | subtitle: Text('返回首页'), 17 | onTap: () => Get.offAllNamed(AppRoutes.Home), 18 | ), 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/pages/personal/personal_binding.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | import 'personal_controller.dart'; 3 | 4 | class PersonalBinding extends Bindings { 5 | @override 6 | void dependencies() { 7 | Get.lazyPut(() => PersonalController()); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/pages/personal/personal_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/pages/personal/personal_state.dart'; 2 | import 'package:get/get.dart'; 3 | 4 | class PersonalController extends GetxController { 5 | final state = PersonalState(); 6 | 7 | @override 8 | void onInit() { 9 | super.onInit(); 10 | } 11 | 12 | @override 13 | void onReady() {} 14 | 15 | @override 16 | void onClose() {} 17 | } 18 | -------------------------------------------------------------------------------- /lib/pages/personal/personal_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class PersonalState { 4 | List list = [ 5 | { 6 | 'name': '个人主页', 7 | 'icon': Icons.supervised_user_circle_outlined, 8 | }, 9 | { 10 | 'name': '创造中心', 11 | 'icon': Icons.local_fire_department_outlined, 12 | }, 13 | {'name': 'line'}, 14 | { 15 | 'name': '我的通知', 16 | 'icon': Icons.notifications_none_outlined, 17 | }, 18 | { 19 | 'name': '收听历史', 20 | 'icon': Icons.access_time, 21 | }, 22 | { 23 | 'name': '我的收藏', 24 | 'icon': Icons.star_border_rounded, 25 | }, 26 | { 27 | 'name': '付费账户', 28 | 'icon': Icons.sentiment_very_satisfied_sharp, 29 | }, 30 | {'name': 'line'}, 31 | { 32 | 'name': '问题反馈', 33 | 'icon': Icons.messenger_outline_rounded, 34 | }, 35 | { 36 | 'name': '设置', 37 | 'icon': Icons.settings, 38 | }, 39 | { 40 | 'name': '退出', 41 | 'icon': Icons.outlet_sharp, 42 | }, 43 | ]; 44 | 45 | /// 显示子拖动前的头像 46 | bool isShow = true; 47 | PersonalState(); 48 | } 49 | -------------------------------------------------------------------------------- /lib/pages/play/bottom_play_bar_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/common/colors/colors.dart'; 2 | import 'package:all_universe_flutter/components/play_btn.dart'; 3 | import 'package:all_universe_flutter/pages/play/play_controller.dart'; 4 | import 'package:all_universe_flutter/pages/play/widgets/play_list_btn.dart'; 5 | import 'package:all_universe_flutter/utils/common.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 8 | import 'package:get/get.dart'; 9 | 10 | /// 底部播放栏 11 | class BottomPlayBarPage extends GetView { 12 | BottomPlayBarPage({Key? key}) : super(key: key); 13 | 14 | final controller = Get.find(); 15 | final state = Get.find().state; 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return GetBuilder( 20 | builder: (_) => Container( 21 | child: GestureDetector( 22 | onTap: () => toPlayPage(), 23 | child: Container( 24 | width: double.infinity, 25 | height: 60.h, 26 | padding: EdgeInsets.symmetric( 27 | horizontal: 20.w, 28 | vertical: 8.h, 29 | ), 30 | child: Row( 31 | children: [ 32 | /// 封面 33 | ClipRRect( 34 | borderRadius: BorderRadius.circular(5.r), 35 | child: Image.network( 36 | state.playData!.cover, 37 | height: 44.h, 38 | width: 44.h, 39 | fit: BoxFit.cover, 40 | ), 41 | ), 42 | SizedBox(width: 10.w), 43 | 44 | /// 标题&时间 45 | Expanded( 46 | child: Column( 47 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 48 | crossAxisAlignment: CrossAxisAlignment.start, 49 | children: [ 50 | Text( 51 | state.playData!.title, 52 | maxLines: 1, 53 | overflow: TextOverflow.ellipsis, 54 | style: TextStyle( 55 | color: AppColors.primaryText, 56 | fontWeight: FontWeight.w400, 57 | fontSize: 14.sp, 58 | ), 59 | ), 60 | Text( 61 | '${state.time}/${state.totalTime}', 62 | maxLines: 1, 63 | overflow: TextOverflow.ellipsis, 64 | style: TextStyle( 65 | color: AppColors.primaryGreyText, 66 | fontWeight: FontWeight.w400, 67 | fontSize: 10.sp, 68 | ), 69 | ), 70 | ], 71 | ), 72 | ), 73 | SizedBox(width: 10.w), 74 | PlayBtn(data: state.playData), 75 | SizedBox(width: 20.w), 76 | PlayListBtn() 77 | ], 78 | ), 79 | decoration: BoxDecoration( 80 | color: Colors.white, 81 | boxShadow: [ 82 | BoxShadow( 83 | color: Colors.grey.withOpacity(0.1), 84 | blurRadius: 4, 85 | offset: Offset(0, -7), 86 | ), 87 | ], 88 | ), 89 | ), 90 | ), 91 | ), 92 | ); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /lib/pages/play/play_binding.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | import 'play_controller.dart'; 3 | 4 | class PlayBinding extends Bindings { 5 | @override 6 | void dependencies() { 7 | Get.lazyPut(() => PlayController()); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/pages/play/play_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/pages/play/widgets/play_progress.dart'; 2 | import 'package:just_audio/just_audio.dart'; 3 | 4 | class PlayState { 5 | /// 播放器 6 | AudioPlayer player = AudioPlayer(); 7 | ProcessingState processingState = ProcessingState.idle; 8 | 9 | /// 剩余时间 10 | String time = '00:00'; 11 | 12 | /// 总时间 13 | String totalTime = '00:00'; 14 | 15 | /// 进度条和总时间之间的转换系数 16 | double timeGini = 1.00; 17 | 18 | final ProgressBarController progressController = ProgressBarController(); 19 | 20 | /// 播放对象 21 | dynamic playData; 22 | 23 | //进度 24 | double progressValue = 0; 25 | 26 | /// 播放列表显示用 27 | List playViewList = []; 28 | 29 | /// 播放列表 - 播放器用 30 | ConcatenatingAudioSource playList = ConcatenatingAudioSource( 31 | // 播放下个音频之前加载 32 | useLazyPreparation: true, 33 | // 定义切换算法 34 | shuffleOrder: DefaultShuffleOrder(), 35 | // 指定播放列表项目 36 | children: [], 37 | ); 38 | 39 | PlayState() {} 40 | } 41 | -------------------------------------------------------------------------------- /lib/pages/play/widgets/play_list_btn.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/common/colors/colors.dart'; 2 | import 'package:all_universe_flutter/pages/play/play_controller.dart'; 3 | import 'package:all_universe_flutter/utils/common.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 6 | import 'package:get/get.dart'; 7 | 8 | class PlayListBtn extends StatelessWidget { 9 | PlayListBtn({ 10 | super.key, 11 | }); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return GetBuilder( 16 | builder: (_) => GestureDetector( 17 | onTap: () { 18 | toPlayListPage(context); 19 | }, 20 | child: Container( 21 | padding: EdgeInsets.all(5.w), 22 | child: Icon( 23 | Icons.line_style_rounded, 24 | size: 22.w, 25 | color: AppColors.primaryColor, 26 | ), 27 | decoration: BoxDecoration( 28 | color: AppColors.primaryColor.withOpacity(0.08), 29 | borderRadius: BorderRadius.circular(100), 30 | ), 31 | ), 32 | ), 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/pages/proxy/proxy_view.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:dio/adapter.dart'; 3 | import 'package:dio/dio.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_easyloading/flutter_easyloading.dart'; 6 | import 'package:all_universe_flutter/components/components.dart'; 7 | import 'package:all_universe_flutter/utils/utils.dart'; 8 | 9 | class ProxyPage extends StatelessWidget { 10 | ProxyPage({Key? key}) : super(key: key); 11 | 12 | final TextEditingController _controllerIP = TextEditingController(); 13 | final TextEditingController _controllerPort = TextEditingController(); 14 | @override 15 | Widget build(BuildContext context) { 16 | return BaseScaffold( 17 | title: "代理设置", 18 | body: Center( 19 | child: Column( 20 | children: [ 21 | Container( 22 | margin: EdgeInsets.all(15), 23 | child: TextField( 24 | decoration: InputDecoration(hintText: '请输入IP'), 25 | controller: _controllerIP, 26 | ), 27 | height: 40, 28 | width: getDeviceWidth(context) - 80, 29 | ), 30 | Container( 31 | margin: EdgeInsets.all(15), 32 | child: TextField( 33 | decoration: InputDecoration(hintText: '请输入端口'), 34 | controller: _controllerPort, 35 | ), 36 | height: 40, 37 | width: getDeviceWidth(context) - 80, 38 | ), 39 | Container( 40 | margin: EdgeInsets.symmetric(vertical: 30), 41 | width: getDeviceWidth(context) - 60, 42 | height: 50, 43 | child: TextButton( 44 | child: Text('设置代理'), onPressed: () => setupProxy()), 45 | ) 46 | ], 47 | ), 48 | ), 49 | ); 50 | } 51 | 52 | // 设置代理 53 | void setupProxy() { 54 | String ip = _controllerIP.text.trim(); 55 | String port = _controllerPort.text.trim(); 56 | if (ip.isEmpty) { 57 | EasyLoading.showToast('IP不能为空'); 58 | return; 59 | } 60 | if (port.isEmpty) { 61 | EasyLoading.showToast('端口不能为空'); 62 | return; 63 | } 64 | Dio dio = Request().dio; 65 | // 在调试模式下需要抓包调试,所以我们使用代理,并禁用HTTPS证书校验 66 | (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = 67 | (client) { 68 | client.findProxy = (uri) { 69 | print('走了代理----$ip:$port'); 70 | return "PROXY $ip:$port"; 71 | }; 72 | //代理工具会提供一个抓包的自签名证书,会通不过证书校验,所以我们禁用证书校验 73 | client.badCertificateCallback = 74 | (X509Certificate cert, String host, int port) => true; 75 | }; 76 | EasyLoading.showToast('代理设置成功'); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /lib/pages/splash/splash_controller.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:all_universe_flutter/pages/splash/splash_state.dart'; 4 | import 'package:get/get.dart'; 5 | 6 | class SplashController extends GetxController { 7 | final SplashState state = SplashState(); 8 | 9 | @override 10 | void onInit() async { 11 | super.onInit(); 12 | updateShow(); 13 | } 14 | 15 | @override 16 | void onReady() {} 17 | 18 | @override 19 | void onClose() {} 20 | 21 | updateShow() async { 22 | await Future.delayed(Duration(seconds: 1)); 23 | state.isShow = true; 24 | update(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/pages/splash/splash_state.dart: -------------------------------------------------------------------------------- 1 | class SplashState { 2 | bool isShow = false; 3 | double containerHeight = 0; 4 | SplashState() {} 5 | } 6 | -------------------------------------------------------------------------------- /lib/pages/subscription/subscription_binding.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | import 'subscription_controller.dart'; 3 | 4 | class SubscriptionBinding extends Bindings { 5 | @override 6 | void dependencies() { 7 | Get.lazyPut(() => SubscriptionController()); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/pages/subscription/subscription_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/pages/subscription/subscription_state.dart'; 2 | import 'package:all_universe_flutter/services/services.dart'; 3 | import 'package:get/get.dart'; 4 | 5 | class SubscriptionController extends GetxController { 6 | final state = SubscriptionState(); 7 | 8 | @override 9 | void onInit() async { 10 | state.scrollController.addListener(() { 11 | if (state.scrollController.offset > 100) { 12 | state.isShowAppbarText = true; 13 | } else { 14 | state.isShowAppbarText = false; 15 | } 16 | update(); 17 | }); 18 | 19 | await initData(); 20 | state.loading = false; 21 | update(); 22 | super.onInit(); 23 | } 24 | 25 | @override 26 | void onReady() {} 27 | 28 | @override 29 | void onClose() {} 30 | 31 | onRefresh() async { 32 | state.list = await getRandomPodcastList({'page': 1, 'pageSize': 10}); 33 | } 34 | 35 | Future initData() async { 36 | state.list = await getRandomPodcastList({'page': 1, 'pageSize': 10}); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/pages/subscription/subscription_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/model/podcast.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class SubscriptionState { 5 | bool loading = true; 6 | bool isShowAppbarText = false; 7 | 8 | ScrollController scrollController = ScrollController(); 9 | List list = []; 10 | SubscriptionState(); 11 | } 12 | -------------------------------------------------------------------------------- /lib/pages/tabbar/tabbar_binding.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:all_universe_flutter/pages/tabbar/tabbar_controller.dart'; 4 | import 'package:get/get.dart'; 5 | 6 | class TabbarBinding extends Bindings { 7 | @override 8 | void dependencies() { 9 | log("---tabbar"); 10 | Get.lazyPut(() => TabbarController()); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/pages/tabbar/tabbar_controller.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:all_universe_flutter/pages/tabbar/tabbar_state.dart'; 4 | import 'package:get/get.dart'; 5 | 6 | class TabbarController extends GetxController { 7 | final TabbarState state = TabbarState(); 8 | @override 9 | void onInit() { 10 | super.onInit(); 11 | } 12 | 13 | @override 14 | void onReady() {} 15 | 16 | @override 17 | void onClose() {} 18 | 19 | void changeTabbar(int value) { 20 | state.selectIndex.value = value; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/pages/tabbar/tabbar_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/pages/home/home_view.dart'; 2 | import 'package:all_universe_flutter/pages/personal/personal_view.dart'; 3 | import 'package:all_universe_flutter/pages/subscription/subscription_view.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:get/get.dart'; 6 | 7 | class TabbarState { 8 | RxInt selectIndex = 0.obs; 9 | 10 | List screens = [ 11 | HomePage(), 12 | SubscriptionPage(), 13 | PersonalPage(), 14 | ]; 15 | 16 | static Image generateIcon(String path) { 17 | return Image.asset( 18 | '${ImageLoader.rootPaht}/tabbar/$path', 19 | width: 28, 20 | height: 28, 21 | ); 22 | } 23 | 24 | final List items = [ 25 | BottomNavigationBarItem( 26 | icon: generateIcon('toolbar1.webp'), 27 | activeIcon: generateIcon('toolbar1_active.webp'), 28 | label: '发现', 29 | ), 30 | BottomNavigationBarItem( 31 | icon: generateIcon('toolbar2.webp'), 32 | activeIcon: generateIcon('toolbar2_active.webp'), 33 | label: '订阅', 34 | ), 35 | BottomNavigationBarItem( 36 | icon: generateIcon('toolbar3.webp'), 37 | activeIcon: generateIcon('toolbar3_active.webp'), 38 | label: '个人', 39 | ), 40 | ]; 41 | TabbarState() {} 42 | } 43 | 44 | class ImageLoader { 45 | static const String rootPaht = 'lib/assets/images'; 46 | 47 | static Image imageAsset(String icon) => Image.asset(rootPaht + icon); 48 | 49 | static Image imageNet(String url) => Image.network(url); 50 | } 51 | -------------------------------------------------------------------------------- /lib/pages/tabbar/tabbar_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/common/colors/colors.dart'; 2 | import 'package:all_universe_flutter/components/custom_scaffold.dart'; 3 | import 'package:all_universe_flutter/pages/play/bottom_play_bar_view.dart'; 4 | import 'package:all_universe_flutter/pages/play/play_controller.dart'; 5 | import 'package:all_universe_flutter/pages/tabbar/tabbar_controller.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 8 | import 'package:get/get.dart'; 9 | 10 | class CustomFloatingActionButtonLocation extends FloatingActionButtonLocation { 11 | FloatingActionButtonLocation location; 12 | double offsetX; // X方向的偏移量 13 | double offsetY; // Y方向的偏移量 14 | CustomFloatingActionButtonLocation(this.location, this.offsetX, this.offsetY); 15 | 16 | @override 17 | Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) { 18 | Offset offset = location.getOffset(scaffoldGeometry); 19 | return Offset(offset.dx + offsetX, offset.dy + offsetY); 20 | } 21 | } 22 | 23 | class TabbarPage extends StatelessWidget { 24 | TabbarPage({super.key}); 25 | final controller = Get.put(TabbarController()); 26 | final playController = Get.put(PlayController()); 27 | final state = Get.find().state; 28 | final PlayState = Get.find().state; 29 | 30 | @override 31 | Widget build(BuildContext context) { 32 | return BaseScaffold( 33 | floatingActionButtonLocation: CustomFloatingActionButtonLocation( 34 | FloatingActionButtonLocation.centerDocked, 0, -(60 / 2).h), 35 | floatingActionButton: GetBuilder( 36 | builder: (_) { 37 | return PlayState.playData == null ? SizedBox() : BottomPlayBarPage(); 38 | }, 39 | ), 40 | body: Obx( 41 | () => IndexedStack( 42 | index: state.selectIndex.value, 43 | children: state.screens, 44 | ), 45 | ), 46 | // body: Obx(() => state.screens[state.selectIndex.value]), 47 | bottomNavigationBar: Obx( 48 | () => BottomNavigationBar( 49 | type: BottomNavigationBarType.fixed, 50 | items: state.items, 51 | onTap: ((value) => controller.changeTabbar(value)), 52 | currentIndex: state.selectIndex.value, 53 | selectedLabelStyle: const TextStyle( 54 | fontWeight: FontWeight.w400, 55 | ), 56 | showUnselectedLabels: true, 57 | selectedItemColor: AppColors.primaryColor, 58 | unselectedItemColor: AppColors.primaryGreyText, 59 | selectedFontSize: 10.sp, 60 | unselectedFontSize: 10.sp, 61 | ), 62 | ), 63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lib/pages/test/test_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class TestScreen extends StatelessWidget { 4 | const TestScreen({key, this.title = ''}); 5 | 6 | static String route() => '/test'; 7 | 8 | final String title; 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Center( 13 | child: Text( 14 | '$title\nWaitting to implement!\nExpect it!', 15 | textAlign: TextAlign.center, 16 | style: const TextStyle(fontWeight: FontWeight.w400, fontSize: 30), 17 | ), 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/pages/webview/browser.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:all_universe_flutter/common/colors/colors.dart'; 4 | import 'package:all_universe_flutter/components/components.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:get/get.dart'; 7 | import 'package:webview_flutter/webview_flutter.dart'; 8 | 9 | class Browser extends StatefulWidget { 10 | const Browser( 11 | {Key? key, required this.url, required this.title, this.onPageFinished}); 12 | 13 | final String url; 14 | final String title; 15 | final Function(String url)? onPageFinished; 16 | 17 | @override 18 | State createState() => _BrowserState(); 19 | } 20 | 21 | class _BrowserState extends State { 22 | GlobalKey progressBarKey = GlobalKey(); 23 | double progressBarValue = 0; 24 | final WebViewController webViewController = WebViewController() 25 | ..setJavaScriptMode(JavaScriptMode.unrestricted); 26 | 27 | @override 28 | void initState() { 29 | webViewController.loadRequest(Uri.parse(widget.url)); 30 | webViewController.setNavigationDelegate(NavigationDelegate( 31 | onNavigationRequest: (request) { 32 | return NavigationDecision.navigate; 33 | }, 34 | onProgress: (progress) { 35 | if (progressBarKey.currentState?.mounted ?? false) { 36 | progressBarKey.currentState?.setState(() { 37 | progressBarValue = progress / 100.toDouble(); 38 | }); 39 | } 40 | }, 41 | onPageFinished: widget.onPageFinished)); 42 | super.initState(); 43 | } 44 | 45 | @override 46 | Widget build(BuildContext context) { 47 | return Scaffold( 48 | appBar: MyAppBar( 49 | title: Text( 50 | widget.title, 51 | style: TextStyle( 52 | color: AppColors.primaryText, 53 | ), 54 | ), 55 | backgroundColor: Colors.white, 56 | leading: InkWell( 57 | onTap: () => Get.back(), 58 | child: Icon( 59 | Icons.close, 60 | color: Colors.black, 61 | ), 62 | ), 63 | ), 64 | body: Column(children: [ 65 | StatefulBuilder( 66 | key: progressBarKey, 67 | builder: (context, setState) { 68 | return Visibility( 69 | visible: progressBarValue < 1, 70 | child: LinearProgressIndicator( 71 | key: ValueKey(progressBarValue), 72 | value: progressBarValue, 73 | ), 74 | ); 75 | }), 76 | Expanded( 77 | child: WebViewWidget(controller: webViewController), 78 | ) 79 | ]), 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lib/router/app_pages.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/pages/Index/Index_view.dart'; 2 | import 'package:all_universe_flutter/pages/details/details_view.dart'; 3 | import 'package:all_universe_flutter/pages/login/login_view.dart'; 4 | import 'package:all_universe_flutter/pages/notfound/notfound_view.dart'; 5 | import 'package:all_universe_flutter/pages/play/play_view.dart'; 6 | import 'package:all_universe_flutter/pages/proxy/proxy_view.dart'; 7 | import 'package:all_universe_flutter/pages/splash/spalsh_view.dart'; 8 | import 'package:all_universe_flutter/pages/subscription/subscription_view.dart'; 9 | import 'package:all_universe_flutter/pages/tabbar/tabbar_view.dart'; 10 | import 'package:get/get.dart'; 11 | part 'app_routes.dart'; 12 | 13 | class AppPages { 14 | static const INITIAL = AppRoutes.Index; 15 | 16 | static final routes = [ 17 | GetPage( 18 | name: AppRoutes.Index, 19 | page: () => IndexPage(), 20 | ), 21 | GetPage( 22 | name: AppRoutes.Login, 23 | page: () => LoginPage(), 24 | ), 25 | GetPage( 26 | name: AppRoutes.Subscription, 27 | page: () => SubscriptionPage(), 28 | ), 29 | GetPage( 30 | name: AppRoutes.Details, 31 | page: () => DetailsPage(), 32 | ), 33 | GetPage( 34 | name: AppRoutes.Tabbar, 35 | page: () => TabbarPage(), 36 | ), 37 | GetPage( 38 | name: AppRoutes.Play, 39 | page: () => PlayPage(), 40 | ), 41 | GetPage( 42 | name: AppRoutes.Splash, 43 | page: () => SplashPage(), 44 | ), 45 | ]; 46 | 47 | static final unknownRoute = GetPage( 48 | name: AppRoutes.NotFound, 49 | page: () => NotfoundPage(), 50 | ); 51 | 52 | static final proxyRoute = GetPage( 53 | name: AppRoutes.Proxy, 54 | page: () => ProxyPage(), 55 | ); 56 | } 57 | -------------------------------------------------------------------------------- /lib/router/app_routes.dart: -------------------------------------------------------------------------------- 1 | part of 'app_pages.dart'; 2 | 3 | abstract class AppRoutes { 4 | static const Index = '/index'; 5 | static const Home = '/home'; 6 | static const Login = '/login'; 7 | static const Splash = '/splash'; 8 | 9 | /// 详情 10 | static const Details = '/details'; 11 | //tabbar页 12 | static const Tabbar = '/tabbar'; 13 | // notfound 14 | static const NotFound = '/notfound'; 15 | // setproxy 16 | static const Proxy = '/proxy'; 17 | 18 | /// 订阅 19 | static const Subscription = '/Subscription'; 20 | 21 | /// 播放页面 22 | static const Play = '/play'; 23 | } 24 | -------------------------------------------------------------------------------- /lib/services/audio_handler.dart: -------------------------------------------------------------------------------- 1 | import 'package:audio_service/audio_service.dart'; 2 | 3 | Future initAudioService() async { 4 | return await AudioService.init( 5 | builder: () => MyAudioHandler(), 6 | config: const AudioServiceConfig( 7 | androidNotificationChannelId: 'com.mycompany.myapp.audio', 8 | androidNotificationChannelName: 'Audio Service Demo', 9 | androidNotificationOngoing: true, 10 | androidStopForegroundOnPause: true, 11 | ), 12 | ); 13 | } 14 | 15 | class MyAudioHandler extends BaseAudioHandler { 16 | // TODO: Override needed methods 17 | } 18 | -------------------------------------------------------------------------------- /lib/services/home.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/model/podcast.dart'; 2 | import 'package:all_universe_flutter/model/podcast_detail.dart'; 3 | import 'package:all_universe_flutter/utils/utils.dart'; 4 | 5 | /// 随机播客列表 6 | Future> getRandomPodcastList( 7 | Map? params, 8 | ) async { 9 | final response = await Request().get('/randomPodcastList', params: params); 10 | final list = 11 | (response.data as List).map((e) => PodcastModel.fromJson((e))).toList(); 12 | return list; 13 | } 14 | 15 | /// 详情 16 | Future getDetails( 17 | Map? params, 18 | ) async { 19 | final response = await Request().get('/details', params: params); 20 | final data = PodcastDetail.fromJson(response.data); 21 | return data; 22 | } 23 | -------------------------------------------------------------------------------- /lib/services/service_locator.dart: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lib/services/services.dart: -------------------------------------------------------------------------------- 1 | library services; 2 | 3 | export 'user.dart'; 4 | export 'home.dart'; 5 | -------------------------------------------------------------------------------- /lib/services/user.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_universe_flutter/model/user.dart'; 2 | import 'package:all_universe_flutter/utils/utils.dart'; 3 | 4 | /// 用户 5 | class UserAPI { 6 | /// 登录 7 | static Future login({ 8 | required Map params, 9 | }) async { 10 | var response = await Request().post( 11 | '/login', 12 | params: params, 13 | ); 14 | return UserInfo.fromJson(response.data); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/utils/authentication.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'package:all_universe_flutter/common/values/values.dart'; 3 | import 'package:all_universe_flutter/global.dart'; 4 | import 'package:all_universe_flutter/router/app_pages.dart'; 5 | import 'package:all_universe_flutter/utils/utils.dart'; 6 | import 'package:get/get.dart'; 7 | 8 | /// 检查是否有 token 9 | Future isAuthenticated() async { 10 | var profileJSON = LoacalStorage().getJSON(STORAGE_USER_PROFILE_KEY); 11 | return profileJSON != null ? true : false; 12 | } 13 | 14 | /// 删除缓存token 15 | Future deleteAuthentication() async { 16 | await LoacalStorage().remove(STORAGE_USER_PROFILE_KEY); 17 | Global.profile = null; 18 | } 19 | 20 | /// 重新登录 21 | void deleteTokenAndReLogin() async { 22 | await deleteAuthentication(); 23 | Get.offAllNamed(AppRoutes.Splash); 24 | } 25 | -------------------------------------------------------------------------------- /lib/utils/common.dart: -------------------------------------------------------------------------------- 1 | // 分组数组 2 | import 'dart:math'; 3 | import 'dart:ui'; 4 | 5 | import 'package:all_universe_flutter/pages/play/play_list_view.dart'; 6 | import 'package:all_universe_flutter/pages/play/play_view.dart'; 7 | import 'package:flutter/material.dart'; 8 | import 'package:flutter/services.dart'; 9 | import 'package:get/get.dart'; 10 | import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; 11 | 12 | List> getSplitList(List list, int len) { 13 | if (len <= 1) { 14 | return [list]; 15 | } 16 | 17 | List> result = []; 18 | int index = 1; 19 | 20 | while (true) { 21 | if (index * len < list.length) { 22 | List temp = list.skip((index - 1) * len).take(len).toList(); 23 | result.add(temp); 24 | index++; 25 | continue; 26 | } 27 | List temp = list.skip((index - 1) * len).toList(); 28 | result.add(temp); 29 | break; 30 | } 31 | return result; 32 | } 33 | 34 | Color hexToColor(String code) { 35 | return new Color(int.parse(code.substring(1, 7), radix: 16) + 0xFF000000); 36 | } 37 | 38 | /// 跳转播放页面 39 | void toPlayPage() { 40 | Get.bottomSheet( 41 | PlayPage(), 42 | barrierColor: Colors.black.withOpacity(.2), 43 | enterBottomSheetDuration: const Duration(milliseconds: 200), 44 | exitBottomSheetDuration: const Duration(milliseconds: 200), 45 | enableDrag: true, 46 | isScrollControlled: true, 47 | ); 48 | } 49 | 50 | /// 跳转播放列表 51 | void toPlayListPage(BuildContext context) { 52 | showBarModalBottomSheet( 53 | expand: true, 54 | context: context, 55 | topControl: SizedBox(), 56 | backgroundColor: Colors.white, 57 | builder: (context) => PlayListPage(), 58 | ); 59 | } 60 | -------------------------------------------------------------------------------- /lib/utils/local_storage.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:shared_preferences/shared_preferences.dart'; 3 | 4 | /// 本地存储-单例模式 5 | class LoacalStorage { 6 | static LoacalStorage _instance = new LoacalStorage._(); 7 | factory LoacalStorage() => _instance; 8 | static late SharedPreferences _prefs; 9 | 10 | LoacalStorage._(); 11 | 12 | static Future init() async { 13 | _prefs = await SharedPreferences.getInstance(); 14 | } 15 | 16 | Future setJSON(String key, dynamic jsonVal) { 17 | String jsonString = jsonEncode(jsonVal); 18 | return _prefs.setString(key, jsonString); 19 | } 20 | 21 | dynamic getJSON(String key) { 22 | String? jsonString = _prefs.getString(key); 23 | return jsonString == null ? null : jsonDecode(jsonString); 24 | } 25 | 26 | Future setBool(String key, bool val) { 27 | return _prefs.setBool(key, val); 28 | } 29 | 30 | bool getBool(String key) { 31 | bool? val = _prefs.getBool(key); 32 | return val == null ? false : val; 33 | } 34 | 35 | Future remove(String key) { 36 | return _prefs.remove(key); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/utils/screen_device.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 设备屏幕高度 6 | double getDeviceHeight(BuildContext context) { 7 | return MediaQuery.of(context).size.height; 8 | } 9 | 10 | /// 设备屏幕宽度 11 | double getDeviceWidth(BuildContext context) { 12 | return MediaQuery.of(context).size.width; 13 | } 14 | 15 | /// 设备顶部状态栏高度 16 | double getDeviceTopHeight() { 17 | return MediaQueryData.fromWindow(window).padding.top; 18 | } 19 | 20 | /// 设备底部Bar宽度 21 | double getDeviceBottomHeight() { 22 | return MediaQueryData.fromWindow(window).padding.bottom; 23 | } 24 | -------------------------------------------------------------------------------- /lib/utils/utils.dart: -------------------------------------------------------------------------------- 1 | library utils; 2 | 3 | export 'local_storage.dart'; 4 | export 'request.dart'; 5 | export 'screen_device.dart'; 6 | export 'authentication.dart'; 7 | export 'common.dart'; 8 | -------------------------------------------------------------------------------- /linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | -------------------------------------------------------------------------------- /linux/flutter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file controls Flutter-level build steps. It should not be edited. 2 | cmake_minimum_required(VERSION 3.10) 3 | 4 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") 5 | 6 | # Configuration provided via flutter tool. 7 | include(${EPHEMERAL_DIR}/generated_config.cmake) 8 | 9 | # TODO: Move the rest of this into files in ephemeral. See 10 | # https://github.com/flutter/flutter/issues/57146. 11 | 12 | # Serves the same purpose as list(TRANSFORM ... PREPEND ...), 13 | # which isn't available in 3.10. 14 | function(list_prepend LIST_NAME PREFIX) 15 | set(NEW_LIST "") 16 | foreach(element ${${LIST_NAME}}) 17 | list(APPEND NEW_LIST "${PREFIX}${element}") 18 | endforeach(element) 19 | set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) 20 | endfunction() 21 | 22 | # === Flutter Library === 23 | # System-level dependencies. 24 | find_package(PkgConfig REQUIRED) 25 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) 26 | pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) 27 | pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) 28 | 29 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") 30 | 31 | # Published to parent scope for install step. 32 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 33 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 34 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 35 | set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) 36 | 37 | list(APPEND FLUTTER_LIBRARY_HEADERS 38 | "fl_basic_message_channel.h" 39 | "fl_binary_codec.h" 40 | "fl_binary_messenger.h" 41 | "fl_dart_project.h" 42 | "fl_engine.h" 43 | "fl_json_message_codec.h" 44 | "fl_json_method_codec.h" 45 | "fl_message_codec.h" 46 | "fl_method_call.h" 47 | "fl_method_channel.h" 48 | "fl_method_codec.h" 49 | "fl_method_response.h" 50 | "fl_plugin_registrar.h" 51 | "fl_plugin_registry.h" 52 | "fl_standard_message_codec.h" 53 | "fl_standard_method_codec.h" 54 | "fl_string_codec.h" 55 | "fl_value.h" 56 | "fl_view.h" 57 | "flutter_linux.h" 58 | ) 59 | list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") 60 | add_library(flutter INTERFACE) 61 | target_include_directories(flutter INTERFACE 62 | "${EPHEMERAL_DIR}" 63 | ) 64 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") 65 | target_link_libraries(flutter INTERFACE 66 | PkgConfig::GTK 67 | PkgConfig::GLIB 68 | PkgConfig::GIO 69 | ) 70 | add_dependencies(flutter flutter_assemble) 71 | 72 | # === Flutter tool backend === 73 | # _phony_ is a non-existent file to force this command to run every time, 74 | # since currently there's no way to get a full input/output list from the 75 | # flutter tool. 76 | add_custom_command( 77 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 78 | ${CMAKE_CURRENT_BINARY_DIR}/_phony_ 79 | COMMAND ${CMAKE_COMMAND} -E env 80 | ${FLUTTER_TOOL_ENVIRONMENT} 81 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" 82 | ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} 83 | VERBATIM 84 | ) 85 | add_custom_target(flutter_assemble DEPENDS 86 | "${FLUTTER_LIBRARY}" 87 | ${FLUTTER_LIBRARY_HEADERS} 88 | ) 89 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | 10 | void fl_register_plugins(FlPluginRegistry* registry) { 11 | } 12 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void fl_register_plugins(FlPluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | ) 7 | 8 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 9 | ) 10 | 11 | set(PLUGIN_BUNDLED_LIBRARIES) 12 | 13 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 14 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) 15 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 16 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 18 | endforeach(plugin) 19 | 20 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 21 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) 22 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 23 | endforeach(ffi_plugin) 24 | -------------------------------------------------------------------------------- /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/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import audio_service 9 | import audio_session 10 | import just_audio 11 | import path_provider_foundation 12 | import shared_preferences_foundation 13 | import sqflite 14 | 15 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 16 | AudioServicePlugin.register(with: registry.registrar(forPlugin: "AudioServicePlugin")) 17 | AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) 18 | JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin")) 19 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) 20 | SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) 21 | SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) 22 | } 23 | -------------------------------------------------------------------------------- /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/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - audio_service (0.14.1): 3 | - FlutterMacOS 4 | - audio_session (0.0.1): 5 | - FlutterMacOS 6 | - FlutterMacOS (1.0.0) 7 | - FMDB (2.7.5): 8 | - FMDB/standard (= 2.7.5) 9 | - FMDB/standard (2.7.5) 10 | - just_audio (0.0.1): 11 | - FlutterMacOS 12 | - path_provider_foundation (0.0.1): 13 | - Flutter 14 | - FlutterMacOS 15 | - shared_preferences_foundation (0.0.1): 16 | - Flutter 17 | - FlutterMacOS 18 | - sqflite (0.0.2): 19 | - FlutterMacOS 20 | - FMDB (>= 2.7.5) 21 | 22 | DEPENDENCIES: 23 | - audio_service (from `Flutter/ephemeral/.symlinks/plugins/audio_service/macos`) 24 | - audio_session (from `Flutter/ephemeral/.symlinks/plugins/audio_session/macos`) 25 | - FlutterMacOS (from `Flutter/ephemeral`) 26 | - just_audio (from `Flutter/ephemeral/.symlinks/plugins/just_audio/macos`) 27 | - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos`) 28 | - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos`) 29 | - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`) 30 | 31 | SPEC REPOS: 32 | trunk: 33 | - FMDB 34 | 35 | EXTERNAL SOURCES: 36 | audio_service: 37 | :path: Flutter/ephemeral/.symlinks/plugins/audio_service/macos 38 | audio_session: 39 | :path: Flutter/ephemeral/.symlinks/plugins/audio_session/macos 40 | FlutterMacOS: 41 | :path: Flutter/ephemeral 42 | just_audio: 43 | :path: Flutter/ephemeral/.symlinks/plugins/just_audio/macos 44 | path_provider_foundation: 45 | :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos 46 | shared_preferences_foundation: 47 | :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos 48 | sqflite: 49 | :path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos 50 | 51 | SPEC CHECKSUMS: 52 | audio_service: b88ff778e0e3915efd4cd1a5ad6f0beef0c950a9 53 | audio_session: dea1f41890dbf1718f04a56f1d6150fd50039b72 54 | FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 55 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a 56 | just_audio: 9b67ca7b97c61cfc9784ea23cd8cc55eb226d489 57 | path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 58 | shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472 59 | sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea 60 | 61 | PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7 62 | 63 | COCOAPODS: 1.11.3 64 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /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/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "version": 1, 4 | "author": "xcode" 5 | }, 6 | "images": [ 7 | { 8 | "size": "16x16", 9 | "idiom": "mac", 10 | "filename": "app_icon_16.png", 11 | "scale": "1x" 12 | }, 13 | { 14 | "size": "16x16", 15 | "idiom": "mac", 16 | "filename": "app_icon_32.png", 17 | "scale": "2x" 18 | }, 19 | { 20 | "size": "32x32", 21 | "idiom": "mac", 22 | "filename": "app_icon_32.png", 23 | "scale": "1x" 24 | }, 25 | { 26 | "size": "32x32", 27 | "idiom": "mac", 28 | "filename": "app_icon_64.png", 29 | "scale": "2x" 30 | }, 31 | { 32 | "size": "128x128", 33 | "idiom": "mac", 34 | "filename": "app_icon_128.png", 35 | "scale": "1x" 36 | }, 37 | { 38 | "size": "128x128", 39 | "idiom": "mac", 40 | "filename": "app_icon_256.png", 41 | "scale": "2x" 42 | }, 43 | { 44 | "size": "256x256", 45 | "idiom": "mac", 46 | "filename": "app_icon_256.png", 47 | "scale": "1x" 48 | }, 49 | { 50 | "size": "256x256", 51 | "idiom": "mac", 52 | "filename": "app_icon_512.png", 53 | "scale": "2x" 54 | }, 55 | { 56 | "size": "512x512", 57 | "idiom": "mac", 58 | "filename": "app_icon_512.png", 59 | "scale": "1x" 60 | }, 61 | { 62 | "size": "512x512", 63 | "idiom": "mac", 64 | "filename": "app_icon_1024.png", 65 | "scale": "2x" 66 | } 67 | ] 68 | } -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /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 = all_univers 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.allUnivers 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2022 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 | 12 | 13 | -------------------------------------------------------------------------------- /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 | 8 | 9 | -------------------------------------------------------------------------------- /memo.md: -------------------------------------------------------------------------------- 1 | adb connect 127.0.0.1:7555 -------------------------------------------------------------------------------- /screenshots/sc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/screenshots/sc.png -------------------------------------------------------------------------------- /screenshots/sc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/screenshots/sc1.png -------------------------------------------------------------------------------- /screenshots/sc10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/screenshots/sc10.png -------------------------------------------------------------------------------- /screenshots/sc11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/screenshots/sc11.png -------------------------------------------------------------------------------- /screenshots/sc2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/screenshots/sc2.png -------------------------------------------------------------------------------- /screenshots/sc3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/screenshots/sc3.png -------------------------------------------------------------------------------- /screenshots/sc4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/screenshots/sc4.png -------------------------------------------------------------------------------- /screenshots/sc5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/screenshots/sc5.png -------------------------------------------------------------------------------- /screenshots/sc6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/screenshots/sc6.png -------------------------------------------------------------------------------- /screenshots/sc7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/screenshots/sc7.png -------------------------------------------------------------------------------- /screenshots/sc8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/screenshots/sc8.png -------------------------------------------------------------------------------- /screenshots/sc9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/screenshots/sc9.png -------------------------------------------------------------------------------- /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 that Flutter provides. 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:all_universe_flutter/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(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/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | all_univers 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "all_univers", 3 | "short_name": "all_univers", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#hexcode", 7 | "theme_color": "#hexcode", 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 | } -------------------------------------------------------------------------------- /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/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | 10 | void RegisterPlugins(flutter::PluginRegistry* registry) { 11 | } 12 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | ) 7 | 8 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 9 | ) 10 | 11 | set(PLUGIN_BUNDLED_LIBRARIES) 12 | 13 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 14 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 15 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 16 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 18 | endforeach(plugin) 19 | 20 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 21 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) 22 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 23 | endforeach(ffi_plugin) 24 | -------------------------------------------------------------------------------- /windows/runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(runner LANGUAGES CXX) 3 | 4 | # Define the application target. To change its name, change BINARY_NAME in the 5 | # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer 6 | # work. 7 | # 8 | # Any new source files that you add to the application should be added here. 9 | add_executable(${BINARY_NAME} WIN32 10 | "flutter_window.cpp" 11 | "main.cpp" 12 | "utils.cpp" 13 | "win32_window.cpp" 14 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 15 | "Runner.rc" 16 | "runner.exe.manifest" 17 | ) 18 | 19 | # Apply the standard set of build settings. This can be removed for applications 20 | # that need different build settings. 21 | apply_standard_settings(${BINARY_NAME}) 22 | 23 | # Add preprocessor definitions for the build version. 24 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") 25 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") 26 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") 27 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") 28 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") 29 | 30 | # Disable Windows macros that collide with C++ standard library functions. 31 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") 32 | 33 | # Add dependency libraries and include directories. Add any application-specific 34 | # dependencies here. 35 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) 36 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") 37 | 38 | # Run the Flutter tool portions of the build. This must not be removed. 39 | add_dependencies(${BINARY_NAME} flutter_assemble) 40 | -------------------------------------------------------------------------------- /windows/runner/Runner.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #pragma code_page(65001) 4 | #include "resource.h" 5 | 6 | #define APSTUDIO_READONLY_SYMBOLS 7 | ///////////////////////////////////////////////////////////////////////////// 8 | // 9 | // Generated from the TEXTINCLUDE 2 resource. 10 | // 11 | #include "winres.h" 12 | 13 | ///////////////////////////////////////////////////////////////////////////// 14 | #undef APSTUDIO_READONLY_SYMBOLS 15 | 16 | ///////////////////////////////////////////////////////////////////////////// 17 | // English (United States) resources 18 | 19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Icon 51 | // 52 | 53 | // Icon with lowest ID value placed first to ensure application icon 54 | // remains consistent on all systems. 55 | IDI_APP_ICON ICON "resources\\app_icon.ico" 56 | 57 | 58 | ///////////////////////////////////////////////////////////////////////////// 59 | // 60 | // Version 61 | // 62 | 63 | #if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) 64 | #define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD 65 | #else 66 | #define VERSION_AS_NUMBER 1,0,0,0 67 | #endif 68 | 69 | #if defined(FLUTTER_VERSION) 70 | #define VERSION_AS_STRING FLUTTER_VERSION 71 | #else 72 | #define VERSION_AS_STRING "1.0.0" 73 | #endif 74 | 75 | VS_VERSION_INFO VERSIONINFO 76 | FILEVERSION VERSION_AS_NUMBER 77 | PRODUCTVERSION VERSION_AS_NUMBER 78 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 79 | #ifdef _DEBUG 80 | FILEFLAGS VS_FF_DEBUG 81 | #else 82 | FILEFLAGS 0x0L 83 | #endif 84 | FILEOS VOS__WINDOWS32 85 | FILETYPE VFT_APP 86 | FILESUBTYPE 0x0L 87 | BEGIN 88 | BLOCK "StringFileInfo" 89 | BEGIN 90 | BLOCK "040904e4" 91 | BEGIN 92 | VALUE "CompanyName", "com.example" "\0" 93 | VALUE "FileDescription", "all_univers" "\0" 94 | VALUE "FileVersion", VERSION_AS_STRING "\0" 95 | VALUE "InternalName", "all_univers" "\0" 96 | VALUE "LegalCopyright", "Copyright (C) 2022 com.example. All rights reserved." "\0" 97 | VALUE "OriginalFilename", "all_univers.exe" "\0" 98 | VALUE "ProductName", "all_univers" "\0" 99 | VALUE "ProductVersion", VERSION_AS_STRING "\0" 100 | END 101 | END 102 | BLOCK "VarFileInfo" 103 | BEGIN 104 | VALUE "Translation", 0x409, 1252 105 | END 106 | END 107 | 108 | #endif // English (United States) resources 109 | ///////////////////////////////////////////////////////////////////////////// 110 | 111 | 112 | 113 | #ifndef APSTUDIO_INVOKED 114 | ///////////////////////////////////////////////////////////////////////////// 115 | // 116 | // Generated from the TEXTINCLUDE 3 resource. 117 | // 118 | 119 | 120 | ///////////////////////////////////////////////////////////////////////////// 121 | #endif // not APSTUDIO_INVOKED 122 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.cpp: -------------------------------------------------------------------------------- 1 | #include "flutter_window.h" 2 | 3 | #include 4 | 5 | #include "flutter/generated_plugin_registrant.h" 6 | 7 | FlutterWindow::FlutterWindow(const flutter::DartProject& project) 8 | : project_(project) {} 9 | 10 | FlutterWindow::~FlutterWindow() {} 11 | 12 | bool FlutterWindow::OnCreate() { 13 | if (!Win32Window::OnCreate()) { 14 | return false; 15 | } 16 | 17 | RECT frame = GetClientArea(); 18 | 19 | // The size here must match the window dimensions to avoid unnecessary surface 20 | // creation / destruction in the startup path. 21 | flutter_controller_ = std::make_unique( 22 | frame.right - frame.left, frame.bottom - frame.top, project_); 23 | // Ensure that basic setup of the controller was successful. 24 | if (!flutter_controller_->engine() || !flutter_controller_->view()) { 25 | return false; 26 | } 27 | RegisterPlugins(flutter_controller_->engine()); 28 | SetChildContent(flutter_controller_->view()->GetNativeWindow()); 29 | return true; 30 | } 31 | 32 | void FlutterWindow::OnDestroy() { 33 | if (flutter_controller_) { 34 | flutter_controller_ = nullptr; 35 | } 36 | 37 | Win32Window::OnDestroy(); 38 | } 39 | 40 | LRESULT 41 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message, 42 | WPARAM const wparam, 43 | LPARAM const lparam) noexcept { 44 | // Give Flutter, including plugins, an opportunity to handle window messages. 45 | if (flutter_controller_) { 46 | std::optional result = 47 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, 48 | lparam); 49 | if (result) { 50 | return *result; 51 | } 52 | } 53 | 54 | switch (message) { 55 | case WM_FONTCHANGE: 56 | flutter_controller_->engine()->ReloadSystemFonts(); 57 | break; 58 | } 59 | 60 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam); 61 | } 62 | -------------------------------------------------------------------------------- /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.CreateAndShow(L"all_univers", 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/xuergo/all-universe-flutter/02dfb41323b7c1a7bcfe18aea4369cdc949f57cb/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.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | void CreateAndAttachConsole() { 11 | if (::AllocConsole()) { 12 | FILE *unused; 13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) { 14 | _dup2(_fileno(stdout), 1); 15 | } 16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) { 17 | _dup2(_fileno(stdout), 2); 18 | } 19 | std::ios::sync_with_stdio(); 20 | FlutterDesktopResyncOutputStreams(); 21 | } 22 | } 23 | 24 | std::vector GetCommandLineArguments() { 25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. 26 | int argc; 27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); 28 | if (argv == nullptr) { 29 | return std::vector(); 30 | } 31 | 32 | std::vector command_line_arguments; 33 | 34 | // Skip the first argument as it's the binary name. 35 | for (int i = 1; i < argc; i++) { 36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i])); 37 | } 38 | 39 | ::LocalFree(argv); 40 | 41 | return command_line_arguments; 42 | } 43 | 44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) { 45 | if (utf16_string == nullptr) { 46 | return std::string(); 47 | } 48 | int target_length = ::WideCharToMultiByte( 49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 50 | -1, nullptr, 0, nullptr, nullptr); 51 | std::string utf8_string; 52 | if (target_length == 0 || target_length > utf8_string.max_size()) { 53 | return utf8_string; 54 | } 55 | utf8_string.resize(target_length); 56 | int converted_length = ::WideCharToMultiByte( 57 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 58 | -1, utf8_string.data(), 59 | target_length, nullptr, nullptr); 60 | if (converted_length == 0) { 61 | return std::string(); 62 | } 63 | return utf8_string; 64 | } 65 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------